feat: Update frontend to display closure statuses, create interface to input user's position for assignment, modify quick responses to be displayed by queues, and add configurations to enable/disable these features. Also, add option to save contacts by queues
parent
5eac253549
commit
bfae2956a5
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -20,11 +20,13 @@ import {
|
|||
} from "../helpers/ContactsCache";
|
||||
|
||||
import { off } from "process";
|
||||
import GetContactService from "../services/ContactServices/GetContactService"
|
||||
import GetContactService from "../services/ContactServices/GetContactService";
|
||||
import ContactQueue from "../models/ContactQueues";
|
||||
|
||||
type IndexQuery = {
|
||||
searchParam: string;
|
||||
pageNumber: string;
|
||||
userId?:string;
|
||||
};
|
||||
|
||||
type IndexGetContactQuery = {
|
||||
|
@ -41,10 +43,11 @@ interface ContactData {
|
|||
number: string;
|
||||
email?: string;
|
||||
extraInfo?: ExtraInfo[];
|
||||
queueIds?: number[];
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -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({
|
||||
searchParam,
|
||||
pageNumber
|
||||
pageNumber,
|
||||
userId
|
||||
});
|
||||
|
||||
return res.json({ contacts, count, hasMore });
|
||||
|
@ -142,7 +144,8 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
|||
number,
|
||||
email,
|
||||
profilePicUrl: profilePicUrl,
|
||||
extraInfo
|
||||
extraInfo,
|
||||
queueIds: newContact?.queueIds
|
||||
});
|
||||
|
||||
const io = getIO();
|
||||
|
@ -208,6 +211,8 @@ export const remove = async (
|
|||
|
||||
await DeleteContactService(contactId);
|
||||
|
||||
await ContactQueue.destroy({ where: { contactId } });
|
||||
|
||||
const io = getIO();
|
||||
io.emit("contact", {
|
||||
action: "delete",
|
||||
|
|
|
@ -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" });
|
||||
};
|
|
@ -11,6 +11,8 @@ 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> => {
|
||||
const queues = await ListQueuesService();
|
||||
|
@ -71,9 +73,15 @@ export const listQueues = async (
|
|||
};
|
||||
|
||||
export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||
const { name, color, greetingMessage, cc } = req.body;
|
||||
const { name, color, greetingMessage, farewellMessage, cc } = req.body;
|
||||
|
||||
const queue = await CreateQueueService({ name, color, greetingMessage, cc });
|
||||
const queue = await CreateQueueService({
|
||||
name,
|
||||
color,
|
||||
greetingMessage,
|
||||
cc,
|
||||
farewellMessage
|
||||
});
|
||||
|
||||
const io = getIO();
|
||||
io.emit("queue", {
|
||||
|
@ -115,43 +123,43 @@ export const customization = async (
|
|||
if (new_queues && new_queues.length > 0) {
|
||||
const db_queues: any = await Queue.findAll();
|
||||
|
||||
for (const i in new_queues) {
|
||||
let { queueName: name, color, greetingMessage } = new_queues[i];
|
||||
// for (const i in new_queues) {
|
||||
// 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(
|
||||
(q: any) => q.name?.trim()?.replace(/\s+/g, " ") == name
|
||||
);
|
||||
// const update = db_queues.find(
|
||||
// (q: any) => q.name?.trim()?.replace(/\s+/g, " ") == name
|
||||
// );
|
||||
|
||||
if (update) {
|
||||
const { id } = update;
|
||||
// UPDATE
|
||||
// const queue = await UpdateQueueService(id, {
|
||||
// name,
|
||||
// color,
|
||||
// greetingMessage
|
||||
// });
|
||||
// if (update) {
|
||||
// const { id } = update;
|
||||
// // UPDATE
|
||||
// // const queue = await UpdateQueueService(id, {
|
||||
// // name,
|
||||
// // color,
|
||||
// // greetingMessage
|
||||
// // });
|
||||
|
||||
// const io = getIO();
|
||||
// io.emit("queue", {
|
||||
// action: "update",
|
||||
// queue
|
||||
// });
|
||||
} else {
|
||||
// CREATE
|
||||
// const queue = await CreateQueueService({
|
||||
// name,
|
||||
// color,
|
||||
// greetingMessage
|
||||
// });
|
||||
// const io = getIO();
|
||||
// io.emit("queue", {
|
||||
// action: "update",
|
||||
// queue
|
||||
// });
|
||||
}
|
||||
}
|
||||
// // const io = getIO();
|
||||
// // io.emit("queue", {
|
||||
// // action: "update",
|
||||
// // queue
|
||||
// // });
|
||||
// } else {
|
||||
// // CREATE
|
||||
// // const queue = await CreateQueueService({
|
||||
// // name,
|
||||
// // color,
|
||||
// // greetingMessage
|
||||
// // });
|
||||
// // const io = getIO();
|
||||
// // io.emit("queue", {
|
||||
// // action: "update",
|
||||
// // queue
|
||||
// // });
|
||||
// }
|
||||
// }
|
||||
|
||||
let remove_queues = db_queues.filter(
|
||||
(q: any) =>
|
||||
|
@ -217,6 +225,9 @@ export const remove = async (
|
|||
|
||||
await DeleteQueueService(queueId);
|
||||
|
||||
await QuickAnswerQueue.destroy({ where: { queueId } });
|
||||
await ContactQueue.destroy({ where: { queueId } });
|
||||
|
||||
await del(`queue:${queueId}`);
|
||||
|
||||
const io = getIO();
|
||||
|
|
|
@ -9,23 +9,27 @@ import UpdateQuickAnswerService from "../services/QuickAnswerService/UpdateQuick
|
|||
import DeleteQuickAnswerService from "../services/QuickAnswerService/DeleteQuickAnswerService";
|
||||
|
||||
import AppError from "../errors/AppError";
|
||||
import QuickAnswerQueue from "../models/QuickAnswerQueue";
|
||||
|
||||
type IndexQuery = {
|
||||
searchParam: string;
|
||||
pageNumber: string;
|
||||
userId?: string;
|
||||
};
|
||||
|
||||
interface QuickAnswerData {
|
||||
shortcut: string;
|
||||
message: string;
|
||||
queueIds?: number[];
|
||||
}
|
||||
|
||||
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({
|
||||
searchParam,
|
||||
pageNumber
|
||||
pageNumber,
|
||||
userId
|
||||
});
|
||||
|
||||
return res.json({ quickAnswers, count, hasMore });
|
||||
|
@ -41,7 +45,7 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
|||
|
||||
try {
|
||||
await QuickAnswerSchema.validate(newQuickAnswer);
|
||||
} catch (err:any) {
|
||||
} catch (err: any) {
|
||||
throw new AppError(err.message);
|
||||
}
|
||||
|
||||
|
@ -59,9 +63,9 @@ export const store = 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);
|
||||
};
|
||||
|
@ -103,10 +107,12 @@ export const remove = async (
|
|||
req: Request,
|
||||
res: Response
|
||||
): Promise<Response> => {
|
||||
const { quickAnswerId } = req.params;
|
||||
const { quickAnswerId, queueId } = req.params;
|
||||
|
||||
await DeleteQuickAnswerService(quickAnswerId);
|
||||
|
||||
await QuickAnswerQueue.destroy({ where: { quickAnswerId } });
|
||||
|
||||
const io = getIO();
|
||||
io.emit("quickAnswer", {
|
||||
action: "delete",
|
||||
|
|
|
@ -6,7 +6,7 @@ import ListSchedulingNotifyContactService from "../services/SchedulingNotifyServ
|
|||
import CreateSchedulingNotifyService from "../services/SchedulingNotifyServices/CreateSchedulingNotifyService";
|
||||
import ShowSchedulingNotifyService from "../services/SchedulingNotifyServices/ShowSchedulingNotifyService";
|
||||
import { deleteScheduleByTicketIdCache } from "../helpers/SchedulingNotifyCache";
|
||||
|
||||
import ShowStatusChatEndService from "../services/StatusChatEndService/ShowStatusChatEndService";
|
||||
|
||||
type IndexQuery = {
|
||||
contactNumber: string;
|
||||
|
@ -14,58 +14,58 @@ type IndexQuery = {
|
|||
endDate: string;
|
||||
};
|
||||
|
||||
export const reportScheduleNotifyByDateStartDateEnd = async (
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<Response> => {
|
||||
const { contactNumber, startDate, endDate } = req.query as IndexQuery;
|
||||
|
||||
|
||||
export const reportScheduleNotifyByDateStartDateEnd = async (req: Request, res: Response): Promise<Response> => {
|
||||
|
||||
const { contactNumber, startDate, endDate } = req.query as IndexQuery
|
||||
|
||||
const data_query = await ListSchedulingNotifyContactService(contactNumber, startDate, endDate);
|
||||
|
||||
// console.group('DATA QUERY SCHEDULE:\n',data_query)
|
||||
const data_query = await ListSchedulingNotifyContactService(
|
||||
contactNumber,
|
||||
startDate,
|
||||
endDate
|
||||
);
|
||||
|
||||
return res.status(200).json(data_query);
|
||||
|
||||
};
|
||||
|
||||
|
||||
export const createOrUpdateScheduleNotify = async (req: Request, res: Response): Promise<Response> => {
|
||||
|
||||
export const createOrUpdateScheduleNotify = async (
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<Response> => {
|
||||
const scheduleData = req.body;
|
||||
|
||||
const statusChatEnd = await ShowStatusChatEndService({
|
||||
name: scheduleData.statusChatEndName
|
||||
});
|
||||
|
||||
|
||||
const schedulingNotifyCreate = await CreateSchedulingNotifyService(
|
||||
{
|
||||
const schedulingNotifyCreate = await CreateSchedulingNotifyService({
|
||||
schedulingNotifyId: scheduleData.schedulingNotifyId,
|
||||
ticketId: scheduleData.ticketId,
|
||||
statusChatEndId: scheduleData.statusChatEndId,
|
||||
statusChatEndId: statusChatEnd.id,
|
||||
schedulingDate: scheduleData.schedulingDate,
|
||||
schedulingTime: scheduleData.schedulingTime,
|
||||
message: scheduleData.message
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
// console.group(':::::::::::::::::: DATA schedulingNotifyCreate:\n',schedulingNotifyCreate)
|
||||
// const io = getIO();
|
||||
// io.emit("schedulingNotify", {action: "update", 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;
|
||||
|
||||
let schedule: any = await ShowSchedulingNotifyService(scheduleId)
|
||||
let schedule: any = await ShowSchedulingNotifyService(scheduleId);
|
||||
|
||||
await deleteScheduleByTicketIdCache(schedule.ticketId)
|
||||
await deleteScheduleByTicketIdCache(schedule.ticketId);
|
||||
|
||||
await DeleteSchedulingNotifyService(scheduleId);
|
||||
|
||||
return res.status(200).send();
|
||||
};
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
|||
|
||||
const settings = await ListSettingsService();
|
||||
|
||||
// const config = await SettingTicket.findAll();
|
||||
|
||||
return res.status(200).json({ settings });
|
||||
};
|
||||
|
||||
|
|
|
@ -1,12 +1,131 @@
|
|||
import { Request, Response } from "express";
|
||||
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 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> => {
|
||||
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);
|
||||
};
|
||||
|
||||
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" });
|
||||
};
|
||||
|
|
|
@ -78,6 +78,7 @@ import WhatsappQueue from "../models/WhatsappQueue";
|
|||
import { get } from "../helpers/RedisClient";
|
||||
import CountStatusChatEndService from "../services/StatusChatEndService/CountStatusChatEndService";
|
||||
import Queue from "../models/Queue";
|
||||
import StatusChatEnd from "../models/StatusChatEnd";
|
||||
|
||||
export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||
const {
|
||||
|
@ -196,7 +197,7 @@ export const remoteTicketCreation = async (
|
|||
|
||||
const whatsapps = await ListWhatsAppsForQueueService(queueId, "CONNECTED");
|
||||
|
||||
if ( whatsapps.length === 0) {
|
||||
if (whatsapps.length === 0) {
|
||||
return res.status(500).json({
|
||||
msg: `No WhatsApp found for this cc ${cc} or the WhatsApp number is disconnected! `
|
||||
});
|
||||
|
@ -385,35 +386,75 @@ export const update = async (
|
|||
// lembrete
|
||||
const scheduleData = JSON.parse(schedulingNotifyData);
|
||||
|
||||
const statusChatEndName = await ShowStatusChatEndService(
|
||||
scheduleData.statusChatEndId
|
||||
);
|
||||
console.log("scheduleData: ", scheduleData);
|
||||
|
||||
const statusChatEnd = await ShowStatusChatEndService({
|
||||
name: scheduleData.statusChatEndName
|
||||
});
|
||||
|
||||
const { ticket } = await UpdateTicketService({
|
||||
ticketData: {
|
||||
status: status,
|
||||
userId: userId,
|
||||
statusChatEnd: statusChatEndName.name,
|
||||
statusChatEndId: statusChatEndName.id
|
||||
statusChatEnd: statusChatEnd.name,
|
||||
statusChatEndId: statusChatEnd.id
|
||||
},
|
||||
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 { farewellMessage } = whatsapp;
|
||||
|
||||
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 (
|
||||
scheduleData.statusChatEndId === "2" ||
|
||||
scheduleData.statusChatEndId === "3"
|
||||
statusChatEnd.name === "LEMBRETE" ||
|
||||
statusChatEnd.name === "AGENDAMENTO À CONFIRMAR"
|
||||
) {
|
||||
// lembrete // agendamento
|
||||
if (
|
||||
isScheduling(scheduleData.schedulingDate, scheduleData.schedulingTime)
|
||||
) {
|
||||
|
@ -424,7 +465,7 @@ export const update = async (
|
|||
|
||||
const schedulingNotifyCreate = await CreateSchedulingNotifyService({
|
||||
ticketId: scheduleData.ticketId,
|
||||
statusChatEndId: scheduleData.statusChatEndId,
|
||||
statusChatEndId: `${statusChatEnd.id}`,
|
||||
schedulingDate: scheduleData.schedulingDate,
|
||||
schedulingTime: scheduleData.schedulingTime,
|
||||
message: scheduleData.message
|
||||
|
|
|
@ -138,8 +138,15 @@ export const all = async (req: Request, res: Response): Promise<Response> => {
|
|||
};
|
||||
|
||||
export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||
const { email, password, name, profile, positionCompany, queueIds } =
|
||||
req.body;
|
||||
const {
|
||||
email,
|
||||
password,
|
||||
name,
|
||||
profile,
|
||||
positionCompany,
|
||||
positionId,
|
||||
queueIds
|
||||
} = req.body;
|
||||
|
||||
console.log("===========> req.url: ", req.url);
|
||||
|
||||
|
@ -163,6 +170,7 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
|||
password,
|
||||
name,
|
||||
positionCompany,
|
||||
positionId,
|
||||
profile,
|
||||
queueIds
|
||||
});
|
||||
|
|
|
@ -15,6 +15,9 @@ import SchedulingNotify from "../models/SchedulingNotify";
|
|||
import StatusChatEnd from "../models/StatusChatEnd";
|
||||
import UserOnlineTime from "../models/UserOnlineTime";
|
||||
import SettingTicket from "../models/SettingTicket";
|
||||
import QuickAnswerQueue from "../models/QuickAnswerQueue";
|
||||
import Position from "../models/Position"
|
||||
import ContactQueue from "../models/ContactQueues"
|
||||
// eslint-disable-next-line
|
||||
const dbConfig = require("../config/database");
|
||||
// import dbConfig from "../config/database";
|
||||
|
@ -33,11 +36,13 @@ const models = [
|
|||
WhatsappQueue,
|
||||
UserQueue,
|
||||
QuickAnswer,
|
||||
|
||||
QuickAnswerQueue,
|
||||
SchedulingNotify,
|
||||
StatusChatEnd,
|
||||
UserOnlineTime,
|
||||
SettingTicket
|
||||
SettingTicket,
|
||||
Position,
|
||||
ContactQueue
|
||||
];
|
||||
|
||||
sequelize.addModels(models);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
};
|
|
@ -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,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: "filterMediasByType",
|
||||
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,25 @@
|
|||
import QuickAnswer from "../models/QuickAnswer";
|
||||
|
||||
export default function quickAnswearByQueueFiltered(
|
||||
queueIds: any[],
|
||||
quickAnswers: QuickAnswer[]
|
||||
) {
|
||||
let auxQuickAnswear = [];
|
||||
const userQueues = queueIds.map((uq: any) => uq.queueId);
|
||||
|
||||
for (const quickAnswer of quickAnswers) {
|
||||
const { queues } = quickAnswer;
|
||||
|
||||
if (queues.length == 0) {
|
||||
auxQuickAnswear.push(quickAnswer);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const q of queues) {
|
||||
if (userQueues.includes(q.id)) {
|
||||
auxQuickAnswear.push(quickAnswer);
|
||||
}
|
||||
}
|
||||
}
|
||||
return auxQuickAnswear;
|
||||
}
|
|
@ -5,6 +5,8 @@ interface SerializedUser {
|
|||
id: number;
|
||||
name: string;
|
||||
positionCompany: string;
|
||||
positionId: string | number;
|
||||
position: object;
|
||||
email: string;
|
||||
profile: string;
|
||||
queues: Queue[];
|
||||
|
@ -15,8 +17,11 @@ export const SerializeUser = (user: User): SerializedUser => {
|
|||
id: user.id,
|
||||
name: user.name,
|
||||
positionCompany: user.positionCompany,
|
||||
positionId: user.positionId,
|
||||
position: user.position,
|
||||
email: user.email,
|
||||
profile: user.profile,
|
||||
queues: user.queues
|
||||
queues: user.queues,
|
||||
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
import axios from "axios";
|
||||
import https from "https"
|
||||
import http from "http"
|
||||
|
||||
|
||||
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;
|
||||
|
|
|
@ -9,10 +9,13 @@ import {
|
|||
AllowNull,
|
||||
Unique,
|
||||
Default,
|
||||
HasMany
|
||||
HasMany,
|
||||
BelongsToMany
|
||||
} from "sequelize-typescript";
|
||||
import ContactCustomField from "./ContactCustomField";
|
||||
import Ticket from "./Ticket";
|
||||
import Queue from "./Queue"
|
||||
import ContactQueue from "./ContactQueues"
|
||||
|
||||
@Table
|
||||
class Contact extends Model<Contact> {
|
||||
|
@ -52,6 +55,12 @@ class Contact extends Model<Contact> {
|
|||
|
||||
@HasMany(() => ContactCustomField)
|
||||
extraInfo: ContactCustomField[];
|
||||
|
||||
@BelongsToMany(() => Queue, () => ContactQueue)
|
||||
queues: Array<Queue & { WhatsappQueue: ContactQueue }>;
|
||||
|
||||
@HasMany(() => ContactQueue)
|
||||
contactQueue: ContactQueue[];
|
||||
}
|
||||
|
||||
export default Contact;
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
import {
|
||||
Table,
|
||||
Column,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
Model,
|
||||
ForeignKey,
|
||||
BelongsTo
|
||||
} from "sequelize-typescript";
|
||||
import Queue from "./Queue";
|
||||
import Contact from "./Contact"
|
||||
|
||||
@Table
|
||||
class ContactQueue extends Model<ContactQueue> {
|
||||
@ForeignKey(() => Contact)
|
||||
@Column
|
||||
contactId: number;
|
||||
|
||||
@ForeignKey(() => Queue)
|
||||
@Column
|
||||
queueId: number;
|
||||
|
||||
@CreatedAt
|
||||
createdAt: Date;
|
||||
|
||||
@UpdatedAt
|
||||
updatedAt: Date;
|
||||
|
||||
@BelongsTo(() => Queue)
|
||||
queue: Queue;
|
||||
}
|
||||
|
||||
export default ContactQueue;
|
|
@ -0,0 +1,48 @@
|
|||
import {
|
||||
Table,
|
||||
Column,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
Model,
|
||||
PrimaryKey,
|
||||
ForeignKey,
|
||||
BelongsTo,
|
||||
HasMany,
|
||||
HasOne,
|
||||
AutoIncrement,
|
||||
Default,
|
||||
DataType,
|
||||
Unique
|
||||
} from "sequelize-typescript";
|
||||
|
||||
import Contact from "./Contact";
|
||||
import Message from "./Message";
|
||||
import Queue from "./Queue";
|
||||
import User from "./User";
|
||||
import Whatsapp from "./Whatsapp";
|
||||
|
||||
import SchedulingNotify from "./SchedulingNotify";
|
||||
import StatusChatEnd from "./StatusChatEnd";
|
||||
|
||||
@Table
|
||||
class Position extends Model<Position> {
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
id: number;
|
||||
|
||||
@Unique
|
||||
@Column(DataType.TEXT)
|
||||
name: string;
|
||||
|
||||
@CreatedAt
|
||||
createdAt: Date;
|
||||
|
||||
@UpdatedAt
|
||||
updatedAt: Date;
|
||||
|
||||
@HasMany(() => User)
|
||||
users: User[];
|
||||
}
|
||||
|
||||
export default Position;
|
|
@ -36,6 +36,9 @@ class Queue extends Model<Queue> {
|
|||
@Column
|
||||
greetingMessage: string;
|
||||
|
||||
@Column
|
||||
farewellMessage: string;
|
||||
|
||||
@Column
|
||||
cc: string;
|
||||
|
||||
|
|
|
@ -6,8 +6,12 @@ import {
|
|||
UpdatedAt,
|
||||
Model,
|
||||
PrimaryKey,
|
||||
AutoIncrement
|
||||
AutoIncrement,
|
||||
BelongsToMany,
|
||||
HasMany
|
||||
} from "sequelize-typescript";
|
||||
import Queue from "./Queue";
|
||||
import QuickAnswerQueue from "./QuickAnswerQueue";
|
||||
|
||||
@Table
|
||||
class QuickAnswer extends Model<QuickAnswer> {
|
||||
|
@ -27,6 +31,12 @@ class QuickAnswer extends Model<QuickAnswer> {
|
|||
|
||||
@UpdatedAt
|
||||
updatedAt: Date;
|
||||
|
||||
@BelongsToMany(() => Queue, () => QuickAnswerQueue)
|
||||
queues: Array<Queue & { QuickAnswerQueue: QuickAnswerQueue }>;
|
||||
|
||||
@HasMany(() => QuickAnswerQueue)
|
||||
quickAnswerQueue: QuickAnswerQueue[];
|
||||
}
|
||||
|
||||
export default QuickAnswer;
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import {
|
||||
Table,
|
||||
Column,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
Model,
|
||||
ForeignKey,
|
||||
BelongsTo
|
||||
} from "sequelize-typescript";
|
||||
import Queue from "./Queue";
|
||||
import Whatsapp from "./Whatsapp";
|
||||
import QuickAnswer from "./QuickAnswer"
|
||||
|
||||
@Table
|
||||
class QuickAnswerQueue extends Model<QuickAnswerQueue> {
|
||||
@ForeignKey(() => QuickAnswer)
|
||||
@Column
|
||||
quickAnswerId: number;
|
||||
|
||||
@ForeignKey(() => Queue)
|
||||
@Column
|
||||
queueId: number;
|
||||
|
||||
@CreatedAt
|
||||
createdAt: Date;
|
||||
|
||||
@UpdatedAt
|
||||
updatedAt: Date;
|
||||
|
||||
@BelongsTo(() => Queue)
|
||||
queue: Queue;
|
||||
}
|
||||
|
||||
export default QuickAnswerQueue;
|
|
@ -7,13 +7,13 @@ import {
|
|||
Model,
|
||||
PrimaryKey,
|
||||
HasMany
|
||||
} from "sequelize-typescript";
|
||||
} from "sequelize-typescript";
|
||||
|
||||
import SchedulingNotify from "./SchedulingNotify";
|
||||
import Ticket from "./Ticket"
|
||||
import SchedulingNotify from "./SchedulingNotify";
|
||||
import Ticket from "./Ticket";
|
||||
|
||||
@Table
|
||||
class StatusChatEnd extends Model<StatusChatEnd> {
|
||||
@Table
|
||||
class StatusChatEnd extends Model<StatusChatEnd> {
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
|
@ -22,6 +22,12 @@ import Ticket from "./Ticket"
|
|||
@Column
|
||||
name: string;
|
||||
|
||||
@Column
|
||||
farewellMessage: string;
|
||||
|
||||
@Column
|
||||
isDefault: boolean;
|
||||
|
||||
@CreatedAt
|
||||
createdAt: Date;
|
||||
|
||||
|
@ -33,7 +39,6 @@ import Ticket from "./Ticket"
|
|||
|
||||
@HasMany(() => Ticket)
|
||||
tickets: Ticket[];
|
||||
}
|
||||
|
||||
export default StatusChatEnd;
|
||||
}
|
||||
|
||||
export default StatusChatEnd;
|
||||
|
|
|
@ -12,12 +12,15 @@ import {
|
|||
Default,
|
||||
HasMany,
|
||||
BelongsToMany,
|
||||
BelongsTo,
|
||||
ForeignKey
|
||||
} from "sequelize-typescript";
|
||||
import { hash, compare } from "bcryptjs";
|
||||
import Ticket from "./Ticket";
|
||||
import Queue from "./Queue";
|
||||
import UserQueue from "./UserQueue";
|
||||
import UserOnlineTime from "./UserOnlineTime";
|
||||
import Position from "./Position"
|
||||
|
||||
@Table
|
||||
class User extends Model<User> {
|
||||
|
@ -66,6 +69,13 @@ class User extends Model<User> {
|
|||
@BelongsToMany(() => Queue, () => UserQueue)
|
||||
queues: Queue[];
|
||||
|
||||
@ForeignKey(() => Position)
|
||||
@Column
|
||||
positionId: number;
|
||||
|
||||
@BelongsTo(() => Position)
|
||||
position: Position;
|
||||
|
||||
@BeforeUpdate
|
||||
@BeforeCreate
|
||||
static hashPassword = async (instance: User): Promise<void> => {
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
import express from "express";
|
||||
import isAuth from "../middleware/isAuth";
|
||||
|
||||
import * as PositionController from "../controllers/PositionController";
|
||||
|
||||
const positionRoutes = express.Router();
|
||||
|
||||
positionRoutes.get("/positions", isAuth, PositionController.index);
|
||||
|
||||
positionRoutes.get(
|
||||
"/positions/:positionId",
|
||||
isAuth,
|
||||
PositionController.show
|
||||
);
|
||||
|
||||
positionRoutes.post("/positions", isAuth, PositionController.store);
|
||||
|
||||
positionRoutes.put(
|
||||
"/positions/:positionId",
|
||||
isAuth,
|
||||
PositionController.update
|
||||
);
|
||||
|
||||
positionRoutes.delete(
|
||||
"/positions/:positionId",
|
||||
isAuth,
|
||||
PositionController.remove
|
||||
);
|
||||
|
||||
export default positionRoutes;
|
|
@ -15,7 +15,7 @@ import schedulingNotifiyRoutes from "./SchedulingNotifyRoutes";
|
|||
import statusChatEndRoutes from "./statusChatEndRoutes";
|
||||
import wbotMonitorRoutes from "./wbotMonitorRoutes";
|
||||
import iamRoutesEL from "./iamRoutesEL";
|
||||
|
||||
import positionRoutes from "./PositionRoutes"
|
||||
const routes = Router();
|
||||
|
||||
|
||||
|
@ -35,5 +35,6 @@ routes.use(schedulingNotifiyRoutes);
|
|||
routes.use(reportRoutes);
|
||||
routes.use(statusChatEndRoutes);
|
||||
routes.use(wbotMonitorRoutes);
|
||||
routes.use(positionRoutes);
|
||||
|
||||
export default routes;
|
||||
|
|
|
@ -5,6 +5,27 @@ import * as StatusChatEnd from "../controllers/StatusChatEndController";
|
|||
|
||||
const statusChatEndRoutes = Router();
|
||||
|
||||
statusChatEndRoutes.get("/statusChatEnd", isAuth, StatusChatEnd.show);
|
||||
statusChatEndRoutes.post("/statusChatEnd", isAuth, StatusChatEnd.store);
|
||||
|
||||
// statusChatEndRoutes.get("/statusChatEnd", isAuth, StatusChatEnd.show);
|
||||
statusChatEndRoutes.get("/statusChatEnd", isAuth, StatusChatEnd.index);
|
||||
|
||||
statusChatEndRoutes.get(
|
||||
"/statusChatEnd/:statusChatEndId",
|
||||
isAuth,
|
||||
StatusChatEnd.show
|
||||
);
|
||||
|
||||
statusChatEndRoutes.put(
|
||||
"/statusChatEnd/:statusChatEndId",
|
||||
isAuth,
|
||||
StatusChatEnd.update
|
||||
);
|
||||
|
||||
statusChatEndRoutes.delete(
|
||||
"/statusChatEnd/:statusChatEndId",
|
||||
isAuth,
|
||||
StatusChatEnd.remove
|
||||
);
|
||||
|
||||
export default statusChatEndRoutes;
|
|
@ -28,6 +28,7 @@ import ShowUserService from "./services/UserServices/ShowUserService";
|
|||
import { json } from "sequelize";
|
||||
import { setBotInfo } from "./helpers/SetBotInfo";
|
||||
import Queue from "./models/Queue";
|
||||
import StatusChatEnd from "./models/StatusChatEnd";
|
||||
|
||||
const server = app.listen(process.env.PORT, () => {
|
||||
logger.info(`Server started on port: ${process.env.PORT}`);
|
||||
|
@ -48,7 +49,14 @@ gracefulShutdown(server);
|
|||
(async () => {
|
||||
console.log("os.tmpdir(): ", os.tmpdir());
|
||||
|
||||
await clearAllKeys("user:*", "whatsapp:*", "queue:*");
|
||||
await clearAllKeys("user:*", "whatsapp:*", "queue:*", "statusChatEnd:*");
|
||||
|
||||
const statusChatEnds = await StatusChatEnd.findAll();
|
||||
|
||||
for (const statusChatEnd of statusChatEnds) {
|
||||
const { id, name, farewellMessage } = statusChatEnd;
|
||||
await set(`statusChatEnd:${id}`, { id, name, farewellMessage });
|
||||
}
|
||||
|
||||
const users = await User.findAll();
|
||||
|
||||
|
@ -63,12 +71,12 @@ gracefulShutdown(server);
|
|||
await set(`user:${id}`, { id, name });
|
||||
}
|
||||
|
||||
// const queues = await Queue.findAll();
|
||||
const queues = await Queue.findAll();
|
||||
|
||||
// for (const queue of queues) {
|
||||
// const { id, greetingMessage, name } = queue;
|
||||
// await set(`queue:${id}`, { id, name, greetingMessage });
|
||||
// }
|
||||
for (const queue of queues) {
|
||||
const { id, greetingMessage, name, farewellMessage } = queue;
|
||||
await set(`queue:${id}`, { id, name, greetingMessage, farewellMessage });
|
||||
}
|
||||
|
||||
loadSettings();
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import Contact from "../../models/Contact";
|
||||
|
||||
const AssociateContatctQueue = async (
|
||||
contact: Contact,
|
||||
queueIds: number[]
|
||||
): Promise<void> => {
|
||||
await contact.$set("queues", queueIds);
|
||||
|
||||
await contact.reload();
|
||||
};
|
||||
|
||||
export default AssociateContatctQueue;
|
|
@ -1,8 +1,9 @@
|
|||
import AppError from "../../errors/AppError";
|
||||
import Contact from "../../models/Contact";
|
||||
|
||||
import { createOrUpdateContactCache } from '../../helpers/ContactsCache'
|
||||
import { createOrUpdateContactCache } from "../../helpers/ContactsCache";
|
||||
import GetProfilePicUrl from "../WbotServices/GetProfilePicUrl";
|
||||
import AssociateContatctQueue from "./AssociateContatctQueue";
|
||||
|
||||
interface ExtraInfo {
|
||||
name: string;
|
||||
|
@ -15,18 +16,18 @@ interface Request {
|
|||
email?: string;
|
||||
profilePicUrl?: string;
|
||||
extraInfo?: ExtraInfo[];
|
||||
queueIds?: number[];
|
||||
}
|
||||
|
||||
const CreateContactService = async ({
|
||||
name,
|
||||
number,
|
||||
email = "",
|
||||
profilePicUrl='',
|
||||
extraInfo = []
|
||||
profilePicUrl = "",
|
||||
extraInfo = [],
|
||||
queueIds = []
|
||||
}: Request): Promise<Contact> => {
|
||||
|
||||
try {
|
||||
|
||||
const numberExists = await Contact.findOne({
|
||||
where: { number }
|
||||
});
|
||||
|
@ -48,21 +49,25 @@ const CreateContactService = async ({
|
|||
}
|
||||
);
|
||||
|
||||
|
||||
await AssociateContatctQueue(contact, queueIds);
|
||||
|
||||
// TEST DEL
|
||||
await createOrUpdateContactCache(`contact:${contact.id}`, {id: contact.id, name, number, profilePicUrl, isGroup:'false', extraInfo, email })
|
||||
await createOrUpdateContactCache(`contact:${contact.id}`, {
|
||||
id: contact.id,
|
||||
name,
|
||||
number,
|
||||
profilePicUrl,
|
||||
isGroup: "false",
|
||||
extraInfo,
|
||||
email
|
||||
});
|
||||
//
|
||||
|
||||
|
||||
return contact;
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('===> Error on CreateContactService.ts file: \n', error)
|
||||
console.error("===> Error on CreateContactService.ts file: \n", error);
|
||||
throw new AppError(error.message);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
export default CreateContactService;
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
import { Sequelize, Op } from "sequelize";
|
||||
import Contact from "../../models/Contact";
|
||||
import Queue from "../../models/Queue";
|
||||
import { getSettingValue } from "../../helpers/WhaticketSettings";
|
||||
// import ListContactsService from "../services/ContactServices/ListContactsService";
|
||||
import ListWhatsappQueueByUserQueue from "../WhatsappService/ListWhatsAppsForQueueService";
|
||||
import QueuesByUser from "../UserServices/ShowQueuesByUser";
|
||||
import { number } from "yup";
|
||||
|
||||
interface Request {
|
||||
searchParam?: string;
|
||||
pageNumber?: string;
|
||||
userId?: string;
|
||||
}
|
||||
|
||||
interface Response {
|
||||
|
@ -14,13 +21,14 @@ interface Response {
|
|||
|
||||
const ListContactsService = async ({
|
||||
searchParam = "",
|
||||
pageNumber = "1"
|
||||
pageNumber = "1",
|
||||
userId
|
||||
}: Request): Promise<Response> => {
|
||||
const whereCondition = {
|
||||
[Op.or]: [
|
||||
{
|
||||
name: Sequelize.where(
|
||||
Sequelize.fn("LOWER", Sequelize.col("name")),
|
||||
Sequelize.fn("LOWER", Sequelize.col("Contact.name")),
|
||||
"LIKE",
|
||||
`%${searchParam.toLowerCase().trim()}%`
|
||||
)
|
||||
|
@ -31,20 +39,59 @@ const ListContactsService = async ({
|
|||
const limit = 20;
|
||||
const offset = limit * (+pageNumber - 1);
|
||||
|
||||
const { count, rows: contacts } = await Contact.findAndCountAll({
|
||||
let { count, rows: contacts } = await Contact.findAndCountAll({
|
||||
where: whereCondition,
|
||||
limit,
|
||||
include: [
|
||||
{
|
||||
model: Queue,
|
||||
as: "queues",
|
||||
// where: whereConditionQueue,
|
||||
attributes: ["id", "name", "color", "greetingMessage"]
|
||||
}
|
||||
],
|
||||
offset,
|
||||
order: [["name", "ASC"]]
|
||||
});
|
||||
|
||||
const hasMore = count > offset + contacts.length;
|
||||
|
||||
if (getSettingValue("contactByqueues")?.value == "enabled") {
|
||||
const queueIds = await QueuesByUser({ userId });
|
||||
|
||||
contacts = contactQueueFilter(queueIds, contacts);
|
||||
}
|
||||
|
||||
return {
|
||||
contacts,
|
||||
count,
|
||||
hasMore
|
||||
};
|
||||
};
|
||||
|
||||
export default ListContactsService;
|
||||
|
||||
function contactQueueFilter(queueIds: any[], contacts: Contact[]) {
|
||||
let auxContact: any[] = [];
|
||||
let repet: any[] = [];
|
||||
const userQueues = queueIds.map((uq: any) => uq.queueId);
|
||||
|
||||
for (const contact of contacts) {
|
||||
const { queues, id } = contact;
|
||||
|
||||
if (queues.length == 0) {
|
||||
auxContact.push(contact);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const q of queues) {
|
||||
if (userQueues.includes(q.id)) {
|
||||
if (repet.includes(id)) continue;
|
||||
repet.push(id);
|
||||
|
||||
auxContact.push(contact);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return auxContact;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,20 @@
|
|||
import Contact from "../../models/Contact";
|
||||
import AppError from "../../errors/AppError";
|
||||
import { getSettingValue } from "../../helpers/WhaticketSettings";
|
||||
import Queue from "../../models/Queue";
|
||||
|
||||
const ShowContactService = async (id: string | number): Promise<Contact> => {
|
||||
const contact = await Contact.findByPk(id, { include: ["extraInfo"] });
|
||||
let includeQueue: any[] = [];
|
||||
|
||||
if (getSettingValue("contactByqueues")?.value == "enabled") {
|
||||
includeQueue = [
|
||||
{ model: Queue, as: "queues", attributes: ["id", "name", "color"] }
|
||||
];
|
||||
}
|
||||
|
||||
const contact = await Contact.findByPk(id, {
|
||||
include: ["extraInfo", ...includeQueue]
|
||||
});
|
||||
|
||||
if (!contact) {
|
||||
throw new AppError("ERR_NO_CONTACT_FOUND", 404);
|
||||
|
|
|
@ -2,9 +2,10 @@ import AppError from "../../errors/AppError";
|
|||
import Contact from "../../models/Contact";
|
||||
import ContactCustomField from "../../models/ContactCustomField";
|
||||
|
||||
import { updateTicketsByContactsCache } from '../../helpers/TicketCache'
|
||||
import { updateContactCacheById } from '../../helpers/ContactsCache'
|
||||
import { updateTicketsByContactsCache } from "../../helpers/TicketCache";
|
||||
import { updateContactCacheById } from "../../helpers/ContactsCache";
|
||||
import { tr } from "date-fns/locale";
|
||||
import AssociateContatctQueue from "./AssociateContatctQueue";
|
||||
|
||||
interface ExtraInfo {
|
||||
id?: number;
|
||||
|
@ -16,6 +17,7 @@ interface ContactData {
|
|||
number?: string;
|
||||
name?: string;
|
||||
extraInfo?: ExtraInfo[];
|
||||
queueIds?: number[];
|
||||
}
|
||||
|
||||
interface Request {
|
||||
|
@ -23,15 +25,12 @@ interface Request {
|
|||
contactId: string;
|
||||
}
|
||||
|
||||
|
||||
const UpdateContactService = async ({
|
||||
contactData,
|
||||
contactId
|
||||
}: Request): Promise<Contact> => {
|
||||
|
||||
try {
|
||||
|
||||
const { email, name, number, extraInfo } = contactData;
|
||||
const { email, name, number, extraInfo, queueIds } = contactData;
|
||||
|
||||
// console.log('email, name, number, extraInfo: ', email, name, number, extraInfo)
|
||||
|
||||
|
@ -54,7 +53,9 @@ const UpdateContactService = async ({
|
|||
|
||||
await Promise.all(
|
||||
contact.extraInfo.map(async oldInfo => {
|
||||
const stillExists = extraInfo.findIndex(info => info.id === oldInfo.id);
|
||||
const stillExists = extraInfo.findIndex(
|
||||
info => info.id === oldInfo.id
|
||||
);
|
||||
|
||||
if (stillExists === -1) {
|
||||
await ContactCustomField.destroy({ where: { id: oldInfo.id } });
|
||||
|
@ -63,11 +64,10 @@ const UpdateContactService = async ({
|
|||
);
|
||||
}
|
||||
|
||||
const oldNumber = contact.number
|
||||
|
||||
const oldNumber = contact.number;
|
||||
|
||||
//Solução para o erro tcp_wrap.cc
|
||||
console.log('----------> oldNumber: ', oldNumber)
|
||||
console.log("----------> oldNumber: ", oldNumber);
|
||||
if (number) {
|
||||
const numberExists = await Contact.findOne({
|
||||
where: { number }
|
||||
|
@ -78,7 +78,6 @@ const UpdateContactService = async ({
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
await contact.update({
|
||||
name,
|
||||
number,
|
||||
|
@ -86,29 +85,28 @@ const UpdateContactService = async ({
|
|||
});
|
||||
|
||||
|
||||
if (queueIds) await AssociateContatctQueue(contact, queueIds);
|
||||
|
||||
//TEST DEL
|
||||
await updateTicketsByContactsCache(oldNumber, contact.name, contact.number)
|
||||
await updateTicketsByContactsCache(oldNumber, contact.name, contact.number);
|
||||
//
|
||||
|
||||
|
||||
await contact.reload({
|
||||
attributes: ["id", "name", "number", "email", "profilePicUrl"],
|
||||
include: ["extraInfo"]
|
||||
});
|
||||
|
||||
|
||||
|
||||
// console.log('contactcontactcontactcontact: ',flatten(JSON.parse(JSON.stringify(contact))))
|
||||
await updateContactCacheById(contact.id, JSON.parse(JSON.stringify(contact)))
|
||||
await updateContactCacheById(
|
||||
contact.id,
|
||||
JSON.parse(JSON.stringify(contact))
|
||||
);
|
||||
|
||||
return contact;
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('===> Error on UpdateContactService.ts file: \n', error)
|
||||
console.error("===> Error on UpdateContactService.ts file: \n", error);
|
||||
throw new AppError(error.message);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default UpdateContactService;
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
import AppError from "../../errors/AppError";
|
||||
import Position from "../../models/Position";
|
||||
import AssociateQuickAnswerQueue from "../QueueService/AssociateQuickAnswerQueue";
|
||||
|
||||
interface Request {
|
||||
name: string;
|
||||
}
|
||||
|
||||
const CreatePositionService = async ({ name }: Request): Promise<Position> => {
|
||||
const nameExists = await Position.findOne({
|
||||
where: { name }
|
||||
});
|
||||
|
||||
if (nameExists) {
|
||||
throw new AppError("ERR_POSITION_DUPLICATED");
|
||||
}
|
||||
|
||||
const position = await Position.create({ name });
|
||||
|
||||
return position;
|
||||
};
|
||||
|
||||
export default CreatePositionService;
|
|
@ -0,0 +1,16 @@
|
|||
import Position from "../../models/Position";
|
||||
import AppError from "../../errors/AppError";
|
||||
|
||||
const DeletePositionService = async (id: string): Promise<void> => {
|
||||
const position = await Position.findOne({
|
||||
where: { id }
|
||||
});
|
||||
|
||||
if (!position) {
|
||||
throw new AppError("ERR_NO_POSITION_FOUND", 404);
|
||||
}
|
||||
|
||||
await position.destroy();
|
||||
};
|
||||
|
||||
export default DeletePositionService;
|
|
@ -0,0 +1,48 @@
|
|||
import { Op, Sequelize } from "sequelize";
|
||||
import Position from "../../models/Position";
|
||||
|
||||
interface Request {
|
||||
searchParam?: string;
|
||||
pageNumber?: string;
|
||||
}
|
||||
|
||||
interface Response {
|
||||
positions: Position[];
|
||||
count: number;
|
||||
hasMore: boolean;
|
||||
}
|
||||
|
||||
const ListPositionService = async ({
|
||||
searchParam = "",
|
||||
pageNumber = "1"
|
||||
}: Request): Promise<Response> => {
|
||||
console.log("searchParam: ", searchParam);
|
||||
|
||||
const whereCondition = {
|
||||
message: Sequelize.where(
|
||||
Sequelize.fn("LOWER", Sequelize.col("name")),
|
||||
"LIKE",
|
||||
`%${searchParam.toLowerCase().trim()}%`
|
||||
)
|
||||
};
|
||||
|
||||
const limit = 20;
|
||||
const offset = limit * (+pageNumber - 1);
|
||||
|
||||
let { count, rows: positions } = await Position.findAndCountAll({
|
||||
where: whereCondition,
|
||||
limit,
|
||||
offset,
|
||||
order: [["name", "ASC"]]
|
||||
});
|
||||
|
||||
const hasMore = count > offset + positions.length;
|
||||
|
||||
return {
|
||||
positions,
|
||||
count,
|
||||
hasMore
|
||||
};
|
||||
};
|
||||
|
||||
export default ListPositionService;
|
|
@ -0,0 +1,16 @@
|
|||
import AppError from "../../errors/AppError";
|
||||
import Position from "../../models/Position";
|
||||
|
||||
const ShowPositionService = async (
|
||||
id: string,
|
||||
): Promise<Position> => {
|
||||
const position = await Position.findByPk(id);
|
||||
|
||||
if (!position) {
|
||||
throw new AppError("ERR_NO_POSITION_FOUND", 404);
|
||||
}
|
||||
|
||||
return position;
|
||||
};
|
||||
|
||||
export default ShowPositionService;
|
|
@ -0,0 +1,38 @@
|
|||
import Position from "../../models/Position";
|
||||
import AppError from "../../errors/AppError";
|
||||
import AssociateQuickAnswerQueue from "../QueueService/AssociateQuickAnswerQueue";
|
||||
|
||||
interface PositionData {
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface Request {
|
||||
positionData: PositionData;
|
||||
positionId: string;
|
||||
}
|
||||
|
||||
const UpdatePositionService = async ({
|
||||
positionData,
|
||||
positionId
|
||||
}: Request): Promise<Position> => {
|
||||
const { name } = positionData;
|
||||
|
||||
const position = await Position.findOne({
|
||||
where: { id: positionId }
|
||||
});
|
||||
|
||||
if (!position) {
|
||||
throw new AppError("ERR_NO_POSITION_FOUND", 404);
|
||||
}
|
||||
await position.update({
|
||||
name
|
||||
});
|
||||
|
||||
await position.reload({
|
||||
attributes: ["id", "name"]
|
||||
});
|
||||
|
||||
return position;
|
||||
};
|
||||
|
||||
export default UpdatePositionService;
|
|
@ -0,0 +1,12 @@
|
|||
import QuickAnswer from "../../models/QuickAnswer";
|
||||
|
||||
const AssociateQuickAnswerQueue = async (
|
||||
QuickAnswer: QuickAnswer,
|
||||
queueIds: number[]
|
||||
): Promise<void> => {
|
||||
await QuickAnswer.$set("queues", queueIds);
|
||||
|
||||
await QuickAnswer.reload();
|
||||
};
|
||||
|
||||
export default AssociateQuickAnswerQueue;
|
|
@ -7,6 +7,7 @@ interface QueueData {
|
|||
name: string;
|
||||
color: string;
|
||||
greetingMessage?: string;
|
||||
farewellMessage?: string;
|
||||
cc?: string;
|
||||
}
|
||||
|
||||
|
@ -64,8 +65,13 @@ const CreateQueueService = async (queueData: QueueData): Promise<Queue> => {
|
|||
|
||||
const queue = await Queue.create(queueData);
|
||||
|
||||
// const { id, greetingMessage } = queue;
|
||||
// await set(`queue:${id}`, { id, name, greetingMessage });
|
||||
const { id, greetingMessage, farewellMessage } = queue;
|
||||
await set(`queue:${id}`, {
|
||||
id,
|
||||
name,
|
||||
greetingMessage,
|
||||
farewellMessage
|
||||
});
|
||||
|
||||
return queue;
|
||||
} catch (error: any) {
|
||||
|
|
|
@ -4,28 +4,28 @@ import UserQueue from "../../models/UserQueue";
|
|||
|
||||
import ListTicketsServiceCache from "../TicketServices/ListTicketServiceCache";
|
||||
|
||||
import { deleteTicketsFieldsCache } from '../../helpers/TicketCache'
|
||||
import { deleteTicketsFieldsCache } from "../../helpers/TicketCache";
|
||||
import { del } from "../../helpers/RedisClient";
|
||||
|
||||
const DeleteQueueService = async (queueId: number | string): Promise<void> => {
|
||||
|
||||
const queue = await ShowQueueService(queueId);
|
||||
|
||||
if (queue.id) {
|
||||
const tickets = await ListTicketsServiceCache({ queueId });
|
||||
|
||||
const tickets = await ListTicketsServiceCache({ queueId })
|
||||
|
||||
await deleteTicketsFieldsCache(tickets, ['queue.id', 'queue.name', 'queue.color'])
|
||||
|
||||
await deleteTicketsFieldsCache(tickets, [
|
||||
"queue.id",
|
||||
"queue.name",
|
||||
"queue.color"
|
||||
]);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
await UserQueue.destroy({ where: { queueId: queueId } });
|
||||
|
||||
del(`queue:${queueId}`);
|
||||
} catch (error) {
|
||||
|
||||
console.log('Error on delete UserQueue by queueId: ', queueId)
|
||||
|
||||
console.log("Error on delete UserQueue by queueId: ", queueId);
|
||||
}
|
||||
|
||||
await queue.destroy();
|
||||
|
|
|
@ -9,6 +9,7 @@ interface QueueData {
|
|||
name?: string;
|
||||
color?: string;
|
||||
greetingMessage?: string;
|
||||
farewellMessage?: string;
|
||||
cc?: string;
|
||||
}
|
||||
|
||||
|
@ -70,8 +71,13 @@ const UpdateQueueService = async (
|
|||
|
||||
await queue.update(queueData);
|
||||
|
||||
// const { id, greetingMessage } = queue;
|
||||
// await set(`queue:${id}`, { id, name, greetingMessage });
|
||||
const { greetingMessage, farewellMessage } = queue;
|
||||
await set(`queue:${queueId}`, {
|
||||
id: queueId,
|
||||
name,
|
||||
greetingMessage,
|
||||
farewellMessage
|
||||
});
|
||||
|
||||
return queue;
|
||||
} catch (error: any) {
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
import AppError from "../../errors/AppError";
|
||||
import QuickAnswer from "../../models/QuickAnswer";
|
||||
import AssociateQuickAnswerQueue from "../QueueService/AssociateQuickAnswerQueue";
|
||||
|
||||
interface Request {
|
||||
shortcut: string;
|
||||
message: string;
|
||||
queueIds?: number[];
|
||||
}
|
||||
|
||||
const CreateQuickAnswerService = async ({
|
||||
shortcut,
|
||||
message
|
||||
message,
|
||||
queueIds = []
|
||||
}: Request): Promise<QuickAnswer> => {
|
||||
const nameExists = await QuickAnswer.findOne({
|
||||
where: { shortcut }
|
||||
|
@ -20,6 +23,8 @@ const CreateQuickAnswerService = async ({
|
|||
|
||||
const quickAnswer = await QuickAnswer.create({ shortcut, message });
|
||||
|
||||
await AssociateQuickAnswerQueue(quickAnswer, queueIds);
|
||||
|
||||
return quickAnswer;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
import { Sequelize } from "sequelize";
|
||||
import { Op, Sequelize } from "sequelize";
|
||||
import QuickAnswer from "../../models/QuickAnswer";
|
||||
import Queue from "../../models/Queue";
|
||||
import QueuesByUser from "../UserServices/ShowQueuesByUser";
|
||||
import quickAnswearByQueueFiltered from "../../helpers/QuickAnswearByqueueFiltered";
|
||||
import { getSettingValue } from "../../helpers/WhaticketSettings";
|
||||
|
||||
interface Request {
|
||||
searchParam?: string;
|
||||
pageNumber?: string;
|
||||
userId?: string | number;
|
||||
}
|
||||
|
||||
interface Response {
|
||||
|
@ -14,8 +19,11 @@ interface Response {
|
|||
|
||||
const ListQuickAnswerService = async ({
|
||||
searchParam = "",
|
||||
pageNumber = "1"
|
||||
pageNumber = "1",
|
||||
userId
|
||||
}: Request): Promise<Response> => {
|
||||
console.log("searchParam: ", searchParam);
|
||||
|
||||
const whereCondition = {
|
||||
message: Sequelize.where(
|
||||
Sequelize.fn("LOWER", Sequelize.col("message")),
|
||||
|
@ -23,11 +31,21 @@ const ListQuickAnswerService = async ({
|
|||
`%${searchParam.toLowerCase().trim()}%`
|
||||
)
|
||||
};
|
||||
|
||||
const limit = 20;
|
||||
const offset = limit * (+pageNumber - 1);
|
||||
|
||||
const { count, rows: quickAnswers } = await QuickAnswer.findAndCountAll({
|
||||
let { count, rows: quickAnswers } = await QuickAnswer.findAndCountAll({
|
||||
where: whereCondition,
|
||||
|
||||
include: [
|
||||
{
|
||||
model: Queue,
|
||||
as: "queues",
|
||||
attributes: ["id", "name", "color", "greetingMessage"]
|
||||
}
|
||||
],
|
||||
|
||||
limit,
|
||||
offset,
|
||||
order: [["message", "ASC"]]
|
||||
|
@ -35,6 +53,11 @@ const ListQuickAnswerService = async ({
|
|||
|
||||
const hasMore = count > offset + quickAnswers.length;
|
||||
|
||||
if (getSettingValue("quickAnswerByQueue")?.value == "enabled") {
|
||||
const queueIds = await QueuesByUser({ userId });
|
||||
quickAnswers = quickAnswearByQueueFiltered(queueIds, quickAnswers);
|
||||
}
|
||||
|
||||
return {
|
||||
quickAnswers,
|
||||
count,
|
||||
|
|
|
@ -1,8 +1,24 @@
|
|||
import QuickAnswer from "../../models/QuickAnswer";
|
||||
import AppError from "../../errors/AppError";
|
||||
import Queue from "../../models/Queue";
|
||||
import QueuesByUser from "../UserServices/ShowQueuesByUser";
|
||||
import quickAnswearByQueueFiltered from "../../helpers/QuickAnswearByqueueFiltered";
|
||||
|
||||
const ShowQuickAnswerService = async (id: string): Promise<QuickAnswer> => {
|
||||
const quickAnswer = await QuickAnswer.findByPk(id);
|
||||
const ShowQuickAnswerService = async (
|
||||
id: string,
|
||||
userId?: string
|
||||
): Promise<QuickAnswer> => {
|
||||
|
||||
const quickAnswer = await QuickAnswer.findByPk(id, {
|
||||
include: [
|
||||
{
|
||||
model: Queue,
|
||||
as: "queues",
|
||||
attributes: ["id", "name", "color", "greetingMessage"]
|
||||
}
|
||||
],
|
||||
order: [["queues", "id", "ASC"]]
|
||||
});
|
||||
|
||||
if (!quickAnswer) {
|
||||
throw new AppError("ERR_NO_QUICK_ANSWERS_FOUND", 404);
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import QuickAnswer from "../../models/QuickAnswer";
|
||||
import AppError from "../../errors/AppError";
|
||||
import AssociateQuickAnswerQueue from "../QueueService/AssociateQuickAnswerQueue";
|
||||
|
||||
interface QuickAnswerData {
|
||||
shortcut?: string;
|
||||
message?: string;
|
||||
queueIds?: number[];
|
||||
}
|
||||
|
||||
interface Request {
|
||||
|
@ -15,7 +17,7 @@ const UpdateQuickAnswerService = async ({
|
|||
quickAnswerData,
|
||||
quickAnswerId
|
||||
}: Request): Promise<QuickAnswer> => {
|
||||
const { shortcut, message } = quickAnswerData;
|
||||
const { shortcut, message, queueIds } = quickAnswerData;
|
||||
|
||||
const quickAnswer = await QuickAnswer.findOne({
|
||||
where: { id: quickAnswerId },
|
||||
|
@ -30,6 +32,8 @@ const UpdateQuickAnswerService = async ({
|
|||
message
|
||||
});
|
||||
|
||||
if (queueIds) await AssociateQuickAnswerQueue(quickAnswer, queueIds);
|
||||
|
||||
await quickAnswer.reload({
|
||||
attributes: ["id", "shortcut", "message"]
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@ import SchedulingNotify from "../../models/SchedulingNotify";
|
|||
interface Request {
|
||||
schedulingNotifyId?: string,
|
||||
ticketId: string,
|
||||
statusChatEndId: string,
|
||||
statusChatEndId: string | number,
|
||||
schedulingDate: string,
|
||||
schedulingTime: string,
|
||||
message: string
|
||||
|
|
|
@ -3,15 +3,17 @@ import Contact from "../../models/Contact";
|
|||
import SchedulingNotify from "../../models/SchedulingNotify";
|
||||
import { Op, where, Sequelize } from "sequelize";
|
||||
import AppError from "../../errors/AppError";
|
||||
import StatusChatEnd from "../../models/StatusChatEnd"
|
||||
|
||||
const ListSchedulingNotifyContactService = async (contactNumber: string = '', startDate: string='', endDate: string=''): Promise<SchedulingNotify[]> => {
|
||||
|
||||
|
||||
let where_clause = {}
|
||||
let where_clause_notify = {}
|
||||
const ListSchedulingNotifyContactService = async (
|
||||
contactNumber: string = "",
|
||||
startDate: string = "",
|
||||
endDate: string = ""
|
||||
): Promise<SchedulingNotify[]> => {
|
||||
let where_clause = {};
|
||||
let where_clause_notify = {};
|
||||
|
||||
let nameNumber = {
|
||||
|
||||
[Op.or]: [
|
||||
{
|
||||
name: Sequelize.where(
|
||||
|
@ -22,126 +24,144 @@ const ListSchedulingNotifyContactService = async (contactNumber: string = '', st
|
|||
},
|
||||
{ number: { [Op.like]: `%${contactNumber.toLowerCase().trim()}%` } }
|
||||
]
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (contactNumber.trim().length>0 && startDate.trim().length>0 && endDate.trim().length>0){
|
||||
|
||||
where_clause = nameNumber
|
||||
if (
|
||||
contactNumber.trim().length > 0 &&
|
||||
startDate.trim().length > 0 &&
|
||||
endDate.trim().length > 0
|
||||
) {
|
||||
where_clause = nameNumber;
|
||||
|
||||
where_clause_notify = {
|
||||
schedulingTime: {
|
||||
[Op.gte]: startDate+' 00:00:00.000000',
|
||||
[Op.lte]: endDate +' 23:59:59.999999'
|
||||
},
|
||||
[Op.gte]: startDate + " 00:00:00.000000",
|
||||
[Op.lte]: endDate + " 23:59:59.999999"
|
||||
}
|
||||
|
||||
}
|
||||
else if (contactNumber.trim().length==0 && startDate.trim().length>0 && endDate.trim().length>0){
|
||||
|
||||
where_clause = {}
|
||||
};
|
||||
} else if (
|
||||
contactNumber.trim().length == 0 &&
|
||||
startDate.trim().length > 0 &&
|
||||
endDate.trim().length > 0
|
||||
) {
|
||||
where_clause = {};
|
||||
|
||||
where_clause_notify = {
|
||||
schedulingDate: {
|
||||
[Op.gte]: startDate+' 00:00:00.000000',
|
||||
[Op.lte]: endDate +' 23:59:59.999999'
|
||||
},
|
||||
[Op.gte]: startDate + " 00:00:00.000000",
|
||||
[Op.lte]: endDate + " 23:59:59.999999"
|
||||
}
|
||||
|
||||
}
|
||||
else if (contactNumber.trim().length==0 && startDate.trim().length>0 && endDate.trim().length==0){
|
||||
|
||||
where_clause = {}
|
||||
};
|
||||
} else if (
|
||||
contactNumber.trim().length == 0 &&
|
||||
startDate.trim().length > 0 &&
|
||||
endDate.trim().length == 0
|
||||
) {
|
||||
where_clause = {};
|
||||
|
||||
where_clause_notify = {
|
||||
schedulingDate: {
|
||||
[Op.gte]: startDate+' 00:00:00.000000',
|
||||
[Op.lte]: startDate +' 23:59:59.999999'
|
||||
},
|
||||
[Op.gte]: startDate + " 00:00:00.000000",
|
||||
[Op.lte]: startDate + " 23:59:59.999999"
|
||||
}
|
||||
|
||||
}
|
||||
else if (contactNumber.trim().length==0 && startDate.trim().length==0 && endDate.trim().length>0){
|
||||
|
||||
where_clause = {}
|
||||
};
|
||||
} else if (
|
||||
contactNumber.trim().length == 0 &&
|
||||
startDate.trim().length == 0 &&
|
||||
endDate.trim().length > 0
|
||||
) {
|
||||
where_clause = {};
|
||||
|
||||
where_clause_notify = {
|
||||
schedulingDate: {
|
||||
[Op.gte]: endDate+' 00:00:00.000000',
|
||||
[Op.lte]: endDate +' 23:59:59.999999'
|
||||
},
|
||||
[Op.gte]: endDate + " 00:00:00.000000",
|
||||
[Op.lte]: endDate + " 23:59:59.999999"
|
||||
}
|
||||
|
||||
}
|
||||
else if (contactNumber.trim().length>0 && startDate.trim().length>0 && endDate.trim().length==0){
|
||||
|
||||
where_clause = nameNumber
|
||||
};
|
||||
} else if (
|
||||
contactNumber.trim().length > 0 &&
|
||||
startDate.trim().length > 0 &&
|
||||
endDate.trim().length == 0
|
||||
) {
|
||||
where_clause = nameNumber;
|
||||
|
||||
where_clause_notify = {
|
||||
schedulingDate: {
|
||||
[Op.gte]: startDate+' 00:00:00.000000',
|
||||
[Op.lte]: startDate +' 23:59:59.999999'
|
||||
},
|
||||
[Op.gte]: startDate + " 00:00:00.000000",
|
||||
[Op.lte]: startDate + " 23:59:59.999999"
|
||||
}
|
||||
|
||||
}
|
||||
else if (contactNumber.trim().length>0 && startDate.trim().length==0 && endDate.trim().length>0){
|
||||
|
||||
where_clause = nameNumber
|
||||
};
|
||||
} else if (
|
||||
contactNumber.trim().length > 0 &&
|
||||
startDate.trim().length == 0 &&
|
||||
endDate.trim().length > 0
|
||||
) {
|
||||
where_clause = nameNumber;
|
||||
|
||||
where_clause_notify = {
|
||||
schedulingDate: {
|
||||
[Op.gte]: endDate+' 00:00:00.000000',
|
||||
[Op.lte]: endDate +' 23:59:59.999999'
|
||||
},
|
||||
[Op.gte]: endDate + " 00:00:00.000000",
|
||||
[Op.lte]: endDate + " 23:59:59.999999"
|
||||
}
|
||||
|
||||
};
|
||||
} else if (contactNumber.trim().length > 0) {
|
||||
where_clause = nameNumber;
|
||||
}
|
||||
else if(contactNumber.trim().length>0){
|
||||
|
||||
where_clause = nameNumber
|
||||
|
||||
}
|
||||
|
||||
|
||||
const ticket = await SchedulingNotify.findAll({
|
||||
|
||||
raw: true,
|
||||
where: where_clause_notify,
|
||||
|
||||
attributes:['id', 'ticketId','statusChatEndId', [Sequelize.fn("DATE_FORMAT",Sequelize.col("schedulingDate"),"%d/%m/%Y %H:%i:%s"),"schedulingDate"],
|
||||
[Sequelize.fn("DATE_FORMAT",Sequelize.col("schedulingTime"),"%d/%m/%Y %H:%i:%s"),"schedulingTime"], 'message'],
|
||||
attributes: [
|
||||
"id",
|
||||
"ticketId",
|
||||
"statusChatEndId",
|
||||
[
|
||||
Sequelize.fn(
|
||||
"DATE_FORMAT",
|
||||
Sequelize.col("schedulingDate"),
|
||||
"%d/%m/%Y %H:%i:%s"
|
||||
),
|
||||
"schedulingDate"
|
||||
],
|
||||
[
|
||||
Sequelize.fn(
|
||||
"DATE_FORMAT",
|
||||
Sequelize.col("schedulingTime"),
|
||||
"%d/%m/%Y %H:%i:%s"
|
||||
),
|
||||
"schedulingTime"
|
||||
],
|
||||
"message"
|
||||
],
|
||||
|
||||
include: [
|
||||
{
|
||||
model: Ticket,
|
||||
required:true,
|
||||
required: true,
|
||||
attributes: [],
|
||||
include: [
|
||||
{
|
||||
model: Contact,
|
||||
where: where_clause,
|
||||
attributes: ['name', 'number', 'profilePicUrl']
|
||||
},
|
||||
attributes: ["name", "number", "profilePicUrl"]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
model: StatusChatEnd,
|
||||
required: true,
|
||||
}
|
||||
],
|
||||
|
||||
order: [["id", "DESC"]]
|
||||
|
||||
});
|
||||
|
||||
|
||||
if (!ticket) {
|
||||
throw new AppError("ERR_NO_TICKET_FOUND", 404);
|
||||
}
|
||||
|
||||
return ticket;
|
||||
};
|
||||
|
||||
export default ListSchedulingNotifyContactService;
|
||||
};
|
||||
|
||||
export default ListSchedulingNotifyContactService;
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
import AppError from "../../errors/AppError";
|
||||
import { set } from "../../helpers/RedisClient";
|
||||
import StatusChatEnd from "../../models/StatusChatEnd";
|
||||
import AssociateQuickAnswerQueue from "../QueueService/AssociateQuickAnswerQueue";
|
||||
|
||||
interface Request {
|
||||
name: string;
|
||||
farewellMessage: string;
|
||||
isDefault: boolean;
|
||||
}
|
||||
|
||||
const CreateStatusChatEndService = async ({
|
||||
name,
|
||||
farewellMessage,
|
||||
isDefault = false
|
||||
}: Request): Promise<StatusChatEnd> => {
|
||||
const nameExists = await StatusChatEnd.findOne({
|
||||
where: { name }
|
||||
});
|
||||
|
||||
if (nameExists) {
|
||||
throw new AppError("ERR_STATUS_CHAT_END_DUPLICATED");
|
||||
}
|
||||
|
||||
const statusChatEnd = await StatusChatEnd.create({ name, farewellMessage, isDefault });
|
||||
|
||||
const { id } = statusChatEnd;
|
||||
await set(`statusChatEnd:${id}`, { id, name, farewellMessage, isDefault });
|
||||
|
||||
return statusChatEnd;
|
||||
};
|
||||
|
||||
export default CreateStatusChatEndService;
|
|
@ -25,10 +25,10 @@ interface Request {
|
|||
|
||||
const { count, rows: statusChatEnd } = await StatusChatEnd.findAndCountAll({
|
||||
where: whereCondition,
|
||||
attributes: ['id', 'name'],
|
||||
attributes: ["id", "name", "farewellMessage", "isDefault"],
|
||||
limit,
|
||||
offset,
|
||||
order: [["id", "ASC"]]
|
||||
order: [["name", "ASC"]]
|
||||
});
|
||||
|
||||
const hasMore = count > offset + statusChatEnd.length;
|
||||
|
|
|
@ -1,20 +1,45 @@
|
|||
import StatusChatEnd from "../../models/StatusChatEnd";
|
||||
import AppError from "../../errors/AppError";
|
||||
import { Op } from "sequelize";
|
||||
|
||||
const ShowStatusChatEndService = async (
|
||||
id: string | number
|
||||
): Promise<StatusChatEnd> => {
|
||||
const status = await StatusChatEnd.findByPk(id, {
|
||||
attributes: ["id", "name"]
|
||||
interface Request {
|
||||
id?: string | number;
|
||||
name?: string;
|
||||
isDefault?: boolean;
|
||||
}
|
||||
|
||||
const ShowStatusChatEndService = async ({
|
||||
id,
|
||||
name,
|
||||
isDefault
|
||||
}: Request): Promise<StatusChatEnd> => {
|
||||
let statusChatEnd: any;
|
||||
|
||||
if (id) {
|
||||
statusChatEnd = await StatusChatEnd.findByPk(id, {
|
||||
attributes: ["id", "name", "farewellMessage", "isDefault"]
|
||||
});
|
||||
} else if (name) {
|
||||
statusChatEnd = await StatusChatEnd.findOne({
|
||||
where: { name },
|
||||
attributes: ["id", "name", "farewellMessage", "isDefault"]
|
||||
});
|
||||
} else if (isDefault) {
|
||||
statusChatEnd = await StatusChatEnd.findOne({
|
||||
where: { isDefault },
|
||||
attributes: ["id", "name", "farewellMessage", "isDefault"]
|
||||
});
|
||||
|
||||
console.log(`---------------> statusChatEnd id: ${id}`);
|
||||
if (!statusChatEnd) {
|
||||
statusChatEnd = await StatusChatEnd.findOne();
|
||||
}
|
||||
}
|
||||
|
||||
if (!status) {
|
||||
if (!statusChatEnd) {
|
||||
throw new AppError("ERR_NO_STATUS_FOUND", 404);
|
||||
}
|
||||
|
||||
return status;
|
||||
return statusChatEnd;
|
||||
};
|
||||
|
||||
export default ShowStatusChatEndService;
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
import QuickAnswer from "../../models/QuickAnswer";
|
||||
import AppError from "../../errors/AppError";
|
||||
import AssociateQuickAnswerQueue from "../QueueService/AssociateQuickAnswerQueue";
|
||||
import StatusChatEnd from "../../models/StatusChatEnd";
|
||||
import { set } from "../../helpers/RedisClient";
|
||||
import { update } from "../../controllers/UserController";
|
||||
import { Op, where } from "sequelize";
|
||||
|
||||
interface StatusChatEndData {
|
||||
name?: string;
|
||||
farewellMessage?: string;
|
||||
isDefault?: boolean;
|
||||
}
|
||||
|
||||
interface Request {
|
||||
statusChatEndData: StatusChatEndData;
|
||||
statusChatEndId: string;
|
||||
}
|
||||
|
||||
const UpdateStatusChatEndService = async ({
|
||||
statusChatEndData,
|
||||
statusChatEndId
|
||||
}: Request): Promise<StatusChatEnd> => {
|
||||
const { name, farewellMessage, isDefault } = statusChatEndData;
|
||||
|
||||
if (isDefault) {
|
||||
StatusChatEnd.update(
|
||||
{ isDefault: false },
|
||||
{ where: { id: { [Op.gte]: 0 } } }
|
||||
);
|
||||
}
|
||||
|
||||
const statusChatEnd = await StatusChatEnd.findOne({
|
||||
where: { id: statusChatEndId },
|
||||
attributes: ["id", "name", "farewellMessage", "isDefault"]
|
||||
});
|
||||
|
||||
if (!statusChatEnd) {
|
||||
throw new AppError("ERR_NO_STATUS_CHAT_END_FIND", 404);
|
||||
}
|
||||
await statusChatEnd.update({
|
||||
name,
|
||||
farewellMessage,
|
||||
isDefault
|
||||
});
|
||||
|
||||
await statusChatEnd.reload({
|
||||
attributes: ["id", "name", "farewellMessage", "isDefault"]
|
||||
});
|
||||
|
||||
const { id } = statusChatEnd;
|
||||
await set(`statusChatEnd:${id}`, { id, name, farewellMessage, isDefault });
|
||||
|
||||
return statusChatEnd;
|
||||
};
|
||||
|
||||
export default UpdateStatusChatEndService;
|
|
@ -1,6 +1,6 @@
|
|||
import { Op, fn, where, col, Filterable, Includeable } from "sequelize";
|
||||
import { startOfDay, endOfDay, parseISO, format } from "date-fns";
|
||||
import ptBR from 'date-fns/locale/pt-BR';
|
||||
import ptBR from "date-fns/locale/pt-BR";
|
||||
|
||||
import Ticket from "../../models/Ticket";
|
||||
import Contact from "../../models/Contact";
|
||||
|
@ -8,20 +8,19 @@ import Message from "../../models/Message";
|
|||
import Queue from "../../models/Queue";
|
||||
import ShowUserService from "../UserServices/ShowUserService";
|
||||
|
||||
const unflatten = require('flat').unflatten
|
||||
const unflatten = require("flat").unflatten;
|
||||
|
||||
import { splitDateTime } from "../../helpers/SplitDateTime";
|
||||
const dateToday = splitDateTime(new Date(format(new Date(), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR })))
|
||||
const dateToday = splitDateTime(
|
||||
new Date(format(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: ptBR }))
|
||||
);
|
||||
|
||||
import ListTicketServiceCache from "./ListTicketServiceCache"
|
||||
import ListTicketServiceCache from "./ListTicketServiceCache";
|
||||
|
||||
import { searchTicketCache, loadTicketsCache } from '../../helpers/TicketCache'
|
||||
import { searchTicketCache, loadTicketsCache } from "../../helpers/TicketCache";
|
||||
import { getWbot } from "../../libs/wbot";
|
||||
import User from "../../models/User";
|
||||
|
||||
|
||||
|
||||
|
||||
interface Request {
|
||||
searchParam?: string;
|
||||
pageNumber?: string;
|
||||
|
@ -41,7 +40,6 @@ interface Response {
|
|||
hasMore: boolean;
|
||||
}
|
||||
|
||||
|
||||
const ListTicketsService = async ({
|
||||
searchParam = "",
|
||||
pageNumber = "1",
|
||||
|
@ -51,64 +49,65 @@ const ListTicketsService = async ({
|
|||
showAll,
|
||||
userId,
|
||||
withUnreadMessages,
|
||||
unlimited = 'false',
|
||||
unlimited = "false",
|
||||
searchParamContent = ""
|
||||
}: Request): Promise<Response> => {
|
||||
console.log("----------> searchParamContent: ", searchParamContent);
|
||||
|
||||
console.log('----------> searchParamContent: ', searchParamContent)
|
||||
let whereCondition: Filterable["where"] = {
|
||||
[Op.or]: [{ userId }, { status: "pending" }],
|
||||
queueId: { [Op.or]: [queueIds, null] }
|
||||
};
|
||||
|
||||
let whereCondition: Filterable["where"] = { [Op.or]: [{ userId }, { status: "pending" }], queueId: { [Op.or]: [queueIds, null] } };
|
||||
|
||||
console.log('PAGE NUMBER TICKET: ', pageNumber)
|
||||
console.log("PAGE NUMBER TICKET: ", pageNumber);
|
||||
|
||||
if (pageNumber.trim().length == 0) {
|
||||
pageNumber = '1'
|
||||
pageNumber = "1";
|
||||
}
|
||||
|
||||
|
||||
if (searchParam && searchParam.trim().length > 0 && process.env.CACHE) {
|
||||
|
||||
try {
|
||||
|
||||
const offset = 40 * (+pageNumber - 1);
|
||||
|
||||
searchParam = searchParam.replace(/\s+/g, ' ').trim().toLowerCase();
|
||||
searchParam = searchParam.replace(/\s+/g, " ").trim().toLowerCase();
|
||||
|
||||
console.log('QUERY TICKET SEARCH PARAM FROM CACHE: ', searchParam)
|
||||
console.log("QUERY TICKET SEARCH PARAM FROM CACHE: ", searchParam);
|
||||
|
||||
let tickets: any = await searchTicketCache(searchParam, offset, 40);
|
||||
|
||||
if (tickets) {
|
||||
console.log('QUERY TICKET SEARCH PARAM FROM CACHE LENGTH...: ', tickets.length)
|
||||
console.log(
|
||||
"QUERY TICKET SEARCH PARAM FROM CACHE LENGTH...: ",
|
||||
tickets.length
|
||||
);
|
||||
|
||||
tickets.map((t: any) => {
|
||||
t["contact.number"] = t["contact_number"];
|
||||
delete t["contact_number"];
|
||||
|
||||
t['contact.number'] = t['contact_number']
|
||||
delete t['contact_number']
|
||||
return { ...["contact_number"] };
|
||||
});
|
||||
|
||||
return { ...['contact_number'] }
|
||||
})
|
||||
tickets = tickets.map((e: any) => unflatten(e));
|
||||
|
||||
tickets = tickets.map((e: any) => unflatten(e))
|
||||
|
||||
return { tickets, count: tickets.length, hasMore: tickets.length > 0 ? true : false };
|
||||
return {
|
||||
tickets,
|
||||
count: tickets.length,
|
||||
hasMore: tickets.length > 0 ? true : false
|
||||
};
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.log('There was an error on search ListTicketservice.ts search cache: ', error)
|
||||
console.log(
|
||||
"There was an error on search ListTicketservice.ts search cache: ",
|
||||
error
|
||||
);
|
||||
}
|
||||
|
||||
console.log('QUERY TICKETS FROM DATABASE...')
|
||||
|
||||
console.log("QUERY TICKETS FROM DATABASE...");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
let includeCondition: Includeable[];
|
||||
|
||||
|
||||
|
||||
includeCondition = [
|
||||
{
|
||||
model: Contact,
|
||||
|
@ -127,10 +126,8 @@ const ListTicketsService = async ({
|
|||
}
|
||||
|
||||
if (status) {
|
||||
|
||||
whereCondition = { ...whereCondition, status };
|
||||
|
||||
|
||||
if (unlimited === "current" && status !== "pending") {
|
||||
whereCondition = {
|
||||
...whereCondition,
|
||||
|
@ -140,16 +137,15 @@ const ListTicketsService = async ({
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (searchParam) {
|
||||
const sanitizedSearchParam = searchParam.toLocaleLowerCase().trim();
|
||||
const sanitizedSearchParamContent = searchParamContent.toLocaleLowerCase().trim();
|
||||
|
||||
const sanitizedSearchParamContent = searchParamContent
|
||||
.toLocaleLowerCase()
|
||||
.trim();
|
||||
|
||||
if (searchParamContent.length > 0) {
|
||||
|
||||
includeCondition = [
|
||||
...includeCondition,
|
||||
{
|
||||
|
@ -157,7 +153,11 @@ const ListTicketsService = async ({
|
|||
as: "messages",
|
||||
attributes: ["id", "body"],
|
||||
where: {
|
||||
body: where(fn("LOWER", col("body")), "LIKE", `%${sanitizedSearchParamContent}%`)
|
||||
body: where(
|
||||
fn("LOWER", col("body")),
|
||||
"LIKE",
|
||||
`%${sanitizedSearchParamContent}%`
|
||||
)
|
||||
},
|
||||
required: false,
|
||||
duplicating: false
|
||||
|
@ -166,27 +166,30 @@ const ListTicketsService = async ({
|
|||
|
||||
whereCondition = {
|
||||
...whereCondition,
|
||||
"$message.body$": where(fn("LOWER", col("body")), "LIKE", `%${sanitizedSearchParamContent}%`)
|
||||
"$message.body$": where(
|
||||
fn("LOWER", col("body")),
|
||||
"LIKE",
|
||||
`%${sanitizedSearchParamContent}%`
|
||||
)
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
whereCondition = {
|
||||
...whereCondition,
|
||||
[Op.or]: [
|
||||
{
|
||||
"$contact.name$": where(fn("LOWER", col("contact.name")), "LIKE", `%${sanitizedSearchParam}%`)
|
||||
"$contact.name$": where(
|
||||
fn("LOWER", col("contact.name")),
|
||||
"LIKE",
|
||||
`%${sanitizedSearchParam}%`
|
||||
)
|
||||
},
|
||||
|
||||
{ "$contact.number$": { [Op.like]: `%${sanitizedSearchParam}%` } },
|
||||
|
||||
],
|
||||
{ "$contact.number$": { [Op.like]: `%${sanitizedSearchParam}%` } }
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
const userProfile: any = await User.findByPk(userId)
|
||||
const userProfile: any = await User.findByPk(userId);
|
||||
|
||||
if (
|
||||
userProfile.dataValues.profile != "admin" &&
|
||||
|
@ -195,8 +198,6 @@ const ListTicketsService = async ({
|
|||
) {
|
||||
whereCondition = { ...whereCondition, userId };
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (date) {
|
||||
|
@ -218,7 +219,13 @@ const ListTicketsService = async ({
|
|||
};
|
||||
}
|
||||
|
||||
const limit = unlimited === "current" || unlimited === "all" ? 100000 : 40;
|
||||
let limit;
|
||||
|
||||
if (unlimited === "current") limit = 10000;
|
||||
else if (unlimited === "all") limit = 100;
|
||||
else limit = 40;
|
||||
|
||||
// const limit = unlimited === "current" || unlimited === "all" ? 1000 : 40;
|
||||
const offset = limit * (+pageNumber - 1);
|
||||
|
||||
console.log("kkkkkkkkk limit: ", limit);
|
||||
|
@ -234,8 +241,6 @@ const ListTicketsService = async ({
|
|||
|
||||
const hasMore = count > offset + tickets.length;
|
||||
|
||||
|
||||
|
||||
return {
|
||||
tickets,
|
||||
count,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue