Merge branch 'master' of github.com:AdrianoRobson/projeto-hit
commit
f1022063a4
|
@ -40,7 +40,10 @@ WWebJS
|
||||||
.env.development.local
|
.env.development.local
|
||||||
.env.test.local
|
.env.test.local
|
||||||
.env.production.local
|
.env.production.local
|
||||||
|
.env.save
|
||||||
|
nano.save
|
||||||
|
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
PORT=8019
|
||||||
|
PORT_START=8020
|
||||||
|
BASE_URL=http://localhost
|
||||||
|
PASS="strongpassword, strongpassword32"
|
||||||
|
DB_MONGO_URL=mongodb://localhost:27017
|
||||||
|
DB_MONGO_NAME=session_out_omnihit_db
|
||||||
|
DB_MONGO_NAME_CAMPAIGN=broker_omnihit
|
||||||
|
|
|
@ -0,0 +1,520 @@
|
||||||
|
const express = require('express')
|
||||||
|
const bodyparser = require('body-parser')
|
||||||
|
const dotenv = require('dotenv')
|
||||||
|
dotenv.config({ path: '.env' })
|
||||||
|
const copyFolder = require('./helpers/copyFolder')
|
||||||
|
const createDir = require('./helpers/createDir')
|
||||||
|
const createFile = require('./helpers/createFile')
|
||||||
|
const path = require('path')
|
||||||
|
const db_info = require('./db_conn')
|
||||||
|
const fs = require('fs')
|
||||||
|
let mysql_conn = require('./helpers/mysql_conn.js')
|
||||||
|
const { exec, execSync, spawn } = require('child_process')
|
||||||
|
|
||||||
|
const startPm2Process = require('./helpers/startPm2Process')
|
||||||
|
const removeDir = require('./helpers/remove_dir')
|
||||||
|
const setSessionName = require('./helpers/setSessionNumber')
|
||||||
|
const getNumberFromName = require('./helpers/getNumberSequence')
|
||||||
|
const pm2 = require('pm2')
|
||||||
|
const bcrypt = require('bcrypt')
|
||||||
|
const OmnihitDBConn = require('./model/db_conn')
|
||||||
|
|
||||||
|
const app = express()
|
||||||
|
|
||||||
|
app.use(bodyparser.json())
|
||||||
|
|
||||||
|
app.get('/', function (req, res) {
|
||||||
|
return res.send('Express + TypeScript Server')
|
||||||
|
})
|
||||||
|
|
||||||
|
app.post('/api/session', async function (req, res) {
|
||||||
|
let { app_name, whatsappId, client_url, number } = req.body
|
||||||
|
|
||||||
|
let oldNumber = ''
|
||||||
|
|
||||||
|
if (app_name) {
|
||||||
|
app_name = app_name.trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('__dirname: ', path.join(__dirname, '..', app_name))
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
'app_name: ',
|
||||||
|
app_name,
|
||||||
|
' | whatsappId: ',
|
||||||
|
whatsappId,
|
||||||
|
' | client_url: ',
|
||||||
|
client_url
|
||||||
|
)
|
||||||
|
|
||||||
|
const sessionsPath = path.join(__dirname, '..', 'sessions')
|
||||||
|
|
||||||
|
const directoriesInDIrectory = fs
|
||||||
|
.readdirSync(sessionsPath, { withFileTypes: true })
|
||||||
|
.filter((item) => item.isDirectory())
|
||||||
|
.map((item) => item.name)
|
||||||
|
|
||||||
|
console.log('directoriesInDIrectory: ', directoriesInDIrectory)
|
||||||
|
|
||||||
|
const dirExist = directoriesInDIrectory.filter((e) => e.trim() == app_name)
|
||||||
|
|
||||||
|
let dirSessionsApp = path.join(sessionsPath, app_name)
|
||||||
|
|
||||||
|
if (dirExist.length == 0) {
|
||||||
|
let create = createDir(dirSessionsApp)
|
||||||
|
|
||||||
|
if (!create) {
|
||||||
|
res.status(500).json({ message: 'Cannot create the directory path!' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let appPort = []
|
||||||
|
|
||||||
|
let existSubDir = false
|
||||||
|
|
||||||
|
for (let i = 0; i < directoriesInDIrectory.length; i++) {
|
||||||
|
console.log('directoriesInDIrectory[i]', directoriesInDIrectory[i])
|
||||||
|
|
||||||
|
const subDir = fs
|
||||||
|
.readdirSync(path.join(sessionsPath, directoriesInDIrectory[i]), {
|
||||||
|
withFileTypes: true,
|
||||||
|
})
|
||||||
|
.filter((item) => item.isDirectory())
|
||||||
|
.map((item) => item.name)
|
||||||
|
|
||||||
|
for (let x = 0; x < subDir.length; x++) {
|
||||||
|
console.log('subdir: ', subDir[x])
|
||||||
|
|
||||||
|
let whatsId = subDir[x].split('_')[0]
|
||||||
|
|
||||||
|
if (whatsId == whatsappId && app_name == directoriesInDIrectory[i]) {
|
||||||
|
let currPath = path.join(
|
||||||
|
sessionsPath,
|
||||||
|
directoriesInDIrectory[i],
|
||||||
|
subDir[x]
|
||||||
|
)
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
'PATH: ',
|
||||||
|
path.join(sessionsPath, directoriesInDIrectory[i], subDir[x])
|
||||||
|
)
|
||||||
|
|
||||||
|
oldNumber = subDir[x].split('_')[1]
|
||||||
|
|
||||||
|
if (oldNumber != number) {
|
||||||
|
deletePm2Process(subDir[x], currPath)
|
||||||
|
|
||||||
|
removeDir(currPath)
|
||||||
|
} else {
|
||||||
|
res.send('ok')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let auxPort = subDir[x].split('_')[3]
|
||||||
|
|
||||||
|
console.log('---------> auxPort: ' + auxPort)
|
||||||
|
|
||||||
|
if (auxPort) {
|
||||||
|
auxPort = +auxPort.trim()
|
||||||
|
|
||||||
|
if (!isNaN(auxPort)) {
|
||||||
|
appPort.push(auxPort)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
existSubDir = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
appPort = existSubDir ? Math.max(...appPort) + 1 : process.env.PORT_START
|
||||||
|
|
||||||
|
console.log('new port: ', appPort)
|
||||||
|
|
||||||
|
let dirSessionAppName
|
||||||
|
|
||||||
|
let numberSession = 1
|
||||||
|
|
||||||
|
let lstPass = process.env.PASS
|
||||||
|
|
||||||
|
if (!lstPass) {
|
||||||
|
console.log('PASS VARIABLE NOT FOUND INTO .ENV!')
|
||||||
|
return res.send('OK')
|
||||||
|
}
|
||||||
|
|
||||||
|
let db_credentials
|
||||||
|
try {
|
||||||
|
db_credentials = await OmnihitDBConn.findOne({ client_url })
|
||||||
|
|
||||||
|
if (!db_credentials) {
|
||||||
|
db_credentials = new OmnihitDBConn({
|
||||||
|
client_url: client_url,
|
||||||
|
db_conf: {
|
||||||
|
DB: '',
|
||||||
|
DB_HOST: '',
|
||||||
|
DB_USER: '',
|
||||||
|
DB_PASS: '',
|
||||||
|
DB_PORT: '',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await db_credentials.save()
|
||||||
|
return res.send('ok')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (db_credentials && db_credentials.db_conf.DB.trim().length > 0) {
|
||||||
|
lstPass = lstPass.split(',')
|
||||||
|
let password = null
|
||||||
|
|
||||||
|
// password = await lstPass.find(
|
||||||
|
// async (pass) =>
|
||||||
|
// await bcrypt.compare(pass.trim(), db_credentials.db_conf.DB_PASS)
|
||||||
|
// )
|
||||||
|
|
||||||
|
for (let i = 0; i < lstPass.length; i++) {
|
||||||
|
const hasPass = await bcrypt.compare(
|
||||||
|
lstPass[i].trim(),
|
||||||
|
db_credentials.db_conf.DB_PASS
|
||||||
|
)
|
||||||
|
|
||||||
|
if (hasPass) {
|
||||||
|
password = lstPass[i].trim()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password) {
|
||||||
|
db_credentials.db_conf.DB_PASS = password
|
||||||
|
} else {
|
||||||
|
return res.send('ok')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
db_credentials.db_conf &&
|
||||||
|
Object.keys(db_credentials.db_conf).length > 0
|
||||||
|
) {
|
||||||
|
const whatsapp_numbers = await new Promise((resolve, reject) => {
|
||||||
|
mysql_conn(db_credentials.db_conf).query(
|
||||||
|
'SELECT name, number FROM Whatsapps WHERE name LIKE ?',
|
||||||
|
[`%${number}%`],
|
||||||
|
(err, result) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err)
|
||||||
|
} else {
|
||||||
|
resolve(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
let session_num = []
|
||||||
|
|
||||||
|
if (whatsapp_numbers && whatsapp_numbers.length > 0) {
|
||||||
|
console.log('whatsapp_numbers.length: ', whatsapp_numbers.length)
|
||||||
|
|
||||||
|
if (whatsapp_numbers.length == 5) {
|
||||||
|
res.status(400).json({
|
||||||
|
message: 'Cannot create more than 4 sessions from the same number',
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let regex = /-> [a-zA-Z]\d$/
|
||||||
|
|
||||||
|
let numbered_sessions = whatsapp_numbers.filter((e) => regex.test(e.name))
|
||||||
|
|
||||||
|
console.log('numbered_sessions: ', numbered_sessions)
|
||||||
|
|
||||||
|
session_num = numbered_sessions.map((e) =>
|
||||||
|
parseInt(
|
||||||
|
e.name
|
||||||
|
.split('->')
|
||||||
|
[e.name.split('->').length - 1].trim()
|
||||||
|
.match(/\d+/)[0]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
console.log('session_num', session_num)
|
||||||
|
}
|
||||||
|
|
||||||
|
let index = 1
|
||||||
|
|
||||||
|
while (index <= 4) {
|
||||||
|
if (!session_num.includes(index)) {
|
||||||
|
console.log(index)
|
||||||
|
numberSession = index
|
||||||
|
break
|
||||||
|
}
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// numberSession = Math.max(...session_number) + 1
|
||||||
|
|
||||||
|
console.log('Number session: ', numberSession)
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
dirSessionAppName = `${whatsappId}_${number}_${numberSession}_${appPort}`
|
||||||
|
|
||||||
|
destDir = path.join(dirSessionsApp, dirSessionAppName)
|
||||||
|
|
||||||
|
originDir = path.join(__dirname, '..', 'whats')
|
||||||
|
|
||||||
|
copyFolder(originDir, destDir)
|
||||||
|
|
||||||
|
if (
|
||||||
|
db_credentials.db_conf &&
|
||||||
|
Object.keys(db_credentials.db_conf).length > 0
|
||||||
|
) {
|
||||||
|
console.log('***SUCCESS SEED DIRECTORY CREATED***')
|
||||||
|
|
||||||
|
let whatsName
|
||||||
|
|
||||||
|
const whatsapp = await new Promise((resolve, reject) => {
|
||||||
|
mysql_conn(db_credentials.db_conf).query(
|
||||||
|
'SELECT name from Whatsapps where id = ?',
|
||||||
|
[whatsappId],
|
||||||
|
(err, result) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err)
|
||||||
|
} else {
|
||||||
|
resolve(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (whatsapp[0]['name']?.split('->')?.length > 0) {
|
||||||
|
whatsName = `${whatsapp[0]['name'].split('->')[0]} -> S${numberSession}`
|
||||||
|
} else {
|
||||||
|
whatsName = `${whatsapp[0]['name']} -> S${numberSession}`
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('whatsName: ', whatsName)
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`url: ${process.env.BASE_URL}:${appPort}\n whatsname: ${whatsName}\n whatsappId: ${whatsappId}`
|
||||||
|
)
|
||||||
|
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
mysql_conn(db_credentials.db_conf).query(
|
||||||
|
'UPDATE Whatsapps SET url = ?, name = ? where id = ?',
|
||||||
|
[`${process.env.BASE_URL}:${appPort}`, `${whatsName}`, whatsappId],
|
||||||
|
|
||||||
|
function (err, result) {
|
||||||
|
if (err) {
|
||||||
|
reject(err)
|
||||||
|
console.log('===> ERROR: ' + err)
|
||||||
|
} else {
|
||||||
|
resolve(result)
|
||||||
|
// console.log('RESULT: ', result)
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
// console.log('myslq result: ', result);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
let whatsappName = `${number} - s${numberSession}`
|
||||||
|
|
||||||
|
console.log('-------------- numberSession', numberSession)
|
||||||
|
|
||||||
|
if (whatsapp.length > 0) {
|
||||||
|
if (whatsapp[0]['name'].split(' ').length > 0) {
|
||||||
|
whatsappName = `${whatsapp[0]['name'].split(' ')[0]
|
||||||
|
} - S${numberSession}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('whatsapp: ', whatsapp)
|
||||||
|
console.log("whatsapp[0]['name']: ", whatsapp[0]['name'])
|
||||||
|
|
||||||
|
const keys = Object.keys(db_credentials.db_conf)
|
||||||
|
|
||||||
|
var stream = fs.createWriteStream(path.join(destDir, '.env'))
|
||||||
|
stream.once('open', function (fd) {
|
||||||
|
stream.write('# NUMBER AND NAME THAT WILL BE DISPLAYED ON CONSOLE\n')
|
||||||
|
stream.write(`MOBILEUID=${number}\n`)
|
||||||
|
stream.write(`MOBILENAME=${whatsappName}\n`)
|
||||||
|
stream.write(`OLD_MOBILEUID=${oldNumber}\n`)
|
||||||
|
stream.write('\n')
|
||||||
|
|
||||||
|
stream.write('# PORT NUMBER FOR THIS API\n')
|
||||||
|
stream.write(`PORT=${appPort}\n`)
|
||||||
|
stream.write('\n')
|
||||||
|
|
||||||
|
stream.write('# URL FROM THE OMNIHIT BACKEND API\n')
|
||||||
|
stream.write(`CLIENT_URL=${client_url}\n`)
|
||||||
|
stream.write('\n')
|
||||||
|
|
||||||
|
stream.write('# OMNIHIT DATABASE\n')
|
||||||
|
keys.forEach((key, index) => {
|
||||||
|
stream.write(`${key}=${db_credentials.db_conf[key]}\n`)
|
||||||
|
})
|
||||||
|
stream.write('\n')
|
||||||
|
|
||||||
|
stream.write(
|
||||||
|
`# WHATSAPP ID OF THE TABLE Whatsapps FROM THE OMNIHIT DATABASE\n`
|
||||||
|
)
|
||||||
|
stream.write(`WHATSAPP_ID=${whatsappId}\n`)
|
||||||
|
stream.write('\n')
|
||||||
|
|
||||||
|
stream.write('# MONGO CONNECTION\n')
|
||||||
|
stream.write(`DB_MONGO_URL=${process.env.DB_MONGO_URL}\n`)
|
||||||
|
stream.write('\n')
|
||||||
|
|
||||||
|
stream.write('# MONGO COLLECTION\n')
|
||||||
|
stream.write(`DB_MONGO_NAME=${process.env.DB_MONGO_NAME_CAMPAIGN}\n`)
|
||||||
|
stream.write('\n')
|
||||||
|
|
||||||
|
stream.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log('----------------destDir: ', destDir)
|
||||||
|
|
||||||
|
execSync(`npm install`, { cwd: destDir }, (error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
console.log(`error: ${error.message}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (stderr) {
|
||||||
|
console.log(`stderr: ${stderr}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log(`stdout: ${stdout}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
const env = {
|
||||||
|
PORT: appPort,
|
||||||
|
DB_MONGO_URL: process.env.DB_MONGO_URL,
|
||||||
|
DB_MONGO_NAME: process.env.DB_MONGO_NAME_CAMPAIGN
|
||||||
|
}
|
||||||
|
|
||||||
|
startPm2Process(dirSessionAppName, 'app.js', destDir, env)
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send('OK')
|
||||||
|
})
|
||||||
|
|
||||||
|
app.post('/api/session/edit', async function (req, res) {
|
||||||
|
const { app_name, whatsappId, client_url, number } = req.body
|
||||||
|
})
|
||||||
|
|
||||||
|
app.post('/api/session/del', async function (req, res) {
|
||||||
|
let { whatsappId, app_name } = req.body
|
||||||
|
|
||||||
|
if (app_name) {
|
||||||
|
app_name = app_name.trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
const sessionsPath = path.join(__dirname, '..', 'sessions')
|
||||||
|
|
||||||
|
const directoriesInDIrectory = fs
|
||||||
|
.readdirSync(sessionsPath, { withFileTypes: true })
|
||||||
|
.filter((item) => item.isDirectory())
|
||||||
|
.map((item) => item.name)
|
||||||
|
|
||||||
|
console.log('directoriesInDIrectory: ', directoriesInDIrectory)
|
||||||
|
|
||||||
|
const dirExist = directoriesInDIrectory.filter((e) => e.trim() == app_name)
|
||||||
|
|
||||||
|
console.log('dirExist: ', dirExist)
|
||||||
|
|
||||||
|
if (dirExist.length == 0) res.send('ok')
|
||||||
|
|
||||||
|
for (let i = 0; i < directoriesInDIrectory.length; i++) {
|
||||||
|
console.log('directoriesInDIrectory[i]', directoriesInDIrectory[i])
|
||||||
|
|
||||||
|
const subDir = fs
|
||||||
|
.readdirSync(path.join(sessionsPath, directoriesInDIrectory[i]), {
|
||||||
|
withFileTypes: true,
|
||||||
|
})
|
||||||
|
.filter((item) => item.isDirectory())
|
||||||
|
.map((item) => item.name)
|
||||||
|
|
||||||
|
for (let x = 0; x < subDir.length; x++) {
|
||||||
|
console.log('subdir: ', subDir[x])
|
||||||
|
|
||||||
|
let whatsId = subDir[x].split('_')[0]
|
||||||
|
|
||||||
|
if (whatsId == whatsappId && app_name == directoriesInDIrectory[i]) {
|
||||||
|
let currPath = path.join(
|
||||||
|
sessionsPath,
|
||||||
|
directoriesInDIrectory[i],
|
||||||
|
subDir[x]
|
||||||
|
)
|
||||||
|
|
||||||
|
deletePm2Process(subDir[x], currPath)
|
||||||
|
|
||||||
|
console.log('currPath: ', currPath)
|
||||||
|
|
||||||
|
removeDir(currPath)
|
||||||
|
|
||||||
|
return res.send('ok')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send('ok')
|
||||||
|
})
|
||||||
|
|
||||||
|
app.listen(process.env.PORT || 8003, function () {
|
||||||
|
console.log(
|
||||||
|
'\u26A1[server]: Server is running at Port ::: ' + process.env.PORT || 8003
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
process.on('uncaughtException', function (err) {
|
||||||
|
console.error(' ')
|
||||||
|
console.error(
|
||||||
|
'----- ' + new Date().toUTCString() + ' ----------------------------------'
|
||||||
|
)
|
||||||
|
console.error('Erro uncaughtException: ', err.message)
|
||||||
|
console.error(err.stack)
|
||||||
|
console.error(' ')
|
||||||
|
return
|
||||||
|
})
|
||||||
|
|
||||||
|
function deletePm2Process(process_name, currPath) {
|
||||||
|
pm2.connect(function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pm2.list(function (err, processes) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
processes.forEach(function (process) {
|
||||||
|
console.log('.........process.name: ', process.name)
|
||||||
|
|
||||||
|
if (process.name === process_name) {
|
||||||
|
execSync(
|
||||||
|
`pm2 delete ${process_name} && pm2 save --force`,
|
||||||
|
{ cwd: currPath },
|
||||||
|
(error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
console.log(`error: ${error.message}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (stderr) {
|
||||||
|
console.log(`stderr: ${stderr}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log(`stdout: ${stdout}`)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
pm2.disconnect()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
const mongoose = require('mongoose')
|
||||||
|
require('dotenv').config({ path: `${process.cwd()}/.env` })
|
||||||
|
|
||||||
|
async function main(){
|
||||||
|
await mongoose.connect(process.env.DB_MONGO_URL, { dbName: process.env.DB_MONGO_NAME })
|
||||||
|
console.log('Conectou ao Mongoose!')
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch((err)=>console.log(err))
|
||||||
|
|
||||||
|
module.exports = mongoose
|
|
@ -0,0 +1,27 @@
|
||||||
|
const db = [
|
||||||
|
|
||||||
|
{
|
||||||
|
client_url: "http://localhost:8080",
|
||||||
|
db_conf: {
|
||||||
|
DB: "whaticket",
|
||||||
|
DB_HOST: "localhost",
|
||||||
|
DB_USER: "whaticket",
|
||||||
|
DB_PASS: "strongpassword",
|
||||||
|
DB_PORT: "3306"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
client_url: "http://localhost:8081",
|
||||||
|
db_conf: {
|
||||||
|
DB: "whaticket",
|
||||||
|
DB_HOST: "localhost",
|
||||||
|
DB_USER: "whaticket",
|
||||||
|
DB_PASS: "strongpassword",
|
||||||
|
DB_PORT: "3306"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
module.exports = db;
|
|
@ -0,0 +1,20 @@
|
||||||
|
const bcrypt = require('bcrypt')
|
||||||
|
|
||||||
|
// const pass = async () => {
|
||||||
|
// // create a password
|
||||||
|
// const salt = await bcrypt.genSalt(12)
|
||||||
|
// const passwordHash = await bcrypt.hash('7901228899', salt)
|
||||||
|
// console.log(passwordHash)
|
||||||
|
// }
|
||||||
|
// pass()
|
||||||
|
|
||||||
|
const passDec = async () => {
|
||||||
|
const _pass = await bcrypt.compare(
|
||||||
|
'strongpassword',
|
||||||
|
'$2b$12$PZ8N1jU77nnNUCCGyKTMNOi2QI7X/SgPsISVQfr.cQ/jgdx5Z7AqC'
|
||||||
|
)
|
||||||
|
console.log('_pass: ', _pass)
|
||||||
|
}
|
||||||
|
passDec()
|
||||||
|
|
||||||
|
console.log('process.cwd(): ', process.cwd())
|
|
@ -0,0 +1,17 @@
|
||||||
|
const fsPromises = require("fs/promises");
|
||||||
|
const fs = require('fs-extra')
|
||||||
|
|
||||||
|
// Delete a directory and its children
|
||||||
|
function copyFolder(sourcePath, destPath) {
|
||||||
|
|
||||||
|
fs.copySync(sourcePath, destPath, { overwrite: true }, (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
} else {
|
||||||
|
console.log("Copy dir success!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = copyFolder;
|
|
@ -0,0 +1,22 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
function createDir(dir) {
|
||||||
|
|
||||||
|
// create new directory
|
||||||
|
try {
|
||||||
|
// check if directory already exists
|
||||||
|
if (!fs.existsSync(dir)) {
|
||||||
|
fs.mkdirSync(dir);
|
||||||
|
console.log("Directory is created.");
|
||||||
|
} else {
|
||||||
|
console.log("Directory already exists.");
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = createDir;
|
|
@ -0,0 +1,17 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
function createFile(saveDir, rows, fileName) {
|
||||||
|
|
||||||
|
var stream = fs.createWriteStream(path.join(saveDir, fileName));
|
||||||
|
|
||||||
|
stream.once('open', function (fd) {
|
||||||
|
|
||||||
|
rows.forEach(element => {
|
||||||
|
stream.write(element);
|
||||||
|
});
|
||||||
|
|
||||||
|
stream.end();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = createFile
|
|
@ -0,0 +1,46 @@
|
||||||
|
const pm2 = require('pm2');
|
||||||
|
|
||||||
|
|
||||||
|
function findAndDeletePm2Process(pm2_process_name) {
|
||||||
|
|
||||||
|
pm2.connect(function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
// process.exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
pm2.list(function (err, processes) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
// process.exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
const processToDelete = processes.find(process => process.name === pm2_process_name);
|
||||||
|
|
||||||
|
if (!processToDelete) {
|
||||||
|
console.error('Process not found');
|
||||||
|
// process.exit(2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
pm2.delete(processToDelete.pm_id, function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
// process.exit(2);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
console.log(`Process deleted: ${pm2_process_name}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
pm2.disconnect();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = findAndDeletePm2Process
|
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
function getNumberFromName(name) {
|
||||||
|
|
||||||
|
name = name + ' '
|
||||||
|
|
||||||
|
let number = name.split('')
|
||||||
|
|
||||||
|
let newNumber = ''
|
||||||
|
let list = []
|
||||||
|
|
||||||
|
for (let i = 0; i < number.length; i++) {
|
||||||
|
|
||||||
|
if (!isNaN(Number(number[i])) && number[i].trim().length > 0) {
|
||||||
|
newNumber += number[i]
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!isNaN(Number(newNumber)) && newNumber.trim().length > 0) {
|
||||||
|
list.push(newNumber)
|
||||||
|
}
|
||||||
|
newNumber = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// longestString = list.filter(str => str.length === Math.max(...list.map(s => s.length)))[0];
|
||||||
|
|
||||||
|
// console.log('list: ', list)
|
||||||
|
|
||||||
|
|
||||||
|
let longestString = ""; // variable to store the longest string
|
||||||
|
for (let i = 0; i < list.length; i++) {
|
||||||
|
if (list[i].length > longestString.length) {
|
||||||
|
longestString = list[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return longestString
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = getNumberFromName;
|
|
@ -0,0 +1,109 @@
|
||||||
|
const dotenv = require('dotenv');
|
||||||
|
dotenv.config({ path: `${process.cwd()}/.env` });
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
|
||||||
|
function mysql_conn(config) {
|
||||||
|
// Ubicua Plataform - MYSQL Module
|
||||||
|
try {
|
||||||
|
var mysql_npm = require('mysql');
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Cannot find `mysql` module. Is it installed ? Try `npm install mysql` or `npm install`.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var db_config = {
|
||||||
|
host: config.DB_HOST,
|
||||||
|
user: config.DB_USER,
|
||||||
|
password: config.DB_PASS,
|
||||||
|
database: config.DB,
|
||||||
|
charset: 'utf8mb4_general_ci',
|
||||||
|
port: config.DB_PORT
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-
|
||||||
|
//- Create the connection variable
|
||||||
|
//-
|
||||||
|
var connection = mysql_npm.createPool(db_config);
|
||||||
|
|
||||||
|
|
||||||
|
//-
|
||||||
|
//- Establish a new connection
|
||||||
|
//-
|
||||||
|
connection.getConnection(function (err) {
|
||||||
|
if (err) {
|
||||||
|
// mysqlErrorHandling(connection, err);
|
||||||
|
console.log("\n\t *** Cannot establish a connection with the database. ***");
|
||||||
|
|
||||||
|
connection = reconnect(connection);
|
||||||
|
} else {
|
||||||
|
console.log("\n\t *** New connection established with the database. ***")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//-
|
||||||
|
//- Reconnection function
|
||||||
|
//-
|
||||||
|
function reconnect(connection) {
|
||||||
|
console.log("\n New connection tentative...");
|
||||||
|
|
||||||
|
//- Create a new one
|
||||||
|
connection = mysql_npm.createPool(db_config);
|
||||||
|
|
||||||
|
//- Try to reconnect
|
||||||
|
connection.getConnection(function (err) {
|
||||||
|
if (err) {
|
||||||
|
//- Try to connect every 2 seconds.
|
||||||
|
setTimeout(reconnect(connection), 2000);
|
||||||
|
} else {
|
||||||
|
console.log("\n\t *** New connection established with the database. ***")
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-
|
||||||
|
//- Error listener
|
||||||
|
//-
|
||||||
|
connection.on('error', function (err) {
|
||||||
|
|
||||||
|
//-
|
||||||
|
//- The server close the connection.
|
||||||
|
//-
|
||||||
|
if (err.code === "PROTOCOL_CONNECTION_LOST") {
|
||||||
|
console.log("/!\\ Cannot establish a connection with the database. /!\\ (" + err.code + ")");
|
||||||
|
return reconnect(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (err.code === "PROTOCOL_ENQUEUE_AFTER_QUIT") {
|
||||||
|
console.log("/!\\ Cannot establish a connection with the database. /!\\ (" + err.code + ")");
|
||||||
|
return reconnect(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (err.code === "PROTOCOL_ENQUEUE_AFTER_FATAL_ERROR") {
|
||||||
|
console.log("/!\\ Cannot establish a connection with the database. /!\\ (" + err.code + ")");
|
||||||
|
return reconnect(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (err.code === "PROTOCOL_ENQUEUE_HANDSHAKE_TWICE") {
|
||||||
|
console.log("/!\\ Cannot establish a connection with the database. /!\\ (" + err.code + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
console.log("/!\\ Cannot establish a connection with the database. /!\\ (" + err.code + ")");
|
||||||
|
return reconnect(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return connection
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-
|
||||||
|
//- Export
|
||||||
|
//-
|
||||||
|
module.exports = mysql_conn;
|
|
@ -0,0 +1,17 @@
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
async function postData(url, body = {}) {
|
||||||
|
|
||||||
|
let response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = await axios.post(url, body);
|
||||||
|
console.log(response.data); // handle successful response
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error); // handle error
|
||||||
|
}
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = postData
|
|
@ -0,0 +1,28 @@
|
||||||
|
const fsPromises = require("fs/promises");
|
||||||
|
const fs = require('fs')
|
||||||
|
|
||||||
|
// Delete a directory and its children
|
||||||
|
const removeDir = async (dirPath) => {
|
||||||
|
|
||||||
|
if (fs.existsSync(dirPath)) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fsPromises.rm(dirPath, { recursive: true, force: true });
|
||||||
|
console.log("Directory removed!");
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log('An error occurred while removing the directory: ', err);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log('Directory not found to remove: ', dirPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = removeDir ;
|
|
@ -0,0 +1,152 @@
|
||||||
|
|
||||||
|
import os from 'os';
|
||||||
|
import dir from 'path';
|
||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
|
export const setJSON = (obj) => {
|
||||||
|
|
||||||
|
const sessionControlFile = dir.join(process.cwd(), `sessionsDir.json`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (fs.existsSync(sessionControlFile)) {
|
||||||
|
|
||||||
|
const sessionsDir = fs.readFileSync(sessionControlFile, { encoding: 'utf8', flag: 'r' });
|
||||||
|
|
||||||
|
let lstRestore = JSON.parse(sessionsDir)
|
||||||
|
|
||||||
|
lstRestore.push(obj)
|
||||||
|
|
||||||
|
fs.writeFileSync(sessionControlFile, JSON.stringify(lstRestore), "utf8");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
console.log('sessionsDir.json file not found! It will be created.');
|
||||||
|
|
||||||
|
if (Array.isArray(obj)) {
|
||||||
|
|
||||||
|
fs.writeFileSync(sessionControlFile, JSON.stringify(obj), "utf8");
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
fs.writeFileSync(sessionControlFile, JSON.stringify([obj]), "utf8");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log('There was an error on try to read the sessionsDir.json file: ', error)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const shifRestoreControll = () => {
|
||||||
|
|
||||||
|
const sessionControlFile = dir.join(os.tmpdir(), `sessionsDir.json`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (fs.existsSync(sessionControlFile)) {
|
||||||
|
|
||||||
|
const sessionsDir = fs.readFileSync(sessionControlFile, { encoding: 'utf8', flag: 'r' });
|
||||||
|
|
||||||
|
let lstRestore: any = JSON.parse(sessionsDir)
|
||||||
|
|
||||||
|
let whatsapp: any = lstRestore.shift()
|
||||||
|
|
||||||
|
fs.writeFileSync(sessionControlFile, JSON.stringify(lstRestore), "utf8");
|
||||||
|
|
||||||
|
return whatsapp
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log('There was an error on try to read the sessionsDir.json file: ', error)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const delRestoreControllFile = () => {
|
||||||
|
|
||||||
|
const sessionControlFile = dir.join(os.tmpdir(), `sessionsDir.json`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (fs.existsSync(sessionControlFile)) {
|
||||||
|
|
||||||
|
fs.unlinkSync(sessionControlFile)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
console.log('sessionsDir.json file not found!');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log('There was an error on try delete the sessionsDir.json file: ', error)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const getRestoreControll = () => {
|
||||||
|
|
||||||
|
const sessionControlFile = dir.join(os.tmpdir(), `sessionsDir.json`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (fs.existsSync(sessionControlFile)) {
|
||||||
|
|
||||||
|
const sessionsDir = fs.readFileSync(sessionControlFile, { encoding: 'utf8', flag: 'r' });
|
||||||
|
|
||||||
|
let lstRestore: any = JSON.parse(sessionsDir)
|
||||||
|
|
||||||
|
return lstRestore
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
console.log('sessionsDir.json file not found!');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log('There was an error on try to read the sessionsDir.json file: ', error)
|
||||||
|
}
|
||||||
|
|
||||||
|
return []
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const _restore = async (whatsapp: Whatsapp, msg_file_title: string) => {
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
if (whatsapp.status != 'RESTORING' && whatsapp.status != 'qrcode') {
|
||||||
|
|
||||||
|
console.log('THE WHATSAAP ID: ', whatsapp.id, ' WILL BE RESTORED SOON!')
|
||||||
|
|
||||||
|
await whatsapp.update({ status: "RESTORING", });
|
||||||
|
|
||||||
|
const io = getIO();
|
||||||
|
|
||||||
|
io.emit("whatsappSession", {
|
||||||
|
action: "update",
|
||||||
|
session: whatsapp
|
||||||
|
});
|
||||||
|
|
||||||
|
// await insertOrUpeateWhatsCache(`whatsapp:${whatsapp.id}`, { status: "RESTORING", })
|
||||||
|
|
||||||
|
setTimeout(async () => await autoRestore(whatsapp.id, msg_file_title), 95000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
let mysql_conn = require('./mysql_conn.js');
|
||||||
|
|
||||||
|
async function sessionNumber(db_info, whatsappId, number, dirSessionsApp) {
|
||||||
|
|
||||||
|
let numberSession = 1
|
||||||
|
|
||||||
|
let whatsappName
|
||||||
|
|
||||||
|
const dirSessionsNumberAppDirectories = fs.readdirSync(dirSessionsApp, { withFileTypes: true })
|
||||||
|
.filter((item) => item.isDirectory() && item.name.includes(`${number}`))
|
||||||
|
.map((item) => item.name);
|
||||||
|
|
||||||
|
if (dirSessionsNumberAppDirectories.length > 0) {
|
||||||
|
|
||||||
|
let session_number = dirSessionsNumberAppDirectories.map((e) => +e.split('_')[2])
|
||||||
|
|
||||||
|
numberSession = Math.max(...session_number) + 1
|
||||||
|
|
||||||
|
console.log('Number session: ', numberSession)
|
||||||
|
|
||||||
|
|
||||||
|
if (numberSession > 4) {
|
||||||
|
res.status(400).json({ message: 'Cannot create more than 4 sessions from the same number' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let db = db_info.filter((e) => e.client_url == client_url)
|
||||||
|
|
||||||
|
|
||||||
|
if (db && db.length > 0) {
|
||||||
|
|
||||||
|
db = db[0].db_conf
|
||||||
|
|
||||||
|
let whatsName
|
||||||
|
|
||||||
|
const whatsapp = await new Promise((resolve, reject) => {
|
||||||
|
|
||||||
|
mysql_conn(db).query("SELECT name from Whatsapps where id = ?", [whatsappId], (err, result) => {
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resolve(result)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
if (whatsapp[0]["name"].split('->').length > 0) {
|
||||||
|
whatsName = `${whatsapp[0]["name"].split('->')[0]} -> S${numberSession}`
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
whatsName = `${whatsapp[0]["name"]} -> S${numberSession}`
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('whatsName: ', whatsName)
|
||||||
|
|
||||||
|
console.log(`url: ${process.env.BASE_URL}:${appPort}\n whatsname: ${whatsName}\n whatsappId: ${whatsappId}`)
|
||||||
|
|
||||||
|
// await new Promise((resolve, reject) => {
|
||||||
|
// mysql_conn(db).query("UPDATE Whatsapps SET name = ? where id = ?", [ `${whatsName}`, whatsappId],
|
||||||
|
|
||||||
|
// function (err, result) {
|
||||||
|
// if (err) {
|
||||||
|
// reject(err)
|
||||||
|
// console.log("===> ERROR: " + err);
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// resolve(result)
|
||||||
|
// console.log('RESULT: ', result)
|
||||||
|
// }
|
||||||
|
// // else
|
||||||
|
// // console.log('myslq result: ', result);
|
||||||
|
// });
|
||||||
|
// })
|
||||||
|
|
||||||
|
whatsappName = `${number} - s${numberSession}`
|
||||||
|
|
||||||
|
console.log('-------------- numberSession', numberSession)
|
||||||
|
|
||||||
|
if (whatsapp.length > 0) {
|
||||||
|
|
||||||
|
if (whatsapp[0]['name'].split(' ').length > 0) {
|
||||||
|
|
||||||
|
whatsappName = `${whatsapp[0]['name'].split(' ')[0]} - S${numberSession}`
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('---------> whatsappName', whatsappName)
|
||||||
|
|
||||||
|
return whatsappName
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = sessionNumber
|
|
@ -0,0 +1,50 @@
|
||||||
|
const pm2 = require('pm2')
|
||||||
|
const { execSync } = require("child_process")
|
||||||
|
|
||||||
|
function startPm2Process(process_name, file, path, env) {
|
||||||
|
|
||||||
|
pm2.connect(function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err)
|
||||||
|
// process.exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('ENV PM2: ', env)
|
||||||
|
|
||||||
|
pm2.start({
|
||||||
|
name: process_name,
|
||||||
|
script: file,
|
||||||
|
cwd: path,
|
||||||
|
env
|
||||||
|
// env: {
|
||||||
|
// NODE_ENV: 'production',
|
||||||
|
|
||||||
|
// PORT: port,
|
||||||
|
// }
|
||||||
|
// additional options here if needed
|
||||||
|
}, function (err, apps) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err)
|
||||||
|
// process.exit(2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
execSync(`pm2 save --force`, { cwd: path }, (error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
console.log(`error: ${error.message}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (stderr) {
|
||||||
|
console.log(`stderr: ${stderr}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log(`stdout: ${stdout}`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pm2.disconnect()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = startPm2Process
|
|
@ -0,0 +1,33 @@
|
||||||
|
const mongoose = require('../db/connMongo')
|
||||||
|
const { Schema } = mongoose
|
||||||
|
|
||||||
|
const OmnihitDBConn = mongoose.model(
|
||||||
|
'Omnihit_db_conn',
|
||||||
|
new Schema(
|
||||||
|
{
|
||||||
|
client_url: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
db_conf: {
|
||||||
|
DB: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
DB_HOST: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
DB_USER: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
DB_PASS: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
DB_PORT: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ timestamps: true }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
module.exports = OmnihitDBConn
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"name": "api-sessions-controller",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "nodemon app.js",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "Adriano <adriano08andrade@hotmail.com>",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bcrypt": "^5.1.0",
|
||||||
|
"body-parser": "^1.20.1",
|
||||||
|
"dotenv": "^16.0.3",
|
||||||
|
"express": "^4.18.2",
|
||||||
|
"fs-extra": "^11.1.0",
|
||||||
|
"mongoose": "^7.4.0",
|
||||||
|
"mysql": "^2.18.1",
|
||||||
|
"nodemon": "^2.0.20",
|
||||||
|
"socket.io": "^4.5.4"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
# NUMBER AND NAME THAT WILL BE DISPLAYED ON CONSOLE
|
||||||
|
MOBILEUID=5517988310949
|
||||||
|
MOBILENAME=test - S1
|
||||||
|
|
||||||
|
# PORT NUMBER FOR THIS API
|
||||||
|
PORT=8029
|
||||||
|
|
||||||
|
# URL FROM THE OMNIHIT BACKEND API
|
||||||
|
CLIENT_URL=http://localhost:8080
|
||||||
|
|
||||||
|
# OMNIHIT DATABASE
|
||||||
|
DB=whaticket
|
||||||
|
DB_HOST=localhost
|
||||||
|
DB_USER=whaticket
|
||||||
|
DB_PASS=strongpassword
|
||||||
|
DB_PORT=3306
|
||||||
|
|
||||||
|
# WHATSAPP ID OF THE TABLE Whatsapps FROM THE OMNIHIT DATABASE
|
||||||
|
WHATSAPP_ID=223
|
||||||
|
|
||||||
|
# MONGO CONNECTION
|
||||||
|
DB_MONGO_URL=mongodb://localhost:27017
|
||||||
|
|
||||||
|
# MONGO COLLECTION
|
||||||
|
DB_MONGO_NAME=broker_omnihit
|
|
@ -0,0 +1,31 @@
|
||||||
|
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
node_modules
|
||||||
|
/node_modules
|
||||||
|
|
||||||
|
/medias/*.*
|
||||||
|
/medias/in/*.*
|
||||||
|
|
||||||
|
|
||||||
|
/WWebJS/session-OmniHIT/Default/**
|
||||||
|
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
|
DevToolsActivePort*
|
||||||
|
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,141 @@
|
||||||
|
const dotenv = require('dotenv');
|
||||||
|
dotenv.config({ path: `${process.cwd()}/.env` });
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
const MongoClient = require( 'mongodb' ).MongoClient;
|
||||||
|
|
||||||
|
const url = process.env.DB_URL;
|
||||||
|
|
||||||
|
var _db;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
|
||||||
|
connectToServer: function( callback ) {
|
||||||
|
|
||||||
|
MongoClient.connect( url, { useNewUrlParser: true }, function( err, client ) {
|
||||||
|
|
||||||
|
_db = client.db(process.env.DB_NAME);
|
||||||
|
|
||||||
|
return callback( err );
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
getDb: function() {
|
||||||
|
|
||||||
|
return _db;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// // PRODUCTION CONNECTION
|
||||||
|
// const MongoClient = require( 'mongodb' ).MongoClient;
|
||||||
|
|
||||||
|
// const url = "mongodb://admin:d1nf54012022prod*@172.31.187.8:27017";
|
||||||
|
|
||||||
|
// var _db;
|
||||||
|
|
||||||
|
// module.exports = {
|
||||||
|
|
||||||
|
// connectToServer: function( callback ) {
|
||||||
|
|
||||||
|
// MongoClient.connect( url, { useNewUrlParser: true }, function( err, client ) {
|
||||||
|
|
||||||
|
// _db = client.db('db_omnihit');
|
||||||
|
|
||||||
|
// return callback( err );
|
||||||
|
|
||||||
|
// } );
|
||||||
|
|
||||||
|
// },
|
||||||
|
|
||||||
|
// getDb: function() {
|
||||||
|
|
||||||
|
// return _db;
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
// LOCA CONNECTION
|
||||||
|
// const MongoClient = require( 'mongodb' ).MongoClient;
|
||||||
|
|
||||||
|
// const url = 'mongodb://localhost:27017';
|
||||||
|
|
||||||
|
// var _db;
|
||||||
|
|
||||||
|
// module.exports = {
|
||||||
|
|
||||||
|
// connectToServer: function( callback ) {
|
||||||
|
// MongoClient.connect( url, { useNewUrlParser: true }, function( err, client ) {
|
||||||
|
// _db = client.db('db_omnihit');
|
||||||
|
// return callback( err );
|
||||||
|
// } );
|
||||||
|
// },
|
||||||
|
|
||||||
|
// getDb: function() {
|
||||||
|
// return _db;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
const MongoClient = require( 'mongodb' ).MongoClient;
|
||||||
|
|
||||||
|
const url = "mongodb://admin:d1nf54012022*@172.31.187.2:27017";
|
||||||
|
|
||||||
|
var _db;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
|
||||||
|
connectToServer: function( callback ) {
|
||||||
|
|
||||||
|
MongoClient.connect( url, { useNewUrlParser: true }, function( err, client ) {
|
||||||
|
|
||||||
|
_db = client.db('db_omnihit_todoo');
|
||||||
|
|
||||||
|
return callback( err );
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
getDb: function() {
|
||||||
|
|
||||||
|
return _db;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// const MongoClient = require( 'mongodb' ).MongoClient;
|
||||||
|
|
||||||
|
// const url = "mongodb://admin:d1nf5401@192.168.15.13/admin?retryWrites=true&w=majority";
|
||||||
|
|
||||||
|
// var _db;
|
||||||
|
|
||||||
|
// module.exports = {
|
||||||
|
|
||||||
|
// connectToServer: function( callback ) {
|
||||||
|
// MongoClient.connect( url, { useNewUrlParser: true }, function( err, client ) {
|
||||||
|
// _db = client.db('db_omnihit');
|
||||||
|
// return callback( err );
|
||||||
|
// } );
|
||||||
|
// },
|
||||||
|
|
||||||
|
// getDb: function() {
|
||||||
|
// return _db;
|
||||||
|
// }
|
||||||
|
// };
|
|
@ -0,0 +1,18 @@
|
||||||
|
const { MongoClient } = require('mongodb')
|
||||||
|
|
||||||
|
const uri = process.env.DB_MONGO_URL
|
||||||
|
|
||||||
|
const mongo = new MongoClient(uri)
|
||||||
|
|
||||||
|
async function run() {
|
||||||
|
try {
|
||||||
|
await mongo.connect()
|
||||||
|
console.log('Connectado ao mongo db')
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run()
|
||||||
|
|
||||||
|
module.exports = mongo
|
|
@ -0,0 +1,85 @@
|
||||||
|
const os = require('os');
|
||||||
|
const dbcloud = require('./dbcloud.js');
|
||||||
|
const dotenv = require('dotenv');
|
||||||
|
const axios = require('axios').default;
|
||||||
|
dotenv.config({path: '../.env'});
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
|
||||||
|
// qrcode: async function(mobileuid, mobilename, qr ) {
|
||||||
|
// payload = {}
|
||||||
|
// payload['mobileuid'] = mobileuid;
|
||||||
|
// payload['mobilename'] = mobilename;
|
||||||
|
// payload['qrcode'] = qr;
|
||||||
|
// await axios.post(process.env.URL_QRCODE, payload, { timeout: 2000, headers: { 'content-type': 'application/json' } });
|
||||||
|
// console.log(new Date().toISOString() + " >>> SEND QR CODE ---------------------------------------");
|
||||||
|
// return 200;
|
||||||
|
// },
|
||||||
|
|
||||||
|
monitor: async function(mobileuid, mobilename, stat) {
|
||||||
|
|
||||||
|
|
||||||
|
let _totalmem = parseInt(os.totalmem());
|
||||||
|
let _freemem = parseInt(os.freemem());
|
||||||
|
let _memory = 100 - (_freemem / _totalmem * 100);
|
||||||
|
|
||||||
|
|
||||||
|
payload = {}
|
||||||
|
payload['mobileuid'] = mobileuid;
|
||||||
|
payload['mobilename'] = mobilename;
|
||||||
|
payload['memory'] = _memory;
|
||||||
|
|
||||||
|
let db = dbcloud.getDb();
|
||||||
|
|
||||||
|
let mco = await db.collection('tab_counts').find({ "_id": mobileuid }).limit(1).toArray();
|
||||||
|
|
||||||
|
if ( mco.length == 0 ) {
|
||||||
|
payload['_id'] = mobileuid;
|
||||||
|
payload['hour'] = 0;
|
||||||
|
payload['in'] = 0;
|
||||||
|
payload['out'] = 0;
|
||||||
|
payload['lastmessage'] = new Date(new Date() + 'UTC');
|
||||||
|
|
||||||
|
payload['in_today'] = 0;
|
||||||
|
payload['out_today'] = 0;
|
||||||
|
|
||||||
|
await db.collection('tab_counts').insertOne(payload);
|
||||||
|
|
||||||
|
}else{
|
||||||
|
payload['hour'] = mco[0]['hour'];
|
||||||
|
payload['in'] = mco[0]['in'];
|
||||||
|
payload['out'] = mco[0]['out'];
|
||||||
|
payload['lastmessage'] = mco[0]['lastmessage']
|
||||||
|
payload['in_today'] = mco[0]['in_today'];
|
||||||
|
payload['out_today'] = mco[0]['out_today'];
|
||||||
|
}
|
||||||
|
|
||||||
|
payload['dt'] = new Date(new Date() + 'UTC');
|
||||||
|
payload['status'] = stat;
|
||||||
|
|
||||||
|
|
||||||
|
console.log(new Date().toISOString() + " >>> SEND MONITOR ALARM ---------------------------------------");
|
||||||
|
console.log(new Date().toISOString() + " >>> payload: ",payload);
|
||||||
|
|
||||||
|
|
||||||
|
let monitor = await db.collection('tab_monitor').find({ "_id": mobileuid }).limit(1).toArray();
|
||||||
|
|
||||||
|
if ( monitor.length == 0 ) {
|
||||||
|
|
||||||
|
payload['_id'] = mobileuid
|
||||||
|
|
||||||
|
await db.collection('tab_monitor').insertOne(payload);
|
||||||
|
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
|
||||||
|
await db.collection('tab_monitor').updateOne({ "_id": mobileuid }, { $set: payload }, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return 200;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
module.exports = function() {
|
||||||
|
|
||||||
|
this.getTimestamp = function() {
|
||||||
|
var date = new Date();
|
||||||
|
var year = date.getFullYear();
|
||||||
|
var month = ("0"+(date.getMonth()+1)).substr(-2);
|
||||||
|
var day = ("0"+date.getDate()).substr(-2);
|
||||||
|
var hour = ("0"+date.getHours()).substr(-2);
|
||||||
|
var minutes = ("0"+date.getMinutes()).substr(-2);
|
||||||
|
var seconds = ("0"+date.getSeconds()).substr(-2);
|
||||||
|
return year+"-"+month+"-"+day+" "+hour+":"+minutes+":"+seconds;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.log = function(desc, message) {
|
||||||
|
console.log(getTimestamp() + ' >> ' + desc + " :: ");
|
||||||
|
console.log(message);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getTime = function() {
|
||||||
|
var date = new Date();
|
||||||
|
var hour = ("0"+date.getHours()).substr(-2);
|
||||||
|
var minutes = ("0"+date.getMinutes()).substr(-2);
|
||||||
|
var seconds = ("0"+date.getSeconds()).substr(-2);
|
||||||
|
return hour+":"+minutes+":"+seconds;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.forceGC = function() {
|
||||||
|
if (global.gc) {
|
||||||
|
console.log(getTimestamp() + " >> Starting Garbage Collector...");
|
||||||
|
global.gc();
|
||||||
|
} else {
|
||||||
|
console.warn("Garbage Collector não habilitado! Execute seu programa com node --expose-gc app.js.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.isJSON = function(str) {
|
||||||
|
try {
|
||||||
|
return (JSON.parse(str) && !!str);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
const removeDir = require('./remove_dir');
|
||||||
|
const copyFolder = require('./copyFolder');
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
|
||||||
|
async function backup_session(destroy, save_session_after, save_first_read_only=false) {
|
||||||
|
|
||||||
|
console.log('process.cwd(): ', process.cwd())
|
||||||
|
|
||||||
|
|
||||||
|
const sessionBackupPath = path.join(process.cwd(), `session_backup`, `session-omnihit_sesssion`)
|
||||||
|
|
||||||
|
if (fs.existsSync(sessionBackupPath) && save_first_read_only) return
|
||||||
|
|
||||||
|
destroy = setTimeout(async () => {
|
||||||
|
|
||||||
|
const sessionPath = path.join(process.cwd(), '.wwebjs_auth', 'session-omnihit_sesssion')
|
||||||
|
|
||||||
|
if (fs.existsSync(path.join(process.cwd(), '.wwebjs_auth'))) {
|
||||||
|
|
||||||
|
await removeDir(sessionBackupPath)
|
||||||
|
|
||||||
|
// copy the good session for backup dir
|
||||||
|
|
||||||
|
copyFolder(sessionPath, sessionBackupPath)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log('Directory not found to copy backup_session: ', sessionPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}, save_session_after);
|
||||||
|
|
||||||
|
return destroy
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = backup_session;
|
|
@ -0,0 +1,41 @@
|
||||||
|
const http = require('http')
|
||||||
|
|
||||||
|
const checkInternetConnection = async () => {
|
||||||
|
const options = {
|
||||||
|
hostname: 'www.google.com',
|
||||||
|
port: 80,
|
||||||
|
method: 'HEAD'
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const req = http.request(options, (res) => {
|
||||||
|
if (res.statusCode === 200) {
|
||||||
|
resolve(true)
|
||||||
|
} else {
|
||||||
|
resolve(false)
|
||||||
|
}
|
||||||
|
req.abort()
|
||||||
|
})
|
||||||
|
|
||||||
|
req.on('error', (err) => {
|
||||||
|
resolve(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
req.end()
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
// (async () => {
|
||||||
|
// try {
|
||||||
|
// const isConnected = await checkInternetConnection()
|
||||||
|
// if (isConnected) {
|
||||||
|
// console.log('Internet connection is available.')
|
||||||
|
// } else {
|
||||||
|
// console.log('Internet connection is not available.')
|
||||||
|
// }
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error('Error checking internet connection:', error)
|
||||||
|
// }
|
||||||
|
// })()
|
||||||
|
|
||||||
|
module.exports = checkInternetConnection
|
|
@ -0,0 +1,17 @@
|
||||||
|
const fsPromises = require("fs/promises");
|
||||||
|
const fs = require('fs-extra')
|
||||||
|
|
||||||
|
// Delete a directory and its children
|
||||||
|
function copyFolder(sourcePath, destPath) {
|
||||||
|
|
||||||
|
fs.copySync(sourcePath, destPath, { overwrite: true }, (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
} else {
|
||||||
|
console.log("Copy dir success!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = copyFolder;
|
|
@ -0,0 +1,36 @@
|
||||||
|
const multer = require('multer')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Destination to store the images
|
||||||
|
const imageStorage = multer.diskStorage({
|
||||||
|
destination: function(req, file, cb){
|
||||||
|
|
||||||
|
// let folder = ""
|
||||||
|
// if(req.baseUrl.includes("users")){
|
||||||
|
// folder = "users"
|
||||||
|
// }else if(req.baseUrl.includes("pets")){
|
||||||
|
// folder = "pets"
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
cb(null, path.join(process.cwd(),'medias', 'out'))
|
||||||
|
},
|
||||||
|
filename: function(req, file, cb) {
|
||||||
|
cb(null, Date.now() + path.extname(file.originalname))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const imageUpload = multer({
|
||||||
|
storage: imageStorage,
|
||||||
|
// fileFilter(req, file, cb){
|
||||||
|
// if (!file.originalname.match(/\.(jpg|jpeg|png)$/)){
|
||||||
|
// return cb(new Error('Por favor, envie apenas jpg ou png!'))
|
||||||
|
// }
|
||||||
|
// cb(undefined, true)
|
||||||
|
// }
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = { imageUpload }
|
|
@ -0,0 +1,129 @@
|
||||||
|
const dotenv = require('dotenv');
|
||||||
|
dotenv.config({ path: `${process.cwd()}/.env` });
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
|
||||||
|
// Ubicua Plataform - MYSQL Module
|
||||||
|
try{
|
||||||
|
var mysql_npm = require('mysql');
|
||||||
|
}catch(err){
|
||||||
|
console.log("Cannot find `mysql` module. Is it installed ? Try `npm install mysql` or `npm install`.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var db_config = {
|
||||||
|
host : process.env.DB_HOST,
|
||||||
|
user : process.env.DB_USER,
|
||||||
|
password : process.env.DB_PASS,
|
||||||
|
database : process.env.DB,
|
||||||
|
charset : 'utf8mb4_general_ci',
|
||||||
|
port : process.env.DB_PORT
|
||||||
|
};
|
||||||
|
|
||||||
|
//-
|
||||||
|
//- Connection configuration
|
||||||
|
//-
|
||||||
|
// var db_config = {
|
||||||
|
// host : 'localhost',
|
||||||
|
// user : 'whaticket',
|
||||||
|
// password : '9147teste',
|
||||||
|
// database : 'db_cdnwork',
|
||||||
|
// charset : 'utf8mb4_general_ci',
|
||||||
|
// port : '6603'
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// var db_config = {
|
||||||
|
// host : '172.31.187.7',
|
||||||
|
// user : 'todoo',
|
||||||
|
// password : '7901228899',
|
||||||
|
// database : 'db_cdnwork',
|
||||||
|
// charset : 'utf8mb4_general_ci'
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-
|
||||||
|
//- Create the connection variable
|
||||||
|
//-
|
||||||
|
var connection = mysql_npm.createPool(db_config);
|
||||||
|
|
||||||
|
|
||||||
|
//-
|
||||||
|
//- Establish a new connection
|
||||||
|
//-
|
||||||
|
connection.getConnection(function(err){
|
||||||
|
if(err) {
|
||||||
|
// mysqlErrorHandling(connection, err);
|
||||||
|
console.log("\n\t *** Cannot establish a connection with the database. ***");
|
||||||
|
|
||||||
|
connection = reconnect(connection);
|
||||||
|
}else {
|
||||||
|
console.log("\n\t *** New connection established with the database. ***")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//-
|
||||||
|
//- Reconnection function
|
||||||
|
//-
|
||||||
|
function reconnect(connection){
|
||||||
|
console.log("\n New connection tentative...");
|
||||||
|
|
||||||
|
//- Create a new one
|
||||||
|
connection = mysql_npm.createPool(db_config);
|
||||||
|
|
||||||
|
//- Try to reconnect
|
||||||
|
connection.getConnection(function(err){
|
||||||
|
if(err) {
|
||||||
|
//- Try to connect every 2 seconds.
|
||||||
|
setTimeout(reconnect(connection), 2000);
|
||||||
|
}else {
|
||||||
|
console.log("\n\t *** New connection established with the database. ***")
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-
|
||||||
|
//- Error listener
|
||||||
|
//-
|
||||||
|
connection.on('error', function(err) {
|
||||||
|
|
||||||
|
//-
|
||||||
|
//- The server close the connection.
|
||||||
|
//-
|
||||||
|
if(err.code === "PROTOCOL_CONNECTION_LOST"){
|
||||||
|
console.log("/!\\ Cannot establish a connection with the database. /!\\ ("+err.code+")");
|
||||||
|
return reconnect(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(err.code === "PROTOCOL_ENQUEUE_AFTER_QUIT"){
|
||||||
|
console.log("/!\\ Cannot establish a connection with the database. /!\\ ("+err.code+")");
|
||||||
|
return reconnect(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(err.code === "PROTOCOL_ENQUEUE_AFTER_FATAL_ERROR"){
|
||||||
|
console.log("/!\\ Cannot establish a connection with the database. /!\\ ("+err.code+")");
|
||||||
|
return reconnect(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(err.code === "PROTOCOL_ENQUEUE_HANDSHAKE_TWICE"){
|
||||||
|
console.log("/!\\ Cannot establish a connection with the database. /!\\ ("+err.code+")");
|
||||||
|
}
|
||||||
|
|
||||||
|
else{
|
||||||
|
console.log("/!\\ Cannot establish a connection with the database. /!\\ ("+err.code+")");
|
||||||
|
return reconnect(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//-
|
||||||
|
//- Export
|
||||||
|
//-
|
||||||
|
module.exports = connection;
|
|
@ -0,0 +1,28 @@
|
||||||
|
const fsPromises = require("fs/promises");
|
||||||
|
const fs = require('fs')
|
||||||
|
|
||||||
|
// Delete a directory and its children
|
||||||
|
const removeDir = async (dirPath) => {
|
||||||
|
|
||||||
|
if (fs.existsSync(dirPath)) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fsPromises.rm(dirPath, { recursive: true, force: true });
|
||||||
|
console.log("Directory removed!");
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log('An error occurred while removing the directory: ', err);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log('Directory not found to remove: ', dirPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = removeDir ;
|
|
@ -0,0 +1,39 @@
|
||||||
|
const removeDir = require('./remove_dir');
|
||||||
|
const copyFolder = require('./copyFolder');
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
|
||||||
|
async function restore(client) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
await client.destroy()
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error on try destroy client: ${error}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const sessionBackupPath = path.join(process.cwd(), `session_backup`, `session-omnihit_sesssion`)
|
||||||
|
|
||||||
|
const sessionPath = path.join(process.cwd(), '.wwebjs_auth', 'session-omnihit_sesssion')
|
||||||
|
|
||||||
|
if (fs.existsSync(path.join(process.cwd(), `session_backup`, `session-omnihit_sesssion`))) {
|
||||||
|
|
||||||
|
await removeDir(sessionPath)
|
||||||
|
|
||||||
|
// copy the good session for backup dir
|
||||||
|
copyFolder(sessionBackupPath, sessionPath)
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log('Directory not found to copy: ', sessionPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('process.exit: kkkkkkkkkkkkkkkkkkkkk')
|
||||||
|
process.exit()
|
||||||
|
}, 5000)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = restore;
|
|
@ -0,0 +1,67 @@
|
||||||
|
|
||||||
|
|
||||||
|
var io = require('socket.io-client');
|
||||||
|
|
||||||
|
var lst = []
|
||||||
|
|
||||||
|
const _clear_lst = () => {
|
||||||
|
|
||||||
|
if (lst.length <= 199) return
|
||||||
|
|
||||||
|
const chunk = Math.floor((lst.length / 2))
|
||||||
|
|
||||||
|
lst = lst.slice(chunk, chunk + lst.length);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const multisessionIdControll = (msgId) => {
|
||||||
|
|
||||||
|
_clear_lst()
|
||||||
|
|
||||||
|
let index = lst.findIndex((x) => x.id == msgId)
|
||||||
|
|
||||||
|
console.log('INDEX: ', index)
|
||||||
|
|
||||||
|
if (index == -1) {
|
||||||
|
|
||||||
|
lst.push({ id: msgId })
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log('IGNORED ID: ', msgId)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log('LIST OF ID MESSAGE lst: ', lst)
|
||||||
|
|
||||||
|
console.log('PASSOU.................................ID: ', msgId)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const initIO = (url) => {
|
||||||
|
|
||||||
|
const socket = io(url, { reconnect: true });
|
||||||
|
|
||||||
|
socket.on('connect', async () => {
|
||||||
|
console.log('Made socket connection2');
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('messageId', messageId => {
|
||||||
|
|
||||||
|
console.log('-------> messageId: ', messageId);
|
||||||
|
|
||||||
|
multisessionIdControll(messageId)
|
||||||
|
|
||||||
|
console.log('socket lst: ', lst)
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return socket;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = { initIO, lst }
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"name": "omnihit",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "app.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"start": "nodemon ./app.js"
|
||||||
|
},
|
||||||
|
"author": "Edson da Silva",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.21.4",
|
||||||
|
"body-parser": "^1.19.0",
|
||||||
|
"dotenv": "^16.0.0",
|
||||||
|
"express": "^4.17.1",
|
||||||
|
"form-data": "^4.0.0",
|
||||||
|
"fs-extra": "^11.1.0",
|
||||||
|
"logger": "^0.0.1",
|
||||||
|
"mime": "^2.4.5",
|
||||||
|
"mongodb": "^4.1.1",
|
||||||
|
"mongoose": "^7.4.3",
|
||||||
|
"multer": "^1.4.4",
|
||||||
|
"mysql": "^2.18.1",
|
||||||
|
"node-os-utils": "^1.3.5",
|
||||||
|
"qr-encode": "^0.3.0",
|
||||||
|
"qrcode-terminal": "^0.12.0",
|
||||||
|
"socket.io": "^4.5.4",
|
||||||
|
"socket.io-client": "^4.5.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"nodemon": "^2.0.20"
|
||||||
|
}
|
||||||
|
}
|
|
@ -183,11 +183,17 @@ socketIo.on('connect_error', async function (err) {
|
||||||
})
|
})
|
||||||
//
|
//
|
||||||
|
|
||||||
|
const wwebVersion = '2.2402.5';
|
||||||
|
|
||||||
|
|
||||||
//NOVA OPÇÃO MD
|
//NOVA OPÇÃO MD
|
||||||
client = new Client({
|
client = new Client({
|
||||||
authStrategy: new LocalAuth({ clientId: 'omnihit_sesssion' }),
|
authStrategy: new LocalAuth({ clientId: 'omnihit_sesssion' }),
|
||||||
puppeteer: { args: ['--no-sandbox', '--disable-setuid-sandbox'], executablePath: process.env.CHROME_BIN || '/usr/bin/google-chrome-stable' },
|
puppeteer: { args: ['--no-sandbox', '--disable-setuid-sandbox'], executablePath: process.env.CHROME_BIN || '/usr/bin/google-chrome-stable' },
|
||||||
|
webVersionCache: {
|
||||||
|
type: 'remote',
|
||||||
|
remotePath: `https://raw.githubusercontent.com/wppconnect-team/wa-version/main/html/${wwebVersion}.html`,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
client.initialize()
|
client.initialize()
|
||||||
|
@ -879,11 +885,15 @@ async function handleMessage(msg) {
|
||||||
|
|
||||||
if (msg.fromMe) {
|
if (msg.fromMe) {
|
||||||
|
|
||||||
|
console.log('MSG FROM ME')
|
||||||
|
|
||||||
msgContact = await client.getContactById(msg.to)
|
msgContact = await client.getContactById(msg.to)
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
console.log('MSG FROM CLIENT')
|
||||||
|
|
||||||
console.log('################# RECEIVING MESSAGE FROM: ', msg.from, ' to ', msg.to)
|
console.log('################# RECEIVING MESSAGE FROM: ', msg.from, ' to ', msg.to)
|
||||||
|
|
||||||
msgContact = await msg.getContact()
|
msgContact = await msg.getContact()
|
||||||
|
@ -906,10 +916,10 @@ async function handleMessage(msg) {
|
||||||
msgContact: msgContact,
|
msgContact: msgContact,
|
||||||
chat: chat,
|
chat: chat,
|
||||||
quotedMsg: quotedMsg ? quotedMsg.id.id : null,
|
quotedMsg: quotedMsg ? quotedMsg.id.id : null,
|
||||||
media: media
|
media: media,
|
||||||
|
getContactById: msg.fromMe ? await client.getContactById(msg.to) : await client.getContactById(msg.from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
socketIo.emit("message_create", data)
|
socketIo.emit("message_create", data)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
NODE_ENV=
|
||||||
|
BACKEND_URL=http://localhost
|
||||||
|
FRONTEND_URL=http://localhost:3000
|
||||||
|
PROXY_PORT=8080
|
||||||
|
PORT=8080
|
||||||
|
|
||||||
|
DB_DIALECT=mysql
|
||||||
|
DB_HOST=localhost
|
||||||
|
DB_USER=whaticket
|
||||||
|
DB_PASS=strongpassword
|
||||||
|
DB_NAME=whaticket
|
||||||
|
|
||||||
|
# WHATSAPP OFFICIAL
|
||||||
|
VERIFY_TOKEN=HAPPY
|
||||||
|
TOKEN=EAAEPZBB2YqgwBOZBEAvPxYaO2nbPvuzU3ZBaZA6YF6tyWtjKom2yLxPxOm421njhbb1ZC2rOkyQyZCWpZBk9jXZCAaMLNY6SkNOrwPoRNaqO9Fbj31mZC8mxra08jIhBiziX7IZBFDWYbkcfw5cfLdTSys9ilfRlKsIZClOUlTiHnhSDkMvXY6rMFrvWswR2YVvJVH1qPvM7hGuuUqM
|
||||||
|
VERSION=v17.0
|
||||||
|
URL_WHATSAPP_MEDIA=https://ccsm-api.omnihit.app.br/whatsapp/official/media
|
||||||
|
URL_WHATSAPP_API=https://graph.facebook.com
|
||||||
|
|
||||||
|
JWT_SECRET=3123123213123
|
||||||
|
JWT_REFRESH_SECRET=75756756756
|
||||||
|
|
||||||
|
SENTRY_DSN=
|
||||||
|
|
||||||
|
CACHE=
|
||||||
|
|
||||||
|
WHATS_NUMBER_VALIDATOR_URL=http://localhost:8021
|
||||||
|
|
||||||
|
TOKEN_REMOTE_TICKET_CREATION=emvd7UfskjstMC99mFqs2tEiNmn05PgsUVK06TZP9LfkyjxDrsKCxlVV5ApYM7hP
|
||||||
|
TOKEN_IAM_HORACIUS_EL=emvd7UfskjstMC99mFqs2tEiNmn05PgsUVK06TZP9LfkyjxDrsKCxlVV5ApYM7hP
|
||||||
|
|
||||||
|
# omnihit da hit test bot
|
||||||
|
# APP_NAME=recrutamento_el
|
||||||
|
APP_NAME=test
|
||||||
|
|
||||||
|
BACKEND_URL_RAW=http://localhost
|
||||||
|
|
||||||
|
PUBLICKEY=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwOvEh4Qc0yeJidiX3YpDdOB/XuDeyNRaypmSyW5FjjIxBFaMiUmNSZ2X2m2LqyyrHJxQgRqwjifHUQ+ivmNBm4YFNSr05iFB/kgi/1Jmbst6h1MnmuD1YFSRnEsmdUXzhhgcj5btyjRfw6L2rGwOnqzMzS54seE1aAy+rtN82DW8wfbYU/IO83MAJiocthCBOev5MDUq6hdkGPPZ/kdFOLcQe+wt/suhmF4KRfq77X4GgLM5nAOMj7N7cJ6b97nB47krfPOMJissNzPDZ879BKeQX4t8TwJGUFNOvLd3UW3xVBTBz8pSS36VlCXjbYm44za8eTuBLDYYbGkUNEFYxwIDAQAB
|
||||||
|
|
||||||
|
REDIS_URI=redis://127.0.0.1:6379
|
||||||
|
|
||||||
|
URL_DASHBOARD_SESSIONS=http://localhost:6002
|
||||||
|
TOKEN_DASHBOARD_SESSIONS=8168dd72adb7bab7e8f54f9d022468ab
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
"watch": "tsc -w",
|
"watch": "tsc -w",
|
||||||
"start": "nodemon --expose-gc dist/server.js",
|
"start": "nodemon --expose-gc dist/server.js",
|
||||||
"dev:server": "ts-node-dev --respawn --transpile-only --ignore node_modules src/server.ts",
|
"dev:server": "ts-node-dev --respawn --transpile-only --ignore node_modules src/server.ts",
|
||||||
|
"dev": "nodemon --exec npm run dev:server",
|
||||||
"pretest": "NODE_ENV=test sequelize db:migrate && NODE_ENV=test sequelize db:seed:all",
|
"pretest": "NODE_ENV=test sequelize db:migrate && NODE_ENV=test sequelize db:seed:all",
|
||||||
"test": "NODE_ENV=test jest",
|
"test": "NODE_ENV=test jest",
|
||||||
"posttest": "NODE_ENV=test sequelize db:migrate:undo:all"
|
"posttest": "NODE_ENV=test sequelize db:migrate:undo:all"
|
||||||
|
|
|
@ -20,11 +20,13 @@ import {
|
||||||
} from "../helpers/ContactsCache";
|
} from "../helpers/ContactsCache";
|
||||||
|
|
||||||
import { off } from "process";
|
import { off } from "process";
|
||||||
import GetContactService from "../services/ContactServices/GetContactService"
|
import GetContactService from "../services/ContactServices/GetContactService";
|
||||||
|
import ContactQueue from "../models/ContactQueues";
|
||||||
|
|
||||||
type IndexQuery = {
|
type IndexQuery = {
|
||||||
searchParam: string;
|
searchParam: string;
|
||||||
pageNumber: string;
|
pageNumber: string;
|
||||||
|
userId?:string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type IndexGetContactQuery = {
|
type IndexGetContactQuery = {
|
||||||
|
@ -41,10 +43,11 @@ interface ContactData {
|
||||||
number: string;
|
number: string;
|
||||||
email?: string;
|
email?: string;
|
||||||
extraInfo?: ExtraInfo[];
|
extraInfo?: ExtraInfo[];
|
||||||
|
queueIds?: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const index = async (req: Request, res: Response): Promise<Response> => {
|
export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
let { searchParam, pageNumber } = req.query as IndexQuery;
|
let { searchParam, pageNumber, userId } = req.query as IndexQuery;
|
||||||
|
|
||||||
console.log("PAGE NUMBER CONTACT: ", pageNumber);
|
console.log("PAGE NUMBER CONTACT: ", pageNumber);
|
||||||
|
|
||||||
|
@ -80,11 +83,10 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("QUERY CONTACTS FROM DATABASE SEARCH PARAM: ", searchParam);
|
|
||||||
|
|
||||||
const { contacts, count, hasMore } = await ListContactsService({
|
const { contacts, count, hasMore } = await ListContactsService({
|
||||||
searchParam,
|
searchParam,
|
||||||
pageNumber
|
pageNumber,
|
||||||
|
userId
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.json({ contacts, count, hasMore });
|
return res.json({ contacts, count, hasMore });
|
||||||
|
@ -142,7 +144,8 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
number,
|
number,
|
||||||
email,
|
email,
|
||||||
profilePicUrl: profilePicUrl,
|
profilePicUrl: profilePicUrl,
|
||||||
extraInfo
|
extraInfo,
|
||||||
|
queueIds: newContact?.queueIds
|
||||||
});
|
});
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
|
@ -208,6 +211,8 @@ export const remove = async (
|
||||||
|
|
||||||
await DeleteContactService(contactId);
|
await DeleteContactService(contactId);
|
||||||
|
|
||||||
|
await ContactQueue.destroy({ where: { contactId } });
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
io.emit("contact", {
|
io.emit("contact", {
|
||||||
action: "delete",
|
action: "delete",
|
||||||
|
|
|
@ -0,0 +1,492 @@
|
||||||
|
import { Request, Response } from "express";
|
||||||
|
import { getIO } from "../libs/socket";
|
||||||
|
import { Op } from "sequelize";
|
||||||
|
import CreateUserService from "../services/UserServices/CreateUserService";
|
||||||
|
import UpdateUserService from "../services/UserServices/UpdateUserService";
|
||||||
|
import DeleteUserService from "../services/UserServices/DeleteUserService";
|
||||||
|
import { del, get, set } from "../helpers/RedisClient";
|
||||||
|
|
||||||
|
import {
|
||||||
|
startWhoIsOnlineMonitor,
|
||||||
|
stopWhoIsOnlineMonitor
|
||||||
|
} from "../helpers/WhoIsOnlineMonitor";
|
||||||
|
|
||||||
|
import User from "../models/User";
|
||||||
|
|
||||||
|
export const createUser = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
const { user_id, user_first_name, user_tax_id, user_email, user_title }: any =
|
||||||
|
req.body;
|
||||||
|
|
||||||
|
const invalid = invalidProperties(req.body, [
|
||||||
|
"user_id",
|
||||||
|
"user_tax_id",
|
||||||
|
"user_first_name"
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (invalid) {
|
||||||
|
return res.status(400).json(response("1", `${invalid}`, "0", "createUser"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const auxUser = await User.findOne({ where: { secondaryId: user_id } });
|
||||||
|
|
||||||
|
if (auxUser) {
|
||||||
|
return res
|
||||||
|
.status(400)
|
||||||
|
.json(
|
||||||
|
response("1", `The user ${user_id} already exist`, "0", "createUser")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await CreateUserService({
|
||||||
|
email: user_tax_id || user_email,
|
||||||
|
password: "12345",
|
||||||
|
name: user_first_name,
|
||||||
|
profile: "user",
|
||||||
|
ignoreThrow: true
|
||||||
|
});
|
||||||
|
|
||||||
|
if (user?.error) {
|
||||||
|
return res
|
||||||
|
.status(user?.status)
|
||||||
|
.json(response("0", `${user?.msg}`, "0", "createUser"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user?.error) {
|
||||||
|
const _user = await User.findByPk(user.id);
|
||||||
|
_user?.update({ secondaryId: user_id });
|
||||||
|
|
||||||
|
const { id, name } = user;
|
||||||
|
await set(`user:${id}`, { id, name });
|
||||||
|
|
||||||
|
const io = getIO();
|
||||||
|
io.emit("user", {
|
||||||
|
action: "create",
|
||||||
|
user
|
||||||
|
});
|
||||||
|
|
||||||
|
await startWhoIsOnlineMonitor();
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
.status(200)
|
||||||
|
.json(response("1", `User ${user_id} created`, "1", "createUser"));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteUser = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
const { user_id }: any = req.body;
|
||||||
|
|
||||||
|
const invalid = invalidProperties(req.body, ["user_id"]);
|
||||||
|
|
||||||
|
if (invalid) {
|
||||||
|
return res.status(400).json(response("1", `${invalid}`, "0", "deleteUser"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const _user = await User.findOne({ where: { secondaryId: user_id } });
|
||||||
|
|
||||||
|
if (_user) {
|
||||||
|
const user = await DeleteUserService(_user.id, true);
|
||||||
|
|
||||||
|
if (user?.error) {
|
||||||
|
return res
|
||||||
|
.status(user?.status)
|
||||||
|
.json(response("0", `${user?.msg}`, "0", "deleteUser"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user?.error) {
|
||||||
|
del(`user:${_user.id}`);
|
||||||
|
|
||||||
|
const io = getIO();
|
||||||
|
io.emit("user", {
|
||||||
|
action: "delete",
|
||||||
|
userId: _user.id
|
||||||
|
});
|
||||||
|
|
||||||
|
await stopWhoIsOnlineMonitor();
|
||||||
|
|
||||||
|
io.emit("onlineStatus", {
|
||||||
|
action: "delete",
|
||||||
|
userOnlineTime: _user.id
|
||||||
|
});
|
||||||
|
|
||||||
|
await startWhoIsOnlineMonitor();
|
||||||
|
|
||||||
|
return res
|
||||||
|
.status(200)
|
||||||
|
.json(response("1", `User ${user_id} deleted`, "1", "deleteUser"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
.status(500)
|
||||||
|
.json(response("0", "Internal server error", "0", "deleteUser"));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const listAllUsers = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
const _users: any = await User.findAll({
|
||||||
|
where: {
|
||||||
|
secondaryId: {
|
||||||
|
[Op.ne]: ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
attributes: ["secondaryId", "name"]
|
||||||
|
});
|
||||||
|
|
||||||
|
if (_users) {
|
||||||
|
const user_list = _users.map((user: any) => {
|
||||||
|
const { secondaryId, name } = user;
|
||||||
|
return { user_id: secondaryId, full_name: name };
|
||||||
|
});
|
||||||
|
|
||||||
|
return res
|
||||||
|
.status(200)
|
||||||
|
.json(response("1", "Success", user_list, "listAllUsers"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
.status(500)
|
||||||
|
.json(response("0", "Internal server error", [], "listAllUsers"));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const checkUser = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
const { user_id }: any = req.body;
|
||||||
|
|
||||||
|
const invalid = invalidProperties(req.body, ["user_id"]);
|
||||||
|
|
||||||
|
if (invalid) {
|
||||||
|
return res.status(400).json(response("1", `${invalid}`, "0", "checkUser"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const _user = await User.findOne({ where: { secondaryId: user_id } });
|
||||||
|
|
||||||
|
if (_user) {
|
||||||
|
return res
|
||||||
|
.status(200)
|
||||||
|
.json(response("1", `User ${user_id} exist`, "1", "checkUser"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
.status(404)
|
||||||
|
.json(response("1", `User ${user_id} not exist`, "0", "checkUser"));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateUser = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
const { user_id, user_first_name, user_tax_id, user_email, user_title }: any =
|
||||||
|
req.body;
|
||||||
|
|
||||||
|
const invalid = invalidProperties(req.body, ["user_id"]);
|
||||||
|
|
||||||
|
if (invalid) {
|
||||||
|
return res.status(400).json(response("1", `${invalid}`, "0", "checkUser"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const _user: any = await User.findOne({ where: { secondaryId: user_id } });
|
||||||
|
|
||||||
|
if (!_user)
|
||||||
|
return res
|
||||||
|
.status(404)
|
||||||
|
.json(response("1", `User ${user_id} not exist`, "0", "updateUser"));
|
||||||
|
|
||||||
|
const userData = {
|
||||||
|
email: user_tax_id || user_email,
|
||||||
|
name: user_first_name,
|
||||||
|
};
|
||||||
|
|
||||||
|
let user: any = await UpdateUserService({
|
||||||
|
userData,
|
||||||
|
userId: _user.id,
|
||||||
|
ignoreThrow: true
|
||||||
|
});
|
||||||
|
|
||||||
|
if (user?.error) {
|
||||||
|
return res
|
||||||
|
.status(user?.status)
|
||||||
|
.json(response("0", `${user?.msg}`, "0", "updateUser"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
const { id, name } = user;
|
||||||
|
await set(`user:${id}`, { id, name });
|
||||||
|
}
|
||||||
|
|
||||||
|
const io = getIO();
|
||||||
|
io.emit("user", {
|
||||||
|
action: "update",
|
||||||
|
user
|
||||||
|
});
|
||||||
|
|
||||||
|
return res
|
||||||
|
.status(200)
|
||||||
|
.json(response("1", `User ${user_id} updated`, "1", "updateUser"));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const resetPassword = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
const { user_id, user_password }: any = req.body;
|
||||||
|
|
||||||
|
const invalid = invalidProperties(req.body, ["user_id", "user_password"]);
|
||||||
|
|
||||||
|
if (invalid) {
|
||||||
|
return res
|
||||||
|
.status(400)
|
||||||
|
.json(response("1", `${invalid}`, "0", "resetPassword"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const _user = await User.findOne({ where: { secondaryId: user_id } });
|
||||||
|
|
||||||
|
if (!_user) {
|
||||||
|
return res
|
||||||
|
.status(404)
|
||||||
|
.json(response("1", `User ${user_id} not exist`, "0", "resetPassword"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const userData = {
|
||||||
|
password: user_password,
|
||||||
|
email: _user.email
|
||||||
|
};
|
||||||
|
|
||||||
|
let user: any = await UpdateUserService({
|
||||||
|
userData,
|
||||||
|
userId: _user.id,
|
||||||
|
ignoreThrow: true
|
||||||
|
});
|
||||||
|
|
||||||
|
if (user?.error) {
|
||||||
|
return res
|
||||||
|
.status(user?.status)
|
||||||
|
.json(response("0", `${user?.msg}`, "0", "resetPassword"));
|
||||||
|
}
|
||||||
|
|
||||||
|
await logoutUser(_user.id);
|
||||||
|
|
||||||
|
return res
|
||||||
|
.status(200)
|
||||||
|
.json(
|
||||||
|
response("1", `User ${user_id} password updated`, "1", "resetPassword")
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const linkUserAndUserRight = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
const { user_id, user_right_id, user_right_title }: any = req.body;
|
||||||
|
|
||||||
|
const invalid = invalidProperties(req.body, ["user_id", "user_right_id"]);
|
||||||
|
|
||||||
|
if (invalid) {
|
||||||
|
return res
|
||||||
|
.status(400)
|
||||||
|
.json(response("1", `${invalid}`, "0", "linkUserAndUserRight"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
(user_right_id &&
|
||||||
|
!["admin", "user", "supervisor"].includes(
|
||||||
|
user_right_id?.trim().toLocaleLowerCase()
|
||||||
|
)) ||
|
||||||
|
(user_right_title &&
|
||||||
|
!["admin", "user", "supervisor"].includes(
|
||||||
|
user_right_title?.trim().toLocaleLowerCase()
|
||||||
|
))
|
||||||
|
) {
|
||||||
|
return res
|
||||||
|
.status(400)
|
||||||
|
.json(
|
||||||
|
response(
|
||||||
|
"1",
|
||||||
|
`The user profile ${
|
||||||
|
user_right_title || user_right_id
|
||||||
|
} provided by the property user_right_title or user_right_id does not match the following profiles: admin, user, supervisor`,
|
||||||
|
"0",
|
||||||
|
"linkUserAndUserRight"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const _user: any = await User.findOne({ where: { secondaryId: user_id } });
|
||||||
|
|
||||||
|
if (!_user)
|
||||||
|
return res
|
||||||
|
.status(404)
|
||||||
|
.json(
|
||||||
|
response("1", `User ${user_id} not exist`, "0", "linkUserAndUserRight")
|
||||||
|
);
|
||||||
|
|
||||||
|
const userData = {
|
||||||
|
profile: user_right_title || user_right_id,
|
||||||
|
email: _user.email
|
||||||
|
};
|
||||||
|
|
||||||
|
let user: any = await UpdateUserService({
|
||||||
|
userData,
|
||||||
|
userId: _user.id,
|
||||||
|
ignoreThrow: true
|
||||||
|
});
|
||||||
|
|
||||||
|
if (user?.error) {
|
||||||
|
return res
|
||||||
|
.status(user?.status)
|
||||||
|
.json(response("0", `${user?.msg}`, "0", "linkUserAndUserRight"));
|
||||||
|
}
|
||||||
|
|
||||||
|
await logoutUser(_user.id);
|
||||||
|
|
||||||
|
return res
|
||||||
|
.status(200)
|
||||||
|
.json(
|
||||||
|
response(
|
||||||
|
"1",
|
||||||
|
`User ${user_id} associated with ${
|
||||||
|
user_right_title || user_right_id
|
||||||
|
} profile`,
|
||||||
|
"1",
|
||||||
|
"linkUserAndUserRight"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const checkUserRight = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
const { user_id, user_right_id, user_right_title }: any = req.body;
|
||||||
|
|
||||||
|
const invalid = invalidProperties(req.body, ["user_id", "user_right_id"]);
|
||||||
|
|
||||||
|
if (invalid) {
|
||||||
|
return res
|
||||||
|
.status(400)
|
||||||
|
.json(response("1", `${invalid}`, "0", "checkUserRight"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
(user_right_id &&
|
||||||
|
!["admin", "user", "supervisor"].includes(
|
||||||
|
user_right_id?.trim().toLocaleLowerCase()
|
||||||
|
)) ||
|
||||||
|
(user_right_title &&
|
||||||
|
!["admin", "user", "supervisor"].includes(
|
||||||
|
user_right_title?.trim().toLocaleLowerCase()
|
||||||
|
))
|
||||||
|
) {
|
||||||
|
return res
|
||||||
|
.status(400)
|
||||||
|
.json(
|
||||||
|
response(
|
||||||
|
"1",
|
||||||
|
`The user profile ${
|
||||||
|
user_right_title || user_right_id
|
||||||
|
} provided by the property user_right_title or user_right_id does not match the following profiles: admin, user, supervisor`,
|
||||||
|
"0",
|
||||||
|
"checkUserRight"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const _user: any = await User.findOne({
|
||||||
|
where: {
|
||||||
|
secondaryId: user_id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!_user)
|
||||||
|
return res
|
||||||
|
.status(404)
|
||||||
|
.json(response("1", `User ${user_id} not exist`, "0", "checkUserRight"));
|
||||||
|
|
||||||
|
if (
|
||||||
|
(user_right_id && _user.profile != user_right_id) ||
|
||||||
|
(user_right_title && _user.profile != user_right_title)
|
||||||
|
) {
|
||||||
|
return res
|
||||||
|
.status(403)
|
||||||
|
.json(
|
||||||
|
response(
|
||||||
|
"1",
|
||||||
|
`User ${user_id} does not have this profile`,
|
||||||
|
"0",
|
||||||
|
"checkUserRight"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
.status(200)
|
||||||
|
.json(
|
||||||
|
response(
|
||||||
|
"1",
|
||||||
|
`User ${user_id} has ${user_right_title || user_right_id} profile`,
|
||||||
|
"1",
|
||||||
|
"checkUserRight"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
async function logoutUser(userId: any) {
|
||||||
|
await stopWhoIsOnlineMonitor();
|
||||||
|
|
||||||
|
let onlineTime = {
|
||||||
|
userId: `${userId}`,
|
||||||
|
status: "logout..."
|
||||||
|
};
|
||||||
|
|
||||||
|
const io = getIO();
|
||||||
|
io.emit("onlineStatus", {
|
||||||
|
action: "logout",
|
||||||
|
userOnlineTime: onlineTime
|
||||||
|
});
|
||||||
|
|
||||||
|
await startWhoIsOnlineMonitor();
|
||||||
|
}
|
||||||
|
|
||||||
|
function response(code: string, msg: string, obj: any, type: string) {
|
||||||
|
let payload = { return_code: code, return_msg: msg };
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case "createUser":
|
||||||
|
return { ...payload, user_created: obj };
|
||||||
|
case "deleteUser":
|
||||||
|
return { ...payload, user_removed: obj };
|
||||||
|
case "listAllUsers":
|
||||||
|
return { ...payload, user_list: obj };
|
||||||
|
case "checkUser":
|
||||||
|
return { ...payload, user_exists: obj };
|
||||||
|
case "updateUser":
|
||||||
|
return { ...payload, user_updated: obj };
|
||||||
|
case "resetPassword":
|
||||||
|
return { ...payload, password_set: obj };
|
||||||
|
case "linkUserAndUserRight":
|
||||||
|
return { ...payload, user_right_linked: obj };
|
||||||
|
case "checkUserRight":
|
||||||
|
return { ...payload, user_right_exists: obj };
|
||||||
|
default:
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function invalidProperties(body: any, pros: any[]) {
|
||||||
|
for (const field of pros) {
|
||||||
|
console.log("body[field]: ", body[field], " field: ", field);
|
||||||
|
if (!body[field]) {
|
||||||
|
return `${field} is required`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
import { Request, Response } from "express";
|
import { Request, Response } from "express";
|
||||||
import whatsappOfficialAPI from "../helpers/WhatsappOfficialAPI";
|
|
||||||
|
|
||||||
import SetTicketMessagesAsRead from "../helpers/SetTicketMessagesAsRead";
|
import SetTicketMessagesAsRead from "../helpers/SetTicketMessagesAsRead";
|
||||||
import { getIO } from "../libs/socket";
|
import { getIO } from "../libs/socket";
|
||||||
|
@ -21,6 +20,8 @@ import sendWhatsAppMessageOfficialAPI from "../helpers/sendWhatsAppMessageOffici
|
||||||
import Whatsapp from "../models/Whatsapp";
|
import Whatsapp from "../models/Whatsapp";
|
||||||
import checkLastClientMsg24hs from "../helpers/CheckLastClientMsg24hs";
|
import checkLastClientMsg24hs from "../helpers/CheckLastClientMsg24hs";
|
||||||
import AppError from "../errors/AppError";
|
import AppError from "../errors/AppError";
|
||||||
|
import { get } from "../helpers/RedisClient";
|
||||||
|
import createApiClientWhatsOfficial from "../helpers/WhatsappOfficialAPI";
|
||||||
|
|
||||||
type IndexQuery = {
|
type IndexQuery = {
|
||||||
pageNumber: string;
|
pageNumber: string;
|
||||||
|
@ -97,7 +98,8 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const name = params.find((p: any) => p?.template_name);
|
const name = params.find((p: any) => p?.template_name);
|
||||||
const { language }: any = params?.find((p: any) => p?.language) || 'pt_BR'
|
const { language }: any =
|
||||||
|
params?.find((p: any) => p?.language) || "pt_BR";
|
||||||
|
|
||||||
const { template_name } = name;
|
const { template_name } = name;
|
||||||
|
|
||||||
|
@ -121,7 +123,12 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
const { wabaId }: any = await Whatsapp.findByPk(whatsappId);
|
const { wabaId, whatsappOfficialToken }: any =
|
||||||
|
await Whatsapp.findByPk(whatsappId);
|
||||||
|
|
||||||
|
const whatsappOfficialAPI = createApiClientWhatsOfficial(
|
||||||
|
whatsappOfficialToken
|
||||||
|
);
|
||||||
|
|
||||||
const { data } = await whatsappOfficialAPI.get(
|
const { data } = await whatsappOfficialAPI.get(
|
||||||
`/${process.env.VERSION}/${wabaId}/message_templates?language=pt_BR`
|
`/${process.env.VERSION}/${wabaId}/message_templates?language=pt_BR`
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
import * as Yup from "yup";
|
||||||
|
import { Request, Response } from "express";
|
||||||
|
import { getIO } from "../libs/socket";
|
||||||
|
|
||||||
|
import AppError from "../errors/AppError";
|
||||||
|
import ListPositionService from "../services/PositionService/ListPositionService";
|
||||||
|
import ShowPositionService from "../services/PositionService/ShowPositionService";
|
||||||
|
import CreatePositionService from "../services/PositionService/CreatePositionService";
|
||||||
|
import UpdatePositionService from "../services/PositionService/UpdatePositionService";
|
||||||
|
import DeletePositionService from "../services/PositionService/DeletePositionService";
|
||||||
|
|
||||||
|
type IndexQuery = {
|
||||||
|
searchParam: string;
|
||||||
|
pageNumber: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface PositionData {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
const { searchParam, pageNumber } = req.query as IndexQuery;
|
||||||
|
|
||||||
|
const { positions, count, hasMore } = await ListPositionService({
|
||||||
|
searchParam,
|
||||||
|
pageNumber
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.json({ positions, count, hasMore });
|
||||||
|
};
|
||||||
|
|
||||||
|
export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
const newPosition: PositionData = req.body;
|
||||||
|
|
||||||
|
const PositionSchema = Yup.object().shape({
|
||||||
|
name: Yup.string().required()
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await PositionSchema.validate(newPosition);
|
||||||
|
} catch (err: any) {
|
||||||
|
throw new AppError(err.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
const position = await CreatePositionService({
|
||||||
|
...newPosition
|
||||||
|
});
|
||||||
|
|
||||||
|
const io = getIO();
|
||||||
|
io.emit("position", {
|
||||||
|
action: "create",
|
||||||
|
position
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(200).json(position);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const show = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
const { positionId } = req.params;
|
||||||
|
|
||||||
|
const position = await ShowPositionService(positionId);
|
||||||
|
|
||||||
|
return res.status(200).json(position);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const update = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
const positionData: PositionData = req.body;
|
||||||
|
|
||||||
|
const schema = Yup.object().shape({
|
||||||
|
name: Yup.string().required()
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await schema.validate(positionData);
|
||||||
|
} catch (err: any) {
|
||||||
|
throw new AppError(err.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { positionId } = req.params;
|
||||||
|
|
||||||
|
const position = await UpdatePositionService({
|
||||||
|
positionData,
|
||||||
|
positionId
|
||||||
|
});
|
||||||
|
|
||||||
|
const io = getIO();
|
||||||
|
io.emit("position", {
|
||||||
|
action: "update",
|
||||||
|
position
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(200).json(position);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const remove = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
const { positionId } = req.params;
|
||||||
|
|
||||||
|
await DeletePositionService(positionId);
|
||||||
|
|
||||||
|
const io = getIO();
|
||||||
|
io.emit("position", {
|
||||||
|
action: "delete",
|
||||||
|
positionId
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(200).json({ message: "Position deleted" });
|
||||||
|
};
|
|
@ -5,11 +5,14 @@ import DeleteQueueService from "../services/QueueService/DeleteQueueService";
|
||||||
import ListQueuesService from "../services/QueueService/ListQueuesService";
|
import ListQueuesService from "../services/QueueService/ListQueuesService";
|
||||||
import ShowQueueService from "../services/QueueService/ShowQueueService";
|
import ShowQueueService from "../services/QueueService/ShowQueueService";
|
||||||
import UpdateQueueService from "../services/QueueService/UpdateQueueService";
|
import UpdateQueueService from "../services/QueueService/UpdateQueueService";
|
||||||
import Queue from "../models/Queue"
|
import Queue from "../models/Queue";
|
||||||
import AppError from "../errors/AppError"
|
import AppError from "../errors/AppError";
|
||||||
import { get, set } from "../helpers/RedisClient";
|
import { del, get, set } from "../helpers/RedisClient";
|
||||||
|
import { Op } from "sequelize";
|
||||||
|
import ListWhatsAppsService from "../services/WhatsappService/ListWhatsAppsService";
|
||||||
|
import Whatsapp from "../models/Whatsapp";
|
||||||
|
import QuickAnswerQueue from "../models/QuickAnswerQueue";
|
||||||
|
import ContactQueue from "../models/ContactQueues";
|
||||||
|
|
||||||
export const index = async (req: Request, res: Response): Promise<Response> => {
|
export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
const queues = await ListQueuesService();
|
const queues = await ListQueuesService();
|
||||||
|
@ -17,10 +20,68 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
return res.status(200).json(queues);
|
return res.status(200).json(queues);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const store = async (req: Request, res: Response): Promise<Response> => {
|
export const listQueues = async (
|
||||||
const { name, color, greetingMessage } = req.body;
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
const whatsapps = await Whatsapp.findAll({
|
||||||
|
where: {
|
||||||
|
name: { [Op.ne]: "botqueue" },
|
||||||
|
number: { [Op.ne]: "" },
|
||||||
|
phoneNumberId: false
|
||||||
|
},
|
||||||
|
attributes: ["number"],
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: Queue,
|
||||||
|
as: "queues",
|
||||||
|
attributes: ["id", "name"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
const queue = await CreateQueueService({ name, color, greetingMessage });
|
const whats = whatsapps
|
||||||
|
?.filter((w: any) => w?.queues?.length > 0)
|
||||||
|
?.map((w: any) => {
|
||||||
|
const { number, queues } = w;
|
||||||
|
return {
|
||||||
|
number,
|
||||||
|
queues: queues?.map((q: any) => {
|
||||||
|
const { id, name } = q;
|
||||||
|
return { id, name };
|
||||||
|
})
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
let _queues: any = [];
|
||||||
|
|
||||||
|
for (const w of whats) {
|
||||||
|
const { queues } = w;
|
||||||
|
|
||||||
|
for (const q of queues) {
|
||||||
|
const { id: queueId, name } = q;
|
||||||
|
|
||||||
|
const auxQueue = _queues.findIndex((q: any) => q.queueId == queueId);
|
||||||
|
|
||||||
|
if (auxQueue == -1) {
|
||||||
|
_queues.push({ queueId, name });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).json(_queues);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
const { name, color, greetingMessage, farewellMessage, cc } = req.body;
|
||||||
|
|
||||||
|
const queue = await CreateQueueService({
|
||||||
|
name,
|
||||||
|
color,
|
||||||
|
greetingMessage,
|
||||||
|
cc,
|
||||||
|
farewellMessage
|
||||||
|
});
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
io.emit("queue", {
|
io.emit("queue", {
|
||||||
|
@ -62,43 +123,43 @@ export const customization = async (
|
||||||
if (new_queues && new_queues.length > 0) {
|
if (new_queues && new_queues.length > 0) {
|
||||||
const db_queues: any = await Queue.findAll();
|
const db_queues: any = await Queue.findAll();
|
||||||
|
|
||||||
for (const i in new_queues) {
|
// for (const i in new_queues) {
|
||||||
let { queueName: name, color, greetingMessage } = new_queues[i];
|
// let { queueName: name, color, greetingMessage } = new_queues[i];
|
||||||
|
|
||||||
name = name?.trim()?.replace(/\s+/g, " ");
|
// name = name?.trim()?.replace(/\s+/g, " ");
|
||||||
|
|
||||||
const update = db_queues.find(
|
// const update = db_queues.find(
|
||||||
(q: any) => q.name?.trim()?.replace(/\s+/g, " ") == name
|
// (q: any) => q.name?.trim()?.replace(/\s+/g, " ") == name
|
||||||
);
|
// );
|
||||||
|
|
||||||
if (update) {
|
// if (update) {
|
||||||
const { id } = update;
|
// const { id } = update;
|
||||||
// UPDATE
|
// // UPDATE
|
||||||
// const queue = await UpdateQueueService(id, {
|
// // const queue = await UpdateQueueService(id, {
|
||||||
// name,
|
// // name,
|
||||||
// color,
|
// // color,
|
||||||
// greetingMessage
|
// // greetingMessage
|
||||||
// });
|
// // });
|
||||||
|
|
||||||
// const io = getIO();
|
// // const io = getIO();
|
||||||
// io.emit("queue", {
|
// // io.emit("queue", {
|
||||||
// action: "update",
|
// // action: "update",
|
||||||
// queue
|
// // queue
|
||||||
// });
|
// // });
|
||||||
} else {
|
// } else {
|
||||||
// CREATE
|
// // CREATE
|
||||||
// const queue = await CreateQueueService({
|
// // const queue = await CreateQueueService({
|
||||||
// name,
|
// // name,
|
||||||
// color,
|
// // color,
|
||||||
// greetingMessage
|
// // greetingMessage
|
||||||
// });
|
// // });
|
||||||
// const io = getIO();
|
// // const io = getIO();
|
||||||
// io.emit("queue", {
|
// // io.emit("queue", {
|
||||||
// action: "update",
|
// // action: "update",
|
||||||
// queue
|
// // queue
|
||||||
// });
|
// // });
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
let remove_queues = db_queues.filter(
|
let remove_queues = db_queues.filter(
|
||||||
(q: any) =>
|
(q: any) =>
|
||||||
|
@ -125,7 +186,7 @@ export const customization = async (
|
||||||
|
|
||||||
await set("ura", ura);
|
await set("ura", ura);
|
||||||
|
|
||||||
const _ura = await get("ura");
|
const _ura = await get({ key: "ura", parse: true });
|
||||||
console.log("_URA: ", _ura);
|
console.log("_URA: ", _ura);
|
||||||
|
|
||||||
return res.status(200).json({ new_queues });
|
return res.status(200).json({ new_queues });
|
||||||
|
@ -164,6 +225,11 @@ export const remove = async (
|
||||||
|
|
||||||
await DeleteQueueService(queueId);
|
await DeleteQueueService(queueId);
|
||||||
|
|
||||||
|
await QuickAnswerQueue.destroy({ where: { queueId } });
|
||||||
|
await ContactQueue.destroy({ where: { queueId } });
|
||||||
|
|
||||||
|
await del(`queue:${queueId}`);
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
io.emit("queue", {
|
io.emit("queue", {
|
||||||
action: "delete",
|
action: "delete",
|
||||||
|
|
|
@ -9,23 +9,27 @@ import UpdateQuickAnswerService from "../services/QuickAnswerService/UpdateQuick
|
||||||
import DeleteQuickAnswerService from "../services/QuickAnswerService/DeleteQuickAnswerService";
|
import DeleteQuickAnswerService from "../services/QuickAnswerService/DeleteQuickAnswerService";
|
||||||
|
|
||||||
import AppError from "../errors/AppError";
|
import AppError from "../errors/AppError";
|
||||||
|
import QuickAnswerQueue from "../models/QuickAnswerQueue";
|
||||||
|
|
||||||
type IndexQuery = {
|
type IndexQuery = {
|
||||||
searchParam: string;
|
searchParam: string;
|
||||||
pageNumber: string;
|
pageNumber: string;
|
||||||
|
userId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface QuickAnswerData {
|
interface QuickAnswerData {
|
||||||
shortcut: string;
|
shortcut: string;
|
||||||
message: string;
|
message: string;
|
||||||
|
queueIds?: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const index = async (req: Request, res: Response): Promise<Response> => {
|
export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
const { searchParam, pageNumber } = req.query as IndexQuery;
|
const { searchParam, pageNumber, userId } = req.query as IndexQuery;
|
||||||
|
|
||||||
const { quickAnswers, count, hasMore } = await ListQuickAnswerService({
|
const { quickAnswers, count, hasMore } = await ListQuickAnswerService({
|
||||||
searchParam,
|
searchParam,
|
||||||
pageNumber
|
pageNumber,
|
||||||
|
userId
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.json({ quickAnswers, count, hasMore });
|
return res.json({ quickAnswers, count, hasMore });
|
||||||
|
@ -59,9 +63,9 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const show = async (req: Request, res: Response): Promise<Response> => {
|
export const show = async (req: Request, res: Response): Promise<Response> => {
|
||||||
const { quickAnswerId } = req.params;
|
const { quickAnswerId, userId } = req.params;
|
||||||
|
|
||||||
const quickAnswer = await ShowQuickAnswerService(quickAnswerId);
|
const quickAnswer = await ShowQuickAnswerService(quickAnswerId, userId);
|
||||||
|
|
||||||
return res.status(200).json(quickAnswer);
|
return res.status(200).json(quickAnswer);
|
||||||
};
|
};
|
||||||
|
@ -103,10 +107,12 @@ export const remove = async (
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response
|
res: Response
|
||||||
): Promise<Response> => {
|
): Promise<Response> => {
|
||||||
const { quickAnswerId } = req.params;
|
const { quickAnswerId, queueId } = req.params;
|
||||||
|
|
||||||
await DeleteQuickAnswerService(quickAnswerId);
|
await DeleteQuickAnswerService(quickAnswerId);
|
||||||
|
|
||||||
|
await QuickAnswerQueue.destroy({ where: { quickAnswerId } });
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
io.emit("quickAnswer", {
|
io.emit("quickAnswer", {
|
||||||
action: "delete",
|
action: "delete",
|
||||||
|
|
|
@ -19,6 +19,8 @@ import CountTicketsByUserQueue from "../services/UserServices/CountTicketsByUser
|
||||||
import ShowQueuesByUser from "../services/UserServices/ShowQueuesByUser";
|
import ShowQueuesByUser from "../services/UserServices/ShowQueuesByUser";
|
||||||
import { getIO } from "../libs/socket";
|
import { getIO } from "../libs/socket";
|
||||||
import { Json } from "sequelize/types/lib/utils";
|
import { Json } from "sequelize/types/lib/utils";
|
||||||
|
import ReportByNumberQueueService from "../services/ReportServices/ReportByNumberQueueService";
|
||||||
|
import CountStatusChatEndService from "../services/StatusChatEndService/CountStatusChatEndService";
|
||||||
|
|
||||||
type IndexQuery = {
|
type IndexQuery = {
|
||||||
userId: string;
|
userId: string;
|
||||||
|
@ -28,6 +30,7 @@ type IndexQuery = {
|
||||||
queueId: string;
|
queueId: string;
|
||||||
pageNumber: string;
|
pageNumber: string;
|
||||||
userQueues: [];
|
userQueues: [];
|
||||||
|
isRemote: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ReportOnQueue = {
|
type ReportOnQueue = {
|
||||||
|
@ -57,26 +60,13 @@ export const reportUserByDateStartDateEnd = async (
|
||||||
queueId
|
queueId
|
||||||
} = req.query as IndexQuery;
|
} = req.query as IndexQuery;
|
||||||
|
|
||||||
console.log(
|
|
||||||
"userId, startDate, endDate, pageNumber, userQueues, createdOrUpdated, queueId: ",
|
|
||||||
userId,
|
|
||||||
startDate,
|
|
||||||
endDate,
|
|
||||||
pageNumber,
|
|
||||||
userQueues,
|
|
||||||
createdOrUpdated,
|
|
||||||
queueId
|
|
||||||
);
|
|
||||||
|
|
||||||
// return res.status(200).json({ tickets:[], count:0, hasMore:false, queues:[] });
|
|
||||||
|
|
||||||
const { tickets, count, hasMore } = await ShowTicketReport({
|
const { tickets, count, hasMore } = await ShowTicketReport({
|
||||||
userId,
|
userId,
|
||||||
startDate,
|
startDate,
|
||||||
endDate,
|
endDate,
|
||||||
pageNumber,
|
pageNumber,
|
||||||
createdOrUpdated,
|
createdOrUpdated,
|
||||||
queueId
|
queueId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const queues = await Queue.findAll({ attributes: ["id", "name"] });
|
const queues = await Queue.findAll({ attributes: ["id", "name"] });
|
||||||
|
@ -95,11 +85,12 @@ export const reportUserService = async (
|
||||||
) {
|
) {
|
||||||
throw new AppError("ERR_NO_PERMISSION", 403);
|
throw new AppError("ERR_NO_PERMISSION", 403);
|
||||||
}
|
}
|
||||||
const { userId, startDate, endDate } = req.query as IndexQuery;
|
const { userId, startDate, endDate, userQueues} = req.query as IndexQuery;
|
||||||
|
|
||||||
// let usersProfile = await ListUserParamiterService({ profile: 'user' })
|
// let usersProfile = await ListUserParamiterService({ profile: 'user' })
|
||||||
let usersProfile = await ListUserParamiterService({
|
let usersProfile = await ListUserParamiterService({
|
||||||
profiles: ["user", "supervisor"],
|
profiles: ["user", "supervisor"],
|
||||||
|
userQueues: userQueues ? userQueues : undefined,
|
||||||
raw: true
|
raw: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -274,8 +265,6 @@ export const reportMessagesUserByDateStartDateEnd = async (
|
||||||
}
|
}
|
||||||
|
|
||||||
data_query_messages[i].id = i + 1;
|
data_query_messages[i].id = i + 1;
|
||||||
|
|
||||||
console.log("data_query_messages: ", data_query_messages[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.status(200).json(data_query_messages);
|
return res.status(200).json(data_query_messages);
|
||||||
|
@ -302,3 +291,86 @@ export const reportOnQueue = async (
|
||||||
|
|
||||||
return res.status(200).json({ message: "ok" });
|
return res.status(200).json({ message: "ok" });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const reportService = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
if (
|
||||||
|
req.user.profile !== "master" &&
|
||||||
|
req.user.profile !== "admin" &&
|
||||||
|
req.user.profile !== "supervisor"
|
||||||
|
) {
|
||||||
|
throw new AppError("ERR_NO_PERMISSION", 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { startDate, endDate, queueId, isRemote } = req.query as IndexQuery;
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`startDate: ${startDate} | endDate: ${endDate} | queueId: ${queueId}`
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("IS REMOTE: ", isRemote);
|
||||||
|
console.log("isRemote: ", isRemote && isRemote == "true" ? true : false);
|
||||||
|
|
||||||
|
const reportService = await ReportByNumberQueueService({
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
isRemote: isRemote && isRemote == "true" ? true : false
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(200).json({ reportService });
|
||||||
|
};
|
||||||
|
|
||||||
|
export const reportServiceByQueue = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
if (
|
||||||
|
req.user.profile !== "master" &&
|
||||||
|
req.user.profile !== "admin" &&
|
||||||
|
req.user.profile !== "supervisor"
|
||||||
|
) {
|
||||||
|
throw new AppError("ERR_NO_PERMISSION", 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { startDate, endDate, queueId, isRemote } = req.query as IndexQuery;
|
||||||
|
|
||||||
|
const reportService = await ReportByNumberQueueService({
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
queue: true,
|
||||||
|
isRemote: isRemote && isRemote == "true" ? true : false
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(200).json({ reportService });
|
||||||
|
};
|
||||||
|
|
||||||
|
export const reportTicksCountByStatusChatEnds = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
if (
|
||||||
|
req.user.profile !== "master" &&
|
||||||
|
req.user.profile !== "admin" &&
|
||||||
|
req.user.profile !== "supervisor"
|
||||||
|
) {
|
||||||
|
throw new AppError("ERR_NO_PERMISSION", 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { startDate, endDate, userQueues } = req.query as IndexQuery;
|
||||||
|
|
||||||
|
const dateToday = splitDateTime(
|
||||||
|
new Date(format(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: ptBR }))
|
||||||
|
);
|
||||||
|
|
||||||
|
const queueIds = userQueues ? userQueues.map(queue => parseInt(queue)) : [];
|
||||||
|
|
||||||
|
const reportStatusChatEnd = await CountStatusChatEndService(
|
||||||
|
startDate || dateToday.fullDate,
|
||||||
|
endDate || dateToday.fullDate,
|
||||||
|
queueIds
|
||||||
|
);
|
||||||
|
|
||||||
|
return res.status(200).json({ reportStatusChatEnd });
|
||||||
|
};
|
||||||
|
|
|
@ -6,7 +6,7 @@ import ListSchedulingNotifyContactService from "../services/SchedulingNotifyServ
|
||||||
import CreateSchedulingNotifyService from "../services/SchedulingNotifyServices/CreateSchedulingNotifyService";
|
import CreateSchedulingNotifyService from "../services/SchedulingNotifyServices/CreateSchedulingNotifyService";
|
||||||
import ShowSchedulingNotifyService from "../services/SchedulingNotifyServices/ShowSchedulingNotifyService";
|
import ShowSchedulingNotifyService from "../services/SchedulingNotifyServices/ShowSchedulingNotifyService";
|
||||||
import { deleteScheduleByTicketIdCache } from "../helpers/SchedulingNotifyCache";
|
import { deleteScheduleByTicketIdCache } from "../helpers/SchedulingNotifyCache";
|
||||||
|
import ShowStatusChatEndService from "../services/StatusChatEndService/ShowStatusChatEndService";
|
||||||
|
|
||||||
type IndexQuery = {
|
type IndexQuery = {
|
||||||
contactNumber: string;
|
contactNumber: string;
|
||||||
|
@ -14,58 +14,58 @@ type IndexQuery = {
|
||||||
endDate: string;
|
endDate: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const reportScheduleNotifyByDateStartDateEnd = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
const { contactNumber, startDate, endDate } = req.query as IndexQuery;
|
||||||
|
|
||||||
|
const data_query = await ListSchedulingNotifyContactService(
|
||||||
export const reportScheduleNotifyByDateStartDateEnd = async (req: Request, res: Response): Promise<Response> => {
|
contactNumber,
|
||||||
|
startDate,
|
||||||
const { contactNumber, startDate, endDate } = req.query as IndexQuery
|
endDate
|
||||||
|
);
|
||||||
const data_query = await ListSchedulingNotifyContactService(contactNumber, startDate, endDate);
|
|
||||||
|
|
||||||
// console.group('DATA QUERY SCHEDULE:\n',data_query)
|
|
||||||
|
|
||||||
return res.status(200).json(data_query);
|
return res.status(200).json(data_query);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const createOrUpdateScheduleNotify = async (
|
||||||
export const createOrUpdateScheduleNotify = async (req: Request, res: Response): Promise<Response> => {
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
const scheduleData = req.body;
|
const scheduleData = req.body;
|
||||||
|
|
||||||
|
const statusChatEnd = await ShowStatusChatEndService({
|
||||||
|
name: scheduleData.statusChatEndName
|
||||||
|
});
|
||||||
|
|
||||||
|
const schedulingNotifyCreate = await CreateSchedulingNotifyService({
|
||||||
const schedulingNotifyCreate = await CreateSchedulingNotifyService(
|
|
||||||
{
|
|
||||||
schedulingNotifyId: scheduleData.schedulingNotifyId,
|
schedulingNotifyId: scheduleData.schedulingNotifyId,
|
||||||
ticketId: scheduleData.ticketId,
|
ticketId: scheduleData.ticketId,
|
||||||
statusChatEndId: scheduleData.statusChatEndId,
|
statusChatEndId: statusChatEnd.id,
|
||||||
schedulingDate: scheduleData.schedulingDate,
|
schedulingDate: scheduleData.schedulingDate,
|
||||||
schedulingTime: scheduleData.schedulingTime,
|
schedulingTime: scheduleData.schedulingTime,
|
||||||
message: scheduleData.message
|
message: scheduleData.message
|
||||||
}
|
});
|
||||||
)
|
|
||||||
|
|
||||||
// console.group(':::::::::::::::::: DATA schedulingNotifyCreate:\n',schedulingNotifyCreate)
|
// console.group(':::::::::::::::::: DATA schedulingNotifyCreate:\n',schedulingNotifyCreate)
|
||||||
// const io = getIO();
|
// const io = getIO();
|
||||||
// io.emit("schedulingNotify", {action: "update", schedulingNotifyCreate });
|
// io.emit("schedulingNotify", {action: "update", schedulingNotifyCreate });
|
||||||
|
|
||||||
return res.status(200).json(schedulingNotifyCreate);
|
return res.status(200).json(schedulingNotifyCreate);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const remove = async (req: Request, res: Response): Promise<Response> => {
|
export const remove = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
const { scheduleId } = req.params;
|
const { scheduleId } = req.params;
|
||||||
|
|
||||||
let schedule: any = await ShowSchedulingNotifyService(scheduleId)
|
let schedule: any = await ShowSchedulingNotifyService(scheduleId);
|
||||||
|
|
||||||
await deleteScheduleByTicketIdCache(schedule.ticketId)
|
await deleteScheduleByTicketIdCache(schedule.ticketId);
|
||||||
|
|
||||||
await DeleteSchedulingNotifyService(scheduleId);
|
await DeleteSchedulingNotifyService(scheduleId);
|
||||||
|
|
||||||
return res.status(200).send();
|
return res.status(200).send();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,7 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
|
||||||
const settings = await ListSettingsService();
|
const settings = await ListSettingsService();
|
||||||
|
|
||||||
// const config = await SettingTicket.findAll();
|
return res.status(200).json({ settings });
|
||||||
|
|
||||||
return res.status(200).json({ settings, });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ticketSettings = async (
|
export const ticketSettings = async (
|
||||||
|
@ -40,6 +38,7 @@ export const updateTicketSettings = async (
|
||||||
): Promise<Response> => {
|
): Promise<Response> => {
|
||||||
const {
|
const {
|
||||||
number,
|
number,
|
||||||
|
saturdayBusinessTime,
|
||||||
outBusinessHours,
|
outBusinessHours,
|
||||||
ticketExpiration,
|
ticketExpiration,
|
||||||
weekend,
|
weekend,
|
||||||
|
@ -58,6 +57,14 @@ export const updateTicketSettings = async (
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (saturdayBusinessTime && Object.keys(saturdayBusinessTime).length > 0) {
|
||||||
|
await updateSettingTicket({
|
||||||
|
...saturdayBusinessTime,
|
||||||
|
key: "saturdayBusinessTime",
|
||||||
|
number
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (ticketExpiration && Object.keys(ticketExpiration).length > 0) {
|
if (ticketExpiration && Object.keys(ticketExpiration).length > 0) {
|
||||||
await updateSettingTicket({
|
await updateSettingTicket({
|
||||||
...ticketExpiration,
|
...ticketExpiration,
|
||||||
|
@ -116,11 +123,12 @@ export const update = async (
|
||||||
throw new AppError("ERR_NO_PERMISSION", 403);
|
throw new AppError("ERR_NO_PERMISSION", 403);
|
||||||
}
|
}
|
||||||
const { settingKey: key } = req.params;
|
const { settingKey: key } = req.params;
|
||||||
const { value } = req.body;
|
const { value, obj } = req.body;
|
||||||
|
|
||||||
const setting = await UpdateSettingService({
|
const setting = await UpdateSettingService({
|
||||||
key,
|
key,
|
||||||
value
|
value,
|
||||||
|
obj
|
||||||
});
|
});
|
||||||
|
|
||||||
if (key && key == "whatsaAppCloudApi") {
|
if (key && key == "whatsaAppCloudApi") {
|
||||||
|
|
|
@ -1,12 +1,131 @@
|
||||||
import { Request, Response } from "express";
|
import { Request, Response } from "express";
|
||||||
import AppError from "../errors/AppError";
|
import AppError from "../errors/AppError";
|
||||||
|
import * as Yup from "yup";
|
||||||
|
|
||||||
|
type IndexQuery = {
|
||||||
|
searchParam: string;
|
||||||
|
pageNumber: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface StatusChatEndData {
|
||||||
|
name: string;
|
||||||
|
farewellMessage: string;
|
||||||
|
isDefault: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
import ListStatusChatEndService from "../services/StatusChatEndService/ListStatusChatEndService";
|
import ListStatusChatEndService from "../services/StatusChatEndService/ListStatusChatEndService";
|
||||||
|
import ShowStatusChatEndService from "../services/StatusChatEndService/ShowStatusChatEndService";
|
||||||
|
import UpdateStatusChatEndService from "../services/StatusChatEndService/UpdateStatusChatEndService";
|
||||||
|
import { getIO } from "../libs/socket";
|
||||||
|
import StatusChatEnd from "../models/StatusChatEnd";
|
||||||
|
import CreateStatusChatEndService from "../services/StatusChatEndService/CreateStatusChatEndService";
|
||||||
|
import { del } from "../helpers/RedisClient";
|
||||||
|
|
||||||
|
// export const show = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
|
||||||
|
// const { statusChatEnd, count, hasMore } = await ListStatusChatEndService({ searchParam: "", pageNumber: "1" });
|
||||||
|
|
||||||
|
// return res.status(200).json(statusChatEnd);
|
||||||
|
// };
|
||||||
|
|
||||||
|
export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
const { searchParam, pageNumber } = req.query as IndexQuery;
|
||||||
|
|
||||||
|
const { statusChatEnd, count, hasMore } = await ListStatusChatEndService({
|
||||||
|
searchParam,
|
||||||
|
pageNumber
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.json({ statusChatEnd, count, hasMore });
|
||||||
|
};
|
||||||
|
|
||||||
export const show = async (req: Request, res: Response): Promise<Response> => {
|
export const show = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
const { statusChatEndId } = req.params;
|
||||||
|
|
||||||
const { statusChatEnd, count, hasMore } = await ListStatusChatEndService({ searchParam: "", pageNumber: "1" });
|
let statushCatEnd;
|
||||||
|
|
||||||
|
const isNumber = (str: any) => !isNaN(str);
|
||||||
|
|
||||||
|
if (isNumber(statusChatEndId))
|
||||||
|
statushCatEnd = await ShowStatusChatEndService({ id: statusChatEndId });
|
||||||
|
else statushCatEnd = await ShowStatusChatEndService({ isDefault: true });
|
||||||
|
|
||||||
|
return res.status(200).json(statushCatEnd);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
const newStatusChatEnd: StatusChatEndData = req.body;
|
||||||
|
|
||||||
|
const StatusChatEndSchema = Yup.object().shape({
|
||||||
|
name: Yup.string().required()
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await StatusChatEndSchema.validate(newStatusChatEnd);
|
||||||
|
} catch (err: any) {
|
||||||
|
throw new AppError(err.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusChatEnd = await CreateStatusChatEndService({
|
||||||
|
...newStatusChatEnd
|
||||||
|
});
|
||||||
|
|
||||||
|
const io = getIO();
|
||||||
|
io.emit("statusChatEnd", {
|
||||||
|
action: "create",
|
||||||
|
statusChatEnd
|
||||||
|
});
|
||||||
|
|
||||||
return res.status(200).json(statusChatEnd);
|
return res.status(200).json(statusChatEnd);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const update = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
const statusChatEndData: StatusChatEndData = req.body;
|
||||||
|
|
||||||
|
const schema = Yup.object().shape({
|
||||||
|
name: Yup.string()
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await schema.validate(statusChatEndData);
|
||||||
|
} catch (err: any) {
|
||||||
|
throw new AppError(err.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { statusChatEndId } = req.params;
|
||||||
|
|
||||||
|
const statusChatEnd = await UpdateStatusChatEndService({
|
||||||
|
statusChatEndData,
|
||||||
|
statusChatEndId
|
||||||
|
});
|
||||||
|
|
||||||
|
const io = getIO();
|
||||||
|
io.emit("statusChatEnd", {
|
||||||
|
action: "update",
|
||||||
|
statusChatEnd
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(200).json(statusChatEnd);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const remove = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
const { statusChatEndId } = req.params;
|
||||||
|
|
||||||
|
await StatusChatEnd.destroy({ where: { id: statusChatEndId } });
|
||||||
|
|
||||||
|
await del(`statusChatEnd:${statusChatEndId}`);
|
||||||
|
|
||||||
|
const io = getIO();
|
||||||
|
io.emit("statusChatEnd", {
|
||||||
|
action: "delete",
|
||||||
|
statusChatEndId
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(200).json({ message: "Status chat deleted" });
|
||||||
|
};
|
||||||
|
|
|
@ -22,7 +22,7 @@ import format from "date-fns/format";
|
||||||
import ListTicketsServiceCache from "../services/TicketServices/ListTicketServiceCache";
|
import ListTicketsServiceCache from "../services/TicketServices/ListTicketServiceCache";
|
||||||
|
|
||||||
import { searchTicketCache, loadTicketsCache } from "../helpers/TicketCache";
|
import { searchTicketCache, loadTicketsCache } from "../helpers/TicketCache";
|
||||||
import { Op } from "sequelize";
|
import { Op, where } from "sequelize";
|
||||||
|
|
||||||
type IndexQuery = {
|
type IndexQuery = {
|
||||||
searchParam: string;
|
searchParam: string;
|
||||||
|
@ -75,6 +75,11 @@ import GetProfilePicUrl from "../services/WbotServices/GetProfilePicUrl";
|
||||||
import CreateContactService from "../services/ContactServices/CreateContactService";
|
import CreateContactService from "../services/ContactServices/CreateContactService";
|
||||||
import { botSendMessage } from "../services/WbotServices/wbotMessageListener";
|
import { botSendMessage } from "../services/WbotServices/wbotMessageListener";
|
||||||
import WhatsappQueue from "../models/WhatsappQueue";
|
import WhatsappQueue from "../models/WhatsappQueue";
|
||||||
|
import { del, get, set } from "../helpers/RedisClient";
|
||||||
|
import CountStatusChatEndService from "../services/StatusChatEndService/CountStatusChatEndService";
|
||||||
|
import Queue from "../models/Queue";
|
||||||
|
import StatusChatEnd from "../models/StatusChatEnd";
|
||||||
|
import controllByNumber from "../helpers/controllByNumber";
|
||||||
|
|
||||||
export const index = async (req: Request, res: Response): Promise<Response> => {
|
export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
const {
|
const {
|
||||||
|
@ -97,7 +102,8 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
queueIds = JSON.parse(queueIdsStringified);
|
queueIds = JSON.parse(queueIdsStringified);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { tickets, count, hasMore } = await ListTicketsService({
|
const { tickets, count, hasMore, remoteTicketsControll } =
|
||||||
|
await ListTicketsService({
|
||||||
searchParam,
|
searchParam,
|
||||||
pageNumber,
|
pageNumber,
|
||||||
status,
|
status,
|
||||||
|
@ -110,17 +116,28 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
searchParamContent
|
searchParamContent
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(200).json({ tickets, count, hasMore });
|
return res
|
||||||
|
.status(200)
|
||||||
|
.json({ tickets, count, hasMore, remoteTicketsControll });
|
||||||
};
|
};
|
||||||
|
|
||||||
export const remoteTicketCreation = async (
|
export const remoteTicketCreation = async (
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response
|
res: Response
|
||||||
): Promise<Response> => {
|
): Promise<Response> => {
|
||||||
const { contact_from, contact_to, msg, contact_name }: any = req.body;
|
let { queueId, contact_from, cc, contact_to, msg, contact_name }: any =
|
||||||
|
req.body;
|
||||||
|
|
||||||
const validate = ["contact_from", "contact_to", "msg"];
|
let whatsappId: any;
|
||||||
const validateOnlyNumber = ["contact_from", "contact_to"];
|
|
||||||
|
if (!queueId && !contact_from && !cc) {
|
||||||
|
return res.status(400).json({
|
||||||
|
error: `Property 'queueId' or 'contact_from' or 'cc' is required.`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const validate = ["contact_to", "msg"];
|
||||||
|
const validateOnlyNumber = ["queueId", "contact_to", "contact_from"];
|
||||||
|
|
||||||
for (let prop of validate) {
|
for (let prop of validate) {
|
||||||
if (!req.body[prop])
|
if (!req.body[prop])
|
||||||
|
@ -137,19 +154,61 @@ export const remoteTicketCreation = async (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (queueId) {
|
||||||
|
const whatsapps = await ListWhatsAppsForQueueService(queueId, "CONNECTED");
|
||||||
|
|
||||||
|
if (!whatsapps || whatsapps?.length == 0) {
|
||||||
|
return res.status(500).json({
|
||||||
|
msg: `queueId ${queueId} does not have a WhatsApp number associated with it or the number's session is disconnected.`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const { id } = whatsapps[0];
|
||||||
|
|
||||||
|
whatsappId = id;
|
||||||
|
} else if (contact_from) {
|
||||||
const whatsapp = await Whatsapp.findOne({
|
const whatsapp = await Whatsapp.findOne({
|
||||||
where: { number: contact_from, status: "CONNECTED" }
|
where: { number: contact_from, status: "CONNECTED" }
|
||||||
});
|
});
|
||||||
|
|
||||||
if (whatsapp) {
|
if (!whatsapp) {
|
||||||
const { id: whatsappId, number, status } = whatsapp;
|
return res.status(404).json({
|
||||||
|
msg: `Whatsapp number ${contact_from} not found or disconnected!`
|
||||||
const queue: any = await WhatsappQueue.findOne({
|
|
||||||
where: { whatsappId },
|
|
||||||
attributes: ["queueId"]
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const { queueId } = queue;
|
const { id } = whatsapp;
|
||||||
|
|
||||||
|
const { queues } = await ShowWhatsAppService(id);
|
||||||
|
|
||||||
|
if (!queues || queues.length == 0) {
|
||||||
|
return res.status(500).json({
|
||||||
|
msg: `The WhatsApp number ${contact_from} is not associated with any queue! `
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
queueId = queues[0].id;
|
||||||
|
whatsappId = id;
|
||||||
|
} else if (cc) {
|
||||||
|
const queue = await Queue.findOne({ where: { cc } });
|
||||||
|
if (!queue) {
|
||||||
|
return res.status(404).json({
|
||||||
|
msg: `Queue with cc ${cc} not found! `
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
queueId = queue.id;
|
||||||
|
|
||||||
|
const whatsapps = await ListWhatsAppsForQueueService(queueId, "CONNECTED");
|
||||||
|
|
||||||
|
if (whatsapps.length === 0) {
|
||||||
|
return res.status(500).json({
|
||||||
|
msg: `No WhatsApp found for this cc ${cc} or the WhatsApp number is disconnected! `
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
whatsappId = whatsapps[0].id;
|
||||||
|
}
|
||||||
|
|
||||||
// const validNumber = await CheckIsValidContact(contact_to, true);
|
// const validNumber = await CheckIsValidContact(contact_to, true);
|
||||||
const validNumber = contact_to;
|
const validNumber = contact_to;
|
||||||
|
@ -177,7 +236,8 @@ export const remoteTicketCreation = async (
|
||||||
|
|
||||||
const botInfo = await BotIsOnQueue("botqueue");
|
const botInfo = await BotIsOnQueue("botqueue");
|
||||||
|
|
||||||
let ticket = await Ticket.findOne({
|
// ticket from queueChoice or bot
|
||||||
|
let ticket: any = await Ticket.findOne({
|
||||||
where: {
|
where: {
|
||||||
[Op.or]: [
|
[Op.or]: [
|
||||||
{ contactId, status: "queueChoice" },
|
{ contactId, status: "queueChoice" },
|
||||||
|
@ -203,16 +263,50 @@ export const remoteTicketCreation = async (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ticket) {
|
ticket = await Ticket.findOne({
|
||||||
|
where: {
|
||||||
|
[Op.or]: [
|
||||||
|
{ contactId, status: "pending" },
|
||||||
|
{ contactId, status: "open" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (ticket) {
|
||||||
|
console.log(
|
||||||
|
`THE CAMPAIGN TICKET WAS NOT CREATED BECAUSE THE TICKET IS PENDING OR OPEN`
|
||||||
|
);
|
||||||
|
|
||||||
|
return res.status(422).json({
|
||||||
|
msg: `The campaign ticket was not created because the number ${contact_to} already has a ticket open or pending`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
ticket = await FindOrCreateTicketService(
|
ticket = await FindOrCreateTicketService(
|
||||||
contact,
|
contact,
|
||||||
whatsappId,
|
whatsappId,
|
||||||
0,
|
0,
|
||||||
undefined,
|
undefined,
|
||||||
queueId
|
queueId,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
// botSendMessage(ticket, `${msg}`);
|
||||||
|
|
||||||
|
await ticket.update({
|
||||||
|
lastMessage: msg
|
||||||
|
});
|
||||||
|
|
||||||
|
await set(
|
||||||
|
`remote:ticketId:${ticket.id}`,
|
||||||
|
JSON.stringify({
|
||||||
|
id: ticket.id,
|
||||||
|
createdAt: ticket.createdAt,
|
||||||
|
updatedAt: ticket.updatedAt,
|
||||||
|
whatsappId: ticket.whatsappId,
|
||||||
|
status: ticket.status
|
||||||
|
})
|
||||||
);
|
);
|
||||||
botSendMessage(ticket, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
io.to(ticket.status).emit("ticket", {
|
io.to(ticket.status).emit("ticket", {
|
||||||
|
@ -220,9 +314,19 @@ export const remoteTicketCreation = async (
|
||||||
ticket
|
ticket
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const obj = await controllByNumber();
|
||||||
|
|
||||||
|
if (obj?.tickets) {
|
||||||
|
io.emit("remoteTickesControll", {
|
||||||
|
action: "update",
|
||||||
|
tickets: obj.ticketIds
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`REMOTE TICKET CREATION FROM ENDPOINT | STATUS: 200 | MSG: success`
|
`REMOTE TICKET CREATION FROM ENDPOINT | STATUS: 200 | MSG: success`
|
||||||
);
|
);
|
||||||
|
|
||||||
return res.status(200).json({ msg: "success" });
|
return res.status(200).json({ msg: "success" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,14 +336,6 @@ export const remoteTicketCreation = async (
|
||||||
return res
|
return res
|
||||||
.status(500)
|
.status(500)
|
||||||
.json({ msg: `The number ${contact_to} does not exist on WhatsApp` });
|
.json({ msg: `The number ${contact_to} does not exist on WhatsApp` });
|
||||||
}
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
`REMOTE TICKET CREATION FROM ENDPOINT | STATUS: 500 | MSG: Whatsapp number ${contact_from} disconnected or it doesn't exist in omnihit`
|
|
||||||
);
|
|
||||||
return res.status(500).json({
|
|
||||||
msg: `Whatsapp number ${contact_from} disconnected or it doesn't exist in omnihit`
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const store = async (req: Request, res: Response): Promise<Response> => {
|
export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
@ -314,9 +410,8 @@ export const show = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
|
||||||
export const count = async (req: Request, res: Response): Promise<Response> => {
|
export const count = async (req: Request, res: Response): Promise<Response> => {
|
||||||
// type indexQ = { status: string; date?: string; };
|
// type indexQ = { status: string; date?: string; };
|
||||||
const { status, date } = req.query as IndexQuery;
|
const { status, date, queueIds } = req.query as IndexQuery;
|
||||||
|
const ticketCount = await CountTicketService(status, date, queueIds);
|
||||||
const ticketCount = await CountTicketService(status, date);
|
|
||||||
|
|
||||||
return res.status(200).json(ticketCount);
|
return res.status(200).json(ticketCount);
|
||||||
};
|
};
|
||||||
|
@ -339,34 +434,75 @@ export const update = async (
|
||||||
// lembrete
|
// lembrete
|
||||||
const scheduleData = JSON.parse(schedulingNotifyData);
|
const scheduleData = JSON.parse(schedulingNotifyData);
|
||||||
|
|
||||||
const statusChatEndName = await ShowStatusChatEndService(
|
console.log("scheduleData: ", scheduleData);
|
||||||
scheduleData.statusChatEndId
|
|
||||||
);
|
const statusChatEnd = await ShowStatusChatEndService({
|
||||||
|
name: scheduleData.statusChatEndName
|
||||||
|
});
|
||||||
|
|
||||||
const { ticket } = await UpdateTicketService({
|
const { ticket } = await UpdateTicketService({
|
||||||
ticketData: {
|
ticketData: {
|
||||||
status: status,
|
status: status,
|
||||||
userId: userId,
|
userId: userId,
|
||||||
statusChatEnd: statusChatEndName.name
|
statusChatEnd: statusChatEnd.name,
|
||||||
|
statusChatEndId: statusChatEnd.id
|
||||||
},
|
},
|
||||||
ticketId
|
ticketId
|
||||||
});
|
});
|
||||||
|
|
||||||
if (scheduleData.farewellMessage) {
|
let _farewellMessage;
|
||||||
|
|
||||||
|
if (getSettingValue("farewellMessageByStatusChatEnd")?.value == "enabled") {
|
||||||
|
const statusChatEndData = await get({
|
||||||
|
key: `statusChatEnd:${statusChatEnd.id}`,
|
||||||
|
parse: true
|
||||||
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
statusChatEndData &&
|
||||||
|
statusChatEndData?.farewellMessage &&
|
||||||
|
statusChatEndData?.farewellMessage?.trim()?.length > 0
|
||||||
|
) {
|
||||||
|
const { farewellMessage } = statusChatEndData;
|
||||||
|
|
||||||
|
_farewellMessage = farewellMessage;
|
||||||
|
}
|
||||||
|
} else if (getSettingValue("farewellMessageByQueue")?.value == "enabled") {
|
||||||
|
const queueData = await get({
|
||||||
|
key: `queue:${ticket.queueId}`,
|
||||||
|
parse: true
|
||||||
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
queueData &&
|
||||||
|
queueData?.farewellMessage &&
|
||||||
|
queueData?.farewellMessage?.trim()?.length > 0
|
||||||
|
) {
|
||||||
|
const { farewellMessage } = queueData;
|
||||||
|
|
||||||
|
_farewellMessage = farewellMessage;
|
||||||
|
}
|
||||||
|
} else if (scheduleData.farewellMessage) {
|
||||||
const whatsapp = await ShowWhatsAppService(ticket.whatsappId);
|
const whatsapp = await ShowWhatsAppService(ticket.whatsappId);
|
||||||
|
|
||||||
const { farewellMessage } = whatsapp;
|
const { farewellMessage } = whatsapp;
|
||||||
|
|
||||||
if (farewellMessage) {
|
if (farewellMessage) {
|
||||||
await SendWhatsAppMessage({ body: farewellMessage, ticket });
|
_farewellMessage = farewellMessage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// lembrete // agendamento
|
if (_farewellMessage) {
|
||||||
|
await SendWhatsAppMessage({ body: `\u200e${_farewellMessage}`, ticket });
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("tatusChatEnd.name: ", statusChatEnd.name);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
scheduleData.statusChatEndId === "2" ||
|
statusChatEnd.name === "LEMBRETE" ||
|
||||||
scheduleData.statusChatEndId === "3"
|
statusChatEnd.name === "AGENDAMENTO À CONFIRMAR"
|
||||||
) {
|
) {
|
||||||
|
// lembrete // agendamento
|
||||||
if (
|
if (
|
||||||
isScheduling(scheduleData.schedulingDate, scheduleData.schedulingTime)
|
isScheduling(scheduleData.schedulingDate, scheduleData.schedulingTime)
|
||||||
) {
|
) {
|
||||||
|
@ -377,7 +513,7 @@ export const update = async (
|
||||||
|
|
||||||
const schedulingNotifyCreate = await CreateSchedulingNotifyService({
|
const schedulingNotifyCreate = await CreateSchedulingNotifyService({
|
||||||
ticketId: scheduleData.ticketId,
|
ticketId: scheduleData.ticketId,
|
||||||
statusChatEndId: scheduleData.statusChatEndId,
|
statusChatEndId: `${statusChatEnd.id}`,
|
||||||
schedulingDate: scheduleData.schedulingDate,
|
schedulingDate: scheduleData.schedulingDate,
|
||||||
schedulingTime: scheduleData.schedulingTime,
|
schedulingTime: scheduleData.schedulingTime,
|
||||||
message: scheduleData.message
|
message: scheduleData.message
|
||||||
|
@ -405,7 +541,6 @@ export const update = async (
|
||||||
for (const w of whatsappsByqueue) {
|
for (const w of whatsappsByqueue) {
|
||||||
let whats = await ListWhatsAppsNumber(w.id);
|
let whats = await ListWhatsAppsNumber(w.id);
|
||||||
|
|
||||||
console.log("-------> WHATS: ", JSON.stringify(whats, null, 6));
|
|
||||||
const ticket = await Ticket.findOne({
|
const ticket = await Ticket.findOne({
|
||||||
where: {
|
where: {
|
||||||
[Op.and]: [
|
[Op.and]: [
|
||||||
|
@ -490,6 +625,26 @@ export const update = async (
|
||||||
await setMessageAsRead(ticket);
|
await setMessageAsRead(ticket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ticketData.status == "open" || ticketData.status == "pending") {
|
||||||
|
let ticketRemote = await get({
|
||||||
|
key: `remote:ticketId:${ticketId}`
|
||||||
|
});
|
||||||
|
|
||||||
|
if (ticketRemote) {
|
||||||
|
ticketRemote = JSON.parse(ticketRemote);
|
||||||
|
|
||||||
|
ticketRemote = {
|
||||||
|
...ticketRemote,
|
||||||
|
...{
|
||||||
|
status: ticketData.status == "open" ? "open" : "pending",
|
||||||
|
updatedAt: ticket.updatedAt
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
set(`remote:ticketId:${ticketId}`, JSON.stringify(ticketRemote));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ticketData.userId) {
|
if (ticketData.userId) {
|
||||||
const dateToday = splitDateTime(
|
const dateToday = splitDateTime(
|
||||||
new Date(format(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: ptBR }))
|
new Date(format(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: ptBR }))
|
||||||
|
@ -560,5 +715,7 @@ export const remove = async (
|
||||||
ticketId: +ticketId
|
ticketId: +ticketId
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await del(`remote:ticketId:${ticketId}`);
|
||||||
|
|
||||||
return res.status(200).json({ message: "ticket deleted" });
|
return res.status(200).json({ message: "ticket deleted" });
|
||||||
};
|
};
|
||||||
|
|
|
@ -100,7 +100,7 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
// };
|
// };
|
||||||
|
|
||||||
export const all = async (req: Request, res: Response): Promise<Response> => {
|
export const all = async (req: Request, res: Response): Promise<Response> => {
|
||||||
let { userId, profile }: any = req.query as IndexQuery;
|
let { userId, profile, transferToOtherQueues }: any = req.query as IndexQuery;
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
"userId: ",
|
"userId: ",
|
||||||
|
@ -111,7 +111,7 @@ export const all = async (req: Request, res: Response): Promise<Response> => {
|
||||||
getSettingValue("queueTransferByWhatsappScope")?.value
|
getSettingValue("queueTransferByWhatsappScope")?.value
|
||||||
);
|
);
|
||||||
|
|
||||||
if (getSettingValue("queueTransferByWhatsappScope")?.value == "enabled") {
|
if (getSettingValue("queueTransferByWhatsappScope")?.value == "enabled" && !transferToOtherQueues) {
|
||||||
if (!userId) return res.json({ users: [], queues: [] });
|
if (!userId) return res.json({ users: [], queues: [] });
|
||||||
|
|
||||||
const obj = await ListUserByWhatsappQueuesService(
|
const obj = await ListUserByWhatsappQueuesService(
|
||||||
|
@ -138,8 +138,15 @@ export const all = async (req: Request, res: Response): Promise<Response> => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const store = async (req: Request, res: Response): Promise<Response> => {
|
export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
const { email, password, name, profile, positionCompany, queueIds } =
|
const {
|
||||||
req.body;
|
email,
|
||||||
|
password,
|
||||||
|
name,
|
||||||
|
profile,
|
||||||
|
positionId,
|
||||||
|
queueIds,
|
||||||
|
transferToOtherQueues
|
||||||
|
} = req.body;
|
||||||
|
|
||||||
console.log("===========> req.url: ", req.url);
|
console.log("===========> req.url: ", req.url);
|
||||||
|
|
||||||
|
@ -162,9 +169,10 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
email,
|
email,
|
||||||
password,
|
password,
|
||||||
name,
|
name,
|
||||||
positionCompany,
|
positionId,
|
||||||
profile,
|
profile,
|
||||||
queueIds
|
queueIds,
|
||||||
|
transferToOtherQueues
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
|
|
|
@ -36,7 +36,6 @@ import ShowUserService from "../services/UserServices/ShowUserService";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import receiveWhatsAppMediaOfficialAPI from "../helpers/ReceiveWhatsAppMediaOfficialAPI";
|
import receiveWhatsAppMediaOfficialAPI from "../helpers/ReceiveWhatsAppMediaOfficialAPI";
|
||||||
|
|
||||||
import whatsappOfficialAPI from "../helpers/WhatsappOfficialAPI";
|
|
||||||
import whatsappOfficialNumberInfo from "../helpers/WhatsappOfficialNumberInfo";
|
import whatsappOfficialNumberInfo from "../helpers/WhatsappOfficialNumberInfo";
|
||||||
import { getSettingValue } from "../helpers/WhaticketSettings";
|
import { getSettingValue } from "../helpers/WhaticketSettings";
|
||||||
import ListWhatsAppsNumber from "../services/WhatsappService/ListWhatsAppsNumber";
|
import ListWhatsAppsNumber from "../services/WhatsappService/ListWhatsAppsNumber";
|
||||||
|
@ -230,7 +229,10 @@ export const weebhook = async (
|
||||||
req.body.entry[0].changes[0].value.metadata.display_phone_number;
|
req.body.entry[0].changes[0].value.metadata.display_phone_number;
|
||||||
let type = message.type;
|
let type = message.type;
|
||||||
|
|
||||||
const contact_to_exist = await get("whatsapp:*", `${contact_to}`);
|
const contact_to_exist = await get({
|
||||||
|
key: "whatsapp:*",
|
||||||
|
value: `${contact_to}`
|
||||||
|
});
|
||||||
|
|
||||||
if (contact_to_exist == null) {
|
if (contact_to_exist == null) {
|
||||||
console.log(
|
console.log(
|
||||||
|
@ -285,7 +287,8 @@ export const weebhook = async (
|
||||||
|
|
||||||
let filename = await receiveWhatsAppMediaOfficialAPI(
|
let filename = await receiveWhatsAppMediaOfficialAPI(
|
||||||
mediaId,
|
mediaId,
|
||||||
whatsapp.phoneNumberId
|
whatsapp.phoneNumberId,
|
||||||
|
whatsapp.whatsappOfficialToken
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!filename) throw new AppError("There was an error");
|
if (!filename) throw new AppError("There was an error");
|
||||||
|
@ -374,9 +377,11 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
} else if (!isOfficial) {
|
} else if (!isOfficial) {
|
||||||
phoneNumberId = "";
|
phoneNumberId = "";
|
||||||
wabaId = "";
|
wabaId = "";
|
||||||
number = "";
|
//number = "";
|
||||||
|
}
|
||||||
|
if(!number){
|
||||||
|
number = getNumberFromName(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
let invalidPhoneName = validatePhoneName(name);
|
let invalidPhoneName = validatePhoneName(name);
|
||||||
|
|
||||||
if (invalidPhoneName) {
|
if (invalidPhoneName) {
|
||||||
|
@ -408,7 +413,15 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
client_url: `${process.env.BACKEND_URL_RAW}:${process.env.PORT}`
|
client_url: `${process.env.BACKEND_URL_RAW}:${process.env.PORT}`
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await set(`whatsapp:${whatsapp.id}`, `${number}`);
|
await set(
|
||||||
|
`whatsapp:${whatsapp.id}`,
|
||||||
|
JSON.stringify({
|
||||||
|
number: whatsapp?.number,
|
||||||
|
id: whatsapp?.id,
|
||||||
|
greetingMessage: whatsapp?.greetingMessage,
|
||||||
|
phoneNumberId: whatsapp?.phoneNumberId
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
|
@ -468,9 +481,11 @@ export const update = async (
|
||||||
} else if (!isOfficial) {
|
} else if (!isOfficial) {
|
||||||
whatsappData.phoneNumberId = "";
|
whatsappData.phoneNumberId = "";
|
||||||
whatsappData.wabaId = "";
|
whatsappData.wabaId = "";
|
||||||
whatsappData.number = "";
|
//whatsappData.number = "";
|
||||||
|
}
|
||||||
|
if(!whatsappData?.number){
|
||||||
|
whatsappData.number = getNumberFromName(whatsappData.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
const { whatsapp, oldDefaultWhatsapp } = await UpdateWhatsAppService({
|
const { whatsapp, oldDefaultWhatsapp } = await UpdateWhatsAppService({
|
||||||
whatsappData,
|
whatsappData,
|
||||||
whatsappId
|
whatsappId
|
||||||
|
@ -484,7 +499,15 @@ export const update = async (
|
||||||
client_url: `${process.env.BACKEND_URL_RAW}:${process.env.PORT}`
|
client_url: `${process.env.BACKEND_URL_RAW}:${process.env.PORT}`
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await set(`whatsapp:${whatsapp.id}`, `${number}`);
|
await set(
|
||||||
|
`whatsapp:${whatsapp.id}`,
|
||||||
|
JSON.stringify({
|
||||||
|
number: whatsapp?.number,
|
||||||
|
id: whatsapp?.id,
|
||||||
|
greetingMessage: whatsapp?.greetingMessage,
|
||||||
|
phoneNumberId: whatsapp?.phoneNumberId
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
|
|
|
@ -15,6 +15,9 @@ import SchedulingNotify from "../models/SchedulingNotify";
|
||||||
import StatusChatEnd from "../models/StatusChatEnd";
|
import StatusChatEnd from "../models/StatusChatEnd";
|
||||||
import UserOnlineTime from "../models/UserOnlineTime";
|
import UserOnlineTime from "../models/UserOnlineTime";
|
||||||
import SettingTicket from "../models/SettingTicket";
|
import SettingTicket from "../models/SettingTicket";
|
||||||
|
import QuickAnswerQueue from "../models/QuickAnswerQueue";
|
||||||
|
import Position from "../models/Position"
|
||||||
|
import ContactQueue from "../models/ContactQueues"
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
const dbConfig = require("../config/database");
|
const dbConfig = require("../config/database");
|
||||||
// import dbConfig from "../config/database";
|
// import dbConfig from "../config/database";
|
||||||
|
@ -33,11 +36,13 @@ const models = [
|
||||||
WhatsappQueue,
|
WhatsappQueue,
|
||||||
UserQueue,
|
UserQueue,
|
||||||
QuickAnswer,
|
QuickAnswer,
|
||||||
|
QuickAnswerQueue,
|
||||||
SchedulingNotify,
|
SchedulingNotify,
|
||||||
StatusChatEnd,
|
StatusChatEnd,
|
||||||
UserOnlineTime,
|
UserOnlineTime,
|
||||||
SettingTicket
|
SettingTicket,
|
||||||
|
Position,
|
||||||
|
ContactQueue
|
||||||
];
|
];
|
||||||
|
|
||||||
sequelize.addModels(models);
|
sequelize.addModels(models);
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("Messages", "fromAgent", {
|
||||||
|
type: DataTypes.BOOLEAN,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: false
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("Messages", "fromAgent");
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("Users", "secondaryId", {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: true
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("Users", "secondaryId");
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("Tickets", "statusChatEndId", {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
references: { model: "StatusChatEnds", key: "id" },
|
||||||
|
onUpdate: "CASCADE",
|
||||||
|
onDelete: "SET NULL",
|
||||||
|
allowNull: true
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("Tickets", "statusChatEndId");
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("Queues", "cc", {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: true
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("Queues", "cc");
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.createTable("QuickAnswerQueues", {
|
||||||
|
quickAnswerId: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true
|
||||||
|
},
|
||||||
|
queueId: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true
|
||||||
|
},
|
||||||
|
createdAt: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
updatedAt: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.dropTable("QuickAnswerQueues");
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("Queues", "farewellMessage", {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: true
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("Queues", "farewellMessage");
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("StatusChatEnds", "farewellMessage", {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: true
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("StatusChatEnds", "farewellMessage");
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("StatusChatEnds", "isDefault", {
|
||||||
|
type: DataTypes.BOOLEAN,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: false
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("StatusChatEnds", "isDefault");
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.createTable("Positions", {
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
autoIncrement: true,
|
||||||
|
primaryKey: true,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: DataTypes.TEXT,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
createdAt: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
updatedAt: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.dropTable("Positions");
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("Users", "positionId", {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
references: { model: "Positions", key: "id" },
|
||||||
|
onUpdate: "CASCADE",
|
||||||
|
onDelete: "SET NULL"
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("Users", "positionId");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.createTable("ContactQueues", {
|
||||||
|
contactId: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true
|
||||||
|
},
|
||||||
|
queueId: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true
|
||||||
|
},
|
||||||
|
createdAt: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
updatedAt: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.dropTable("ContactQueues");
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("Tickets", "isRemote", {
|
||||||
|
type: DataTypes.BOOLEAN,
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: false
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("Tickets", "isRemote");
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("Tickets", "remoteDone", {
|
||||||
|
type: DataTypes.BOOLEAN,
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: false
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("Tickets", "remoteDone");
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("Settings", "obj", {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: true
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("Settings", "obj");
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("Users", "transferToOtherQueues", {
|
||||||
|
type: DataTypes.BOOLEAN,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: false
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("Users", "transferToOtherQueues");
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("Users", "positionCompany");
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("Users", "positionCompany", {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("Users", "identifier", {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: true
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("Users", "identifier");
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("Whatsapps", "whatsappOfficialToken", {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: true
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("Whatsapps", "whatsappOfficialToken");
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,26 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
up: (queryInterface, Sequelize) => {
|
|
||||||
/*
|
|
||||||
Add altering commands here.
|
|
||||||
Return a promise to correctly handle asynchronicity.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
return queryInterface.bulkInsert('People', [{
|
|
||||||
name: 'John Doe',
|
|
||||||
isBetaMember: false
|
|
||||||
}], {});
|
|
||||||
*/
|
|
||||||
},
|
|
||||||
|
|
||||||
down: (queryInterface, Sequelize) => {
|
|
||||||
/*
|
|
||||||
Add reverting commands here.
|
|
||||||
Return a promise to correctly handle asynchronicity.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
return queryInterface.bulkDelete('People', null, {});
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { QueryInterface } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkInsert(
|
||||||
|
"SettingTickets",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
message: "",
|
||||||
|
startTime: new Date(),
|
||||||
|
endTime: new Date(),
|
||||||
|
value: "disabled",
|
||||||
|
key: "saturdayBusinessTime",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkDelete("SettingTickets", {});
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { QueryInterface } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkInsert(
|
||||||
|
"Settings",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: "quickAnswerByQueue",
|
||||||
|
value: "disabled",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkDelete("Settings", {});
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { QueryInterface } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkInsert(
|
||||||
|
"Settings",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: "farewellMessageByQueue",
|
||||||
|
value: "disabled",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkDelete("Settings", {});
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { QueryInterface } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkInsert(
|
||||||
|
"Settings",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: "farewellMessageByStatusChatEnd",
|
||||||
|
value: "disabled",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkDelete("Settings", {});
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { QueryInterface } from "sequelize"
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkInsert(
|
||||||
|
"Settings",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: "contactByqueues",
|
||||||
|
value: "disabled",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkDelete("Settings", {})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { QueryInterface } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkInsert(
|
||||||
|
"Settings",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: "blockAudioVideoMedia",
|
||||||
|
value: "disabled",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkDelete("Settings", {});
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { QueryInterface } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkInsert(
|
||||||
|
"Settings",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: "waitingTimeTickets",
|
||||||
|
value: "disabled",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkDelete("Settings", {});
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { QueryInterface } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkInsert(
|
||||||
|
"Settings",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: "notificationTransferQueue",
|
||||||
|
value: "disabled",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkDelete("Settings", {});
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { QueryInterface } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkInsert(
|
||||||
|
"Settings",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: "remoteTicketSendControll",
|
||||||
|
value: "true",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkDelete("Settings", {});
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,5 +1,5 @@
|
||||||
class AppError {
|
class AppError {
|
||||||
public readonly message: string;
|
public message: string;
|
||||||
|
|
||||||
public readonly statusCode: number;
|
public readonly statusCode: number;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
import { intervalToDuration } from "date-fns";
|
||||||
|
import { del, get, set } from "./RedisClient";
|
||||||
|
import { getIO } from "../libs/socket";
|
||||||
|
import controllByNumber from "./controllByNumber";
|
||||||
|
import UpdateTicketService from "../services/TicketServices/UpdateTicketService";
|
||||||
|
|
||||||
|
let timer: any;
|
||||||
|
|
||||||
|
const AutoRemoteTickets = async () => {
|
||||||
|
try {
|
||||||
|
let obj: any = await controllByNumber();
|
||||||
|
|
||||||
|
if (!obj?.tickets) return;
|
||||||
|
|
||||||
|
// console.log("remote tickets: ", obj?.tickets);
|
||||||
|
|
||||||
|
for (const ticket of obj.tickets) {
|
||||||
|
if (!ticket.includes("open") || ticket.includes("messageDateTime"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const regex = /"updatedAt":"([^"]+)"/;
|
||||||
|
let match = ticket.match(regex);
|
||||||
|
|
||||||
|
const updatedAt = match ? match[1] : null;
|
||||||
|
|
||||||
|
console.log("updatedAt: ", updatedAt);
|
||||||
|
|
||||||
|
let timeDiff: any = intervalToDuration({
|
||||||
|
start: new Date(updatedAt),
|
||||||
|
end: new Date()
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("----------> idle time timeDiff: ", timeDiff);
|
||||||
|
|
||||||
|
if (timeDiff.minutes > 2) {
|
||||||
|
match = ticket.match(/"id":(\d+)/);
|
||||||
|
let ticketId = match ? match[1] : null;
|
||||||
|
console.log("ticketId: ", ticketId);
|
||||||
|
|
||||||
|
ticketId = JSON.parse(ticketId);
|
||||||
|
|
||||||
|
let ticketRemote = await get({
|
||||||
|
key: `remote:ticketId:${ticketId}`
|
||||||
|
});
|
||||||
|
|
||||||
|
if (ticketRemote) {
|
||||||
|
ticketRemote = JSON.parse(ticketRemote);
|
||||||
|
|
||||||
|
ticketRemote = {
|
||||||
|
...ticketRemote,
|
||||||
|
...{ status: "pending" }
|
||||||
|
};
|
||||||
|
|
||||||
|
set(`remote:ticketId:${ticketId}`, JSON.stringify(ticketRemote));
|
||||||
|
|
||||||
|
await UpdateTicketService({
|
||||||
|
ticketData: {
|
||||||
|
status: "pending",
|
||||||
|
userId: null
|
||||||
|
},
|
||||||
|
ticketId
|
||||||
|
});
|
||||||
|
|
||||||
|
const io = getIO();
|
||||||
|
io.emit("remoteTickesControllIdleOpen", {
|
||||||
|
action: "update",
|
||||||
|
ticketId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const ticket of obj.tickets) {
|
||||||
|
if (!ticket.includes("messageDateTime")) continue;
|
||||||
|
|
||||||
|
let match = ticket.match(/"messageDateTime":("[^"]*")/);
|
||||||
|
let messageDateTime = match ? match[1] : null;
|
||||||
|
console.log("messageDateTime: ", messageDateTime);
|
||||||
|
|
||||||
|
match = ticket.match(/"whatsappId":(\d+)/);
|
||||||
|
let whatsappId = match ? match[1] : null;
|
||||||
|
console.log("whatsappId: ", whatsappId);
|
||||||
|
|
||||||
|
const whatsapp = await get({
|
||||||
|
key: `whatsapp:${whatsappId}`
|
||||||
|
});
|
||||||
|
|
||||||
|
match = whatsapp.match(/"number":"(\d+)"/);
|
||||||
|
let number = match ? match[1] : null;
|
||||||
|
console.log("number: ", number);
|
||||||
|
|
||||||
|
match = ticket.match(/"id":(\d+)/);
|
||||||
|
let ticketId = match ? match[1] : null;
|
||||||
|
console.log("ticketId: ", ticketId);
|
||||||
|
|
||||||
|
number = JSON.parse(number);
|
||||||
|
ticketId = JSON.parse(ticketId);
|
||||||
|
|
||||||
|
let timeDiff: any = intervalToDuration({
|
||||||
|
start: new Date(JSON.parse(messageDateTime)),
|
||||||
|
end: new Date()
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("______timeDiff: ", timeDiff);
|
||||||
|
|
||||||
|
if (timeDiff.seconds > 50) {
|
||||||
|
del(`remote:ticketId:${ticketId}`);
|
||||||
|
|
||||||
|
obj = await controllByNumber();
|
||||||
|
|
||||||
|
const io = getIO();
|
||||||
|
io.emit("remoteTickesControll", {
|
||||||
|
action: "update",
|
||||||
|
tickets: obj.ticketIds
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("There was an error on auto remote tickets service: ", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const schedule = async () => {
|
||||||
|
try {
|
||||||
|
clearInterval(timer);
|
||||||
|
|
||||||
|
await AutoRemoteTickets();
|
||||||
|
} catch (error) {
|
||||||
|
console.log("error on schedule: ", error);
|
||||||
|
} finally {
|
||||||
|
timer = setInterval(schedule, 5000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
timer = setInterval(schedule, 5000);
|
||||||
|
|
||||||
|
export default schedule;
|
|
@ -5,8 +5,7 @@ import ListUsersService from "../services/UserServices/ListUsersService";
|
||||||
import { get } from "./RedisClient";
|
import { get } from "./RedisClient";
|
||||||
|
|
||||||
const _botIsOnQueue = async (botName: string) => {
|
const _botIsOnQueue = async (botName: string) => {
|
||||||
|
const botInfo = await get({ key: "botInfo", parse: true });
|
||||||
const botInfo = await get("botInfo");
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
botInfo &&
|
botInfo &&
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Op } from "sequelize";
|
import { Op } from "sequelize";
|
||||||
import AppError from "../errors/AppError";
|
import AppError from "../errors/AppError";
|
||||||
import Ticket from "../models/Ticket";
|
import Ticket from "../models/Ticket";
|
||||||
|
import User from "../models/User";
|
||||||
import ListWhatsAppsNumber from "../services/WhatsappService/ListWhatsAppsNumber";
|
import ListWhatsAppsNumber from "../services/WhatsappService/ListWhatsAppsNumber";
|
||||||
import { getSettingValue } from "./WhaticketSettings";
|
import { getSettingValue } from "./WhaticketSettings";
|
||||||
import ListWhatsAppsForQueueService from "../services/WhatsappService/ListWhatsAppsForQueueService";
|
import ListWhatsAppsForQueueService from "../services/WhatsappService/ListWhatsAppsForQueueService";
|
||||||
|
@ -38,8 +39,13 @@ const CheckContactOpenTickets = async (
|
||||||
|
|
||||||
if (ticket) {
|
if (ticket) {
|
||||||
if (handle) return true;
|
if (handle) return true;
|
||||||
|
const userName = await User.findOne({
|
||||||
|
where:{ id: ticket.userId }
|
||||||
|
});
|
||||||
|
const error = new AppError("ERR_OTHER_OPEN_TICKET");
|
||||||
|
error.message = `Erro: já existe um ticket criado com esse contato. Responsável: ${userName? userName.name.toUpperCase() : 'Aguardando'}`;
|
||||||
|
|
||||||
throw new AppError("ERR_OTHER_OPEN_TICKET");
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ const GetDefaultWhatsApp = async ({
|
||||||
where: { isDefault: true }
|
where: { isDefault: true }
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!defaultWhatsapp && !ignoreNoWhatsappFound) {
|
if (!defaultWhatsapp) {
|
||||||
if (userId) {
|
if (userId) {
|
||||||
let whatsapps = await wbotByUserQueue({ userId, queueId });
|
let whatsapps = await wbotByUserQueue({ userId, queueId });
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
const monthsAgo = (months: number) => {
|
||||||
|
const { subMonths, startOfMonth, format } = require("date-fns");
|
||||||
|
|
||||||
|
// Get the current date
|
||||||
|
const currentDate = new Date();
|
||||||
|
|
||||||
|
// Subtract 4 months from the current date
|
||||||
|
const monthsAgo = subMonths(currentDate, months);
|
||||||
|
|
||||||
|
// Get the start of the month for the current date and four months ago
|
||||||
|
// const startOfCurrentMonth = startOfMonth(currentDate);
|
||||||
|
const startMonthsAgo = startOfMonth(monthsAgo);
|
||||||
|
|
||||||
|
// Format the dates in YYYY-MM-DD format
|
||||||
|
// const formattedCurrentMonth = format(startOfCurrentMonth, "yyyy-MM-dd");
|
||||||
|
const formattedMonthsAgo = format(startMonthsAgo, "yyyy-MM-dd");
|
||||||
|
|
||||||
|
// console.log("Current Month:", formattedCurrentMonth);
|
||||||
|
// console.log("Months Ago:", formattedMonthsAgo);
|
||||||
|
return formattedMonthsAgo;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default monthsAgo;
|
|
@ -0,0 +1,29 @@
|
||||||
|
import QuickAnswer from "../models/QuickAnswer";
|
||||||
|
|
||||||
|
export default function quickAnswearByQueueFiltered(
|
||||||
|
queueIds: any[],
|
||||||
|
quickAnswers: QuickAnswer[]
|
||||||
|
) {
|
||||||
|
let auxQuickAnswear = [];
|
||||||
|
let repet: any[] = [];
|
||||||
|
const userQueues = queueIds.map((uq: any) => uq.queueId);
|
||||||
|
|
||||||
|
for (const quickAnswer of quickAnswers) {
|
||||||
|
const { queues, id } = quickAnswer;
|
||||||
|
|
||||||
|
if (queues.length == 0) {
|
||||||
|
auxQuickAnswear.push(quickAnswer);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const q of queues) {
|
||||||
|
if (userQueues.includes(q.id)) {
|
||||||
|
if (repet.includes(id)) continue;
|
||||||
|
repet.push(id);
|
||||||
|
|
||||||
|
auxQuickAnswear.push(quickAnswer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return auxQuickAnswear;
|
||||||
|
}
|
|
@ -10,7 +10,6 @@ import {
|
||||||
|
|
||||||
import { writeFile } from "fs";
|
import { writeFile } from "fs";
|
||||||
|
|
||||||
import whatsappOfficialAPI from "./WhatsappOfficialAPI";
|
|
||||||
import path, { join } from "path";
|
import path, { join } from "path";
|
||||||
import { promisify } from "util";
|
import { promisify } from "util";
|
||||||
|
|
||||||
|
@ -18,14 +17,20 @@ import mime from "mime";
|
||||||
|
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import { response } from "express";
|
import { response } from "express";
|
||||||
|
import createApiClientWhatsOfficial from "./WhatsappOfficialAPI";
|
||||||
|
|
||||||
const writeFileAsync = promisify(writeFile);
|
const writeFileAsync = promisify(writeFile);
|
||||||
|
|
||||||
async function receiveWhatsAppMediaOfficialAPI(
|
async function receiveWhatsAppMediaOfficialAPI(
|
||||||
mediaId: string,
|
mediaId: string,
|
||||||
phoneNumberId: string
|
phoneNumberId: string,
|
||||||
|
whatsappOfficialToken: string
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
const whatsappOfficialAPI = createApiClientWhatsOfficial(
|
||||||
|
whatsappOfficialToken
|
||||||
|
);
|
||||||
|
|
||||||
const { data } = await whatsappOfficialAPI.get(
|
const { data } = await whatsappOfficialAPI.get(
|
||||||
`/${process.env.VERSION}/${mediaId}?phone_number_id=${phoneNumberId}`
|
`/${process.env.VERSION}/${mediaId}?phone_number_id=${phoneNumberId}`
|
||||||
);
|
);
|
||||||
|
@ -33,7 +38,7 @@ async function receiveWhatsAppMediaOfficialAPI(
|
||||||
if (data && data?.url) {
|
if (data && data?.url) {
|
||||||
const config: any = {
|
const config: any = {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${process.env.TOKEN}`
|
Authorization: `Bearer ${whatsappOfficialToken}`
|
||||||
},
|
},
|
||||||
responseType: "arraybuffer"
|
responseType: "arraybuffer"
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,6 +6,13 @@ type WhatsappData = {
|
||||||
contactId: string;
|
contactId: string;
|
||||||
identifier: string;
|
identifier: string;
|
||||||
value?: string;
|
value?: string;
|
||||||
|
history?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type getData = {
|
||||||
|
key: string;
|
||||||
|
value?: string;
|
||||||
|
parse?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function set(key: string, value: string | object) {
|
export async function set(key: string, value: string | object) {
|
||||||
|
@ -15,21 +22,40 @@ export async function set(key: string, value: string | object) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function get(key: string, value?: string) {
|
export async function getSimple(key: string) {
|
||||||
|
const value: any = await redis.get(key);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function get({ key, value, parse }: getData) {
|
||||||
if (key.includes("*")) {
|
if (key.includes("*")) {
|
||||||
const keys = await redis.keys(key);
|
const keys = await redis.keys(key);
|
||||||
|
|
||||||
// If there are keys, delete them
|
|
||||||
if (keys.length > 0) {
|
if (keys.length > 0) {
|
||||||
|
if (value) {
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
const val = await redis.get(key);
|
const val = await redis.get(key);
|
||||||
if (value == val) return value;
|
if (val.includes(value)) {
|
||||||
|
if (parse) return JSON.parse(val);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let res: any[] = [];
|
||||||
|
for (const key of keys) {
|
||||||
|
const val = await redis.get(key);
|
||||||
|
if (parse) res.push(JSON.parse(val));
|
||||||
|
res.push(val);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
const value: any = await redis.get(key);
|
const value: any = await redis.get(key);
|
||||||
return JSON.parse(value);
|
|
||||||
|
if (parse) return JSON.parse(value);
|
||||||
|
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +70,7 @@ export async function clearAllKeys(...keys: string[]) {
|
||||||
|
|
||||||
// If there are keys, delete them
|
// If there are keys, delete them
|
||||||
if (del_keys.length > 0) {
|
if (del_keys.length > 0) {
|
||||||
console.log("del_keys: ", del_keys);
|
// console.log("del_keys: ", del_keys);
|
||||||
await redis.del(...del_keys);
|
await redis.del(...del_keys);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,7 +109,8 @@ export async function createObject({
|
||||||
whatsappId,
|
whatsappId,
|
||||||
contactId,
|
contactId,
|
||||||
identifier,
|
identifier,
|
||||||
value
|
value,
|
||||||
|
history = ""
|
||||||
}: WhatsappData) {
|
}: WhatsappData) {
|
||||||
const key = `whatsappId:${whatsappId}:contactId:${contactId}:identifier:${identifier}`;
|
const key = `whatsappId:${whatsappId}:contactId:${contactId}:identifier:${identifier}`;
|
||||||
const result = await redis.hmset(
|
const result = await redis.hmset(
|
||||||
|
@ -95,7 +122,9 @@ export async function createObject({
|
||||||
"identifier",
|
"identifier",
|
||||||
identifier,
|
identifier,
|
||||||
"value",
|
"value",
|
||||||
value
|
value,
|
||||||
|
"history",
|
||||||
|
history
|
||||||
);
|
);
|
||||||
|
|
||||||
await redis.expire(key, 300);
|
await redis.expire(key, 300);
|
||||||
|
@ -123,7 +152,8 @@ export async function findObject(
|
||||||
"whatsappId",
|
"whatsappId",
|
||||||
"contactId",
|
"contactId",
|
||||||
"identifier",
|
"identifier",
|
||||||
"value"
|
"value",
|
||||||
|
"history"
|
||||||
);
|
);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -190,3 +220,5 @@ export async function getHashesWithPattern(
|
||||||
|
|
||||||
return hashes;
|
return hashes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -104,16 +104,16 @@ const monitor = async () => {
|
||||||
stdout = stdout[1].trim().split(/\s+/);
|
stdout = stdout[1].trim().split(/\s+/);
|
||||||
|
|
||||||
// DISK SPACE MONITORING
|
// DISK SPACE MONITORING
|
||||||
const io = getIO();
|
// const io = getIO();
|
||||||
io.emit("diskSpaceMonit", {
|
// io.emit("diskSpaceMonit", {
|
||||||
action: "update",
|
// action: "update",
|
||||||
diskSpace: {
|
// diskSpace: {
|
||||||
size: stdout[1],
|
// size: stdout[1],
|
||||||
used: stdout[2],
|
// used: stdout[2],
|
||||||
available: stdout[3],
|
// available: stdout[3],
|
||||||
use: stdout[4]
|
// use: stdout[4]
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
let data: any = {};
|
let data: any = {};
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,8 @@ import User from "../models/User";
|
||||||
interface SerializedUser {
|
interface SerializedUser {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
positionCompany: string;
|
positionId: string | number;
|
||||||
|
position: object;
|
||||||
email: string;
|
email: string;
|
||||||
profile: string;
|
profile: string;
|
||||||
queues: Queue[];
|
queues: Queue[];
|
||||||
|
@ -14,9 +15,11 @@ export const SerializeUser = (user: User): SerializedUser => {
|
||||||
return {
|
return {
|
||||||
id: user.id,
|
id: user.id,
|
||||||
name: user.name,
|
name: user.name,
|
||||||
positionCompany: user.positionCompany,
|
positionId: user.positionId,
|
||||||
|
position: user.position,
|
||||||
email: user.email,
|
email: user.email,
|
||||||
profile: user.profile,
|
profile: user.profile,
|
||||||
queues: user.queues
|
queues: user.queues,
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,8 +5,6 @@ import Ticket from "../models/Ticket";
|
||||||
import Whatsapp from "../models/Whatsapp";
|
import Whatsapp from "../models/Whatsapp";
|
||||||
import endPointQuery from "./old_EndPointQuery";
|
import endPointQuery from "./old_EndPointQuery";
|
||||||
|
|
||||||
import whatsappOfficialAPI from "./WhatsappOfficialAPI";
|
|
||||||
|
|
||||||
export async function setMessageAsRead(ticket: Ticket) {
|
export async function setMessageAsRead(ticket: Ticket) {
|
||||||
if (ticket?.phoneNumberId) {
|
if (ticket?.phoneNumberId) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -62,21 +62,8 @@ const isWeekend = async (number: string | number) => {
|
||||||
weekend.value == "enabled" &&
|
weekend.value == "enabled" &&
|
||||||
weekend.message?.trim()?.length > 0
|
weekend.message?.trim()?.length > 0
|
||||||
) {
|
) {
|
||||||
// Specify your desired timezone
|
|
||||||
const brazilTimeZone = "America/Sao_Paulo";
|
|
||||||
|
|
||||||
const currentDateUtc = new Date();
|
|
||||||
|
|
||||||
// Convert UTC date to Brazil time zone
|
|
||||||
const currentDate = utcToZonedTime(currentDateUtc, brazilTimeZone);
|
|
||||||
|
|
||||||
// Format the date using the desired format
|
|
||||||
const formattedDate = _format(currentDate, "yyyy-MM-dd HH:mm:ssXXX");
|
|
||||||
|
|
||||||
const parsedDate = parseISO(formattedDate);
|
|
||||||
|
|
||||||
// Convert parsed date to Brazil time zone
|
// Convert parsed date to Brazil time zone
|
||||||
const localDate = utcToZonedTime(parsedDate, brazilTimeZone);
|
const localDate = localDateConvert();
|
||||||
|
|
||||||
// Check if it's Saturday or Sunday
|
// Check if it's Saturday or Sunday
|
||||||
if (isSaturday(localDate)) {
|
if (isSaturday(localDate)) {
|
||||||
|
@ -173,8 +160,104 @@ async function isOutBusinessTime(number: string | number) {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
async function isOutBusinessTimeSaturday(number: string | number) {
|
||||||
isWeekend,
|
let obj = { set: false, msg: "" };
|
||||||
isHoliday,
|
|
||||||
isOutBusinessTime
|
// Convert parsed date to Brazil time zone
|
||||||
};
|
const localDate = localDateConvert();
|
||||||
|
|
||||||
|
// Check if it's Saturday or Sunday
|
||||||
|
if (!isSaturday(localDate)) {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
const outBusinessHoursSaturday = await SettingTicket.findOne({
|
||||||
|
where: { key: "saturdayBusinessTime", number }
|
||||||
|
});
|
||||||
|
|
||||||
|
let isWithinRange = false;
|
||||||
|
|
||||||
|
if (
|
||||||
|
outBusinessHoursSaturday &&
|
||||||
|
outBusinessHoursSaturday.value == "enabled" &&
|
||||||
|
outBusinessHoursSaturday?.message?.trim()?.length > 0
|
||||||
|
) {
|
||||||
|
const ticketDateTimeUpdate = splitDateTime(
|
||||||
|
new Date(
|
||||||
|
_format(new Date(), "yyyy-MM-dd HH:mm:ss", {
|
||||||
|
locale: ptBR
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const startTime = splitDateTime(
|
||||||
|
new Date(
|
||||||
|
_format(
|
||||||
|
new Date(outBusinessHoursSaturday.startTime),
|
||||||
|
"yyyy-MM-dd HH:mm:ss",
|
||||||
|
{
|
||||||
|
locale: ptBR
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const endTime = splitDateTime(
|
||||||
|
new Date(
|
||||||
|
_format(
|
||||||
|
new Date(outBusinessHoursSaturday.endTime),
|
||||||
|
"yyyy-MM-dd HH:mm:ss",
|
||||||
|
{
|
||||||
|
locale: ptBR
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const format = "HH:mm:ss";
|
||||||
|
const parsedStartTime = parse(
|
||||||
|
ticketDateTimeUpdate.fullTime,
|
||||||
|
format,
|
||||||
|
new Date()
|
||||||
|
);
|
||||||
|
const parsedEndTime = parse(startTime.fullTime, format, new Date());
|
||||||
|
const parsedTimeToCheck = parse(endTime.fullTime, format, new Date());
|
||||||
|
const timeInterval = { start: parsedStartTime, end: parsedEndTime };
|
||||||
|
|
||||||
|
// If the time range spans across different days, handle the date part
|
||||||
|
if (parsedEndTime < parsedStartTime) {
|
||||||
|
const nextDay = new Date(parsedStartTime);
|
||||||
|
nextDay.setDate(nextDay.getDate() + 1);
|
||||||
|
timeInterval.end = nextDay;
|
||||||
|
}
|
||||||
|
|
||||||
|
isWithinRange = isWithinInterval(parsedTimeToCheck, timeInterval);
|
||||||
|
|
||||||
|
if (!isWithinRange) {
|
||||||
|
obj.set = true;
|
||||||
|
obj.msg = outBusinessHoursSaturday.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
function localDateConvert() {
|
||||||
|
const brazilTimeZone = "America/Sao_Paulo";
|
||||||
|
|
||||||
|
const currentDateUtc = new Date();
|
||||||
|
|
||||||
|
// Convert UTC date to Brazil time zone
|
||||||
|
const currentDate = utcToZonedTime(currentDateUtc, brazilTimeZone);
|
||||||
|
|
||||||
|
// Format the date using the desired format
|
||||||
|
const formattedDate = _format(currentDate, "yyyy-MM-dd HH:mm:ssXXX");
|
||||||
|
|
||||||
|
const parsedDate = parseISO(formattedDate);
|
||||||
|
|
||||||
|
// Convert parsed date to Brazil time zone
|
||||||
|
const localDate = utcToZonedTime(parsedDate, brazilTimeZone);
|
||||||
|
return localDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { isWeekend, isHoliday, isOutBusinessTime, isOutBusinessTimeSaturday };
|
||||||
|
|
|
@ -1,11 +1,30 @@
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import https from "https"
|
||||||
|
import http from "http"
|
||||||
|
|
||||||
const api = axios.create({
|
|
||||||
|
// const api = axios.create({
|
||||||
|
// baseURL: process.env.URL_WHATSAPP_API,
|
||||||
|
// headers: {
|
||||||
|
// Accept: "application/json",
|
||||||
|
// Authorization: `Bearer ${process.env.TOKEN}`
|
||||||
|
// },
|
||||||
|
// httpAgent: new http.Agent({ keepAlive: true }),
|
||||||
|
// httpsAgent: new https.Agent({ keepAlive: true })
|
||||||
|
// });
|
||||||
|
|
||||||
|
// export default api;
|
||||||
|
|
||||||
|
const createApiClientWhatsOfficial = (token: string) => {
|
||||||
|
return axios.create({
|
||||||
baseURL: process.env.URL_WHATSAPP_API,
|
baseURL: process.env.URL_WHATSAPP_API,
|
||||||
headers: {
|
headers: {
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
Authorization: `Bearer ${process.env.TOKEN}`
|
Authorization: `Bearer ${token}`
|
||||||
}
|
},
|
||||||
|
httpAgent: new http.Agent({ keepAlive: true }),
|
||||||
|
httpsAgent: new https.Agent({ keepAlive: true })
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export default api;
|
export default createApiClientWhatsOfficial;
|
||||||
|
|
|
@ -1,7 +1,15 @@
|
||||||
import whatsappOfficialAPI from "./WhatsappOfficialAPI";
|
import Whatsapp from "../models/Whatsapp";
|
||||||
|
import createApiClientWhatsOfficial from "./WhatsappOfficialAPI";
|
||||||
|
|
||||||
async function whatsappOfficialNumberInfo(wabaId: string) {
|
async function whatsappOfficialNumberInfo(wabaId: string) {
|
||||||
try {
|
try {
|
||||||
|
const { whatsappOfficialToken }: any = await Whatsapp.findOne({
|
||||||
|
where: { wabaId }
|
||||||
|
});
|
||||||
|
|
||||||
|
const whatsappOfficialAPI = createApiClientWhatsOfficial(
|
||||||
|
whatsappOfficialToken
|
||||||
|
);
|
||||||
const { data } = await whatsappOfficialAPI.get(
|
const { data } = await whatsappOfficialAPI.get(
|
||||||
`/${process.env.VERSION}/${wabaId}/phone_numbers`
|
`/${process.env.VERSION}/${wabaId}/phone_numbers`
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { values } from "sequelize/types/lib/operators";
|
||||||
|
import Ticket from "../models/Ticket";
|
||||||
|
import { get, set } from "./RedisClient";
|
||||||
|
import { getIO } from "../libs/socket";
|
||||||
|
import UpdateTicketService from "../services/TicketServices/UpdateTicketService";
|
||||||
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
|
||||||
|
async function controllByNumber() {
|
||||||
|
let tickets = await get({ key: "remote:ticketId*", parse: false });
|
||||||
|
|
||||||
|
if (!tickets) return { ticketIds: [], tickets: null };
|
||||||
|
|
||||||
|
let controll: any[] = [];
|
||||||
|
|
||||||
|
for (const ticket of tickets) {
|
||||||
|
let match = ticket?.match(/"whatsappId":(\d+)/);
|
||||||
|
let whatsappId = match ? match[1] : null;
|
||||||
|
|
||||||
|
const whatsapp = await get({
|
||||||
|
key: `whatsapp:${whatsappId}`
|
||||||
|
});
|
||||||
|
|
||||||
|
match = whatsapp?.match(/"number":"(\d+)"/);
|
||||||
|
let number = match ? match[1] : null;
|
||||||
|
|
||||||
|
match = ticket?.match(/"id":(\d+)/);
|
||||||
|
let ticketId = match ? match[1] : null;
|
||||||
|
|
||||||
|
number = JSON.parse(number);
|
||||||
|
ticketId = JSON.parse(ticketId);
|
||||||
|
|
||||||
|
const index = controll?.findIndex((c: any) => c.number == number);
|
||||||
|
|
||||||
|
if (index == -1) {
|
||||||
|
controll?.push({ ticketId, number });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ticketIds = controll?.map((c: any) => c.ticketId);
|
||||||
|
|
||||||
|
//console.log("=======> ticketIds: ", ticketIds);
|
||||||
|
|
||||||
|
for (const ticketId of ticketIds) {
|
||||||
|
const ticket: any = await Ticket.findByPk(ticketId);
|
||||||
|
if(ticket){
|
||||||
|
const { status } = ticket;
|
||||||
|
|
||||||
|
if (status && status == "pending") {
|
||||||
|
await UpdateTicketService({
|
||||||
|
ticketData: { statusChatEnd: uuidv4() },
|
||||||
|
ticketId: ticket.id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set(`remote:controll`, JSON.stringify(ticketIds));
|
||||||
|
|
||||||
|
return { ticketIds, tickets };
|
||||||
|
}
|
||||||
|
|
||||||
|
export default controllByNumber;
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { where } from "sequelize";
|
||||||
import { getIO } from "../libs/socket";
|
import { getIO } from "../libs/socket";
|
||||||
import Contact from "../models/Contact";
|
import Contact from "../models/Contact";
|
||||||
import Ticket from "../models/Ticket";
|
import Ticket from "../models/Ticket";
|
||||||
|
@ -5,8 +6,9 @@ import {
|
||||||
isValidMsg,
|
isValidMsg,
|
||||||
verifyMessage
|
verifyMessage
|
||||||
} from "../services/WbotServices/wbotMessageListener";
|
} from "../services/WbotServices/wbotMessageListener";
|
||||||
|
import { get } from "./RedisClient";
|
||||||
import whatsappOfficialAPI from "./WhatsappOfficialAPI";
|
import createApiClientWhatsOfficial from "./WhatsappOfficialAPI";
|
||||||
|
import Whatsapp from "../models/Whatsapp";
|
||||||
|
|
||||||
async function sendWhatsAppMessageOfficialAPI(
|
async function sendWhatsAppMessageOfficialAPI(
|
||||||
ticket: Ticket,
|
ticket: Ticket,
|
||||||
|
@ -52,7 +54,14 @@ async function sendWhatsAppMessageOfficialAPI(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { whatsappOfficialToken }: any = await Whatsapp.findOne({
|
||||||
|
where: { phoneNumberId }
|
||||||
|
});
|
||||||
|
|
||||||
console.log("SEND MESSAGE: ", JSON.stringify(data, null, 2));
|
console.log("SEND MESSAGE: ", JSON.stringify(data, null, 2));
|
||||||
|
const whatsappOfficialAPI = createApiClientWhatsOfficial(
|
||||||
|
whatsappOfficialToken
|
||||||
|
);
|
||||||
|
|
||||||
whatsappOfficialAPI
|
whatsappOfficialAPI
|
||||||
.post(`/${process.env.VERSION}/${phoneNumberId}/messages`, data)
|
.post(`/${process.env.VERSION}/${phoneNumberId}/messages`, data)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue