Merge remote-tracking branch 'origin/dual_session_test' into dialogflow
commit
4c510ed75b
|
@ -1,7 +1,11 @@
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import multer from "multer";
|
import multer from "multer";
|
||||||
|
|
||||||
const publicFolder = path.resolve(__dirname, "..", "..", "public");
|
// const publicFolder = path.resolve(__dirname, "..", "..", "public");
|
||||||
|
const publicFolder = path.resolve(__dirname, "..", "..","..","..", "public");
|
||||||
|
|
||||||
|
console.log('publicFolder: ',publicFolder)
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
directory: publicFolder,
|
directory: publicFolder,
|
||||||
|
|
||||||
|
|
|
@ -4,15 +4,8 @@ import { getIO } from "../libs/socket";
|
||||||
import DeleteSchedulingNotifyService from "../services/SchedulingNotifyServices/DeleteSchedulingNotifyService";
|
import DeleteSchedulingNotifyService from "../services/SchedulingNotifyServices/DeleteSchedulingNotifyService";
|
||||||
import ListSchedulingNotifyContactService from "../services/SchedulingNotifyServices/ListSchedulingNotifyContactService";
|
import ListSchedulingNotifyContactService from "../services/SchedulingNotifyServices/ListSchedulingNotifyContactService";
|
||||||
import CreateSchedulingNotifyService from "../services/SchedulingNotifyServices/CreateSchedulingNotifyService";
|
import CreateSchedulingNotifyService from "../services/SchedulingNotifyServices/CreateSchedulingNotifyService";
|
||||||
|
import ShowSchedulingNotifyService from "../services/SchedulingNotifyServices/ShowSchedulingNotifyService";
|
||||||
// const test = await ListSchedulingNotifyContactService('5517988310949','2022-03-18','2022-03-19');
|
import { deleteScheduleByTicketIdCache } from "../helpers/SchedulingNotifyCache";
|
||||||
// const test = await ListSchedulingNotifyContactService('','2022-03-18','2022-03-19');
|
|
||||||
// const test = await ListSchedulingNotifyContactService('5517988310949');
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type IndexQuery = {
|
type IndexQuery = {
|
||||||
|
@ -61,12 +54,16 @@ export const createOrUpdateScheduleNotify = async (req: Request, res: Response):
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const remove = async ( req: Request, res: Response ): Promise<Response> => {
|
export const remove = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const { scheduleId } = req.params;
|
const { scheduleId } = req.params;
|
||||||
|
|
||||||
|
let schedule: any = await ShowSchedulingNotifyService(scheduleId)
|
||||||
|
|
||||||
|
await deleteScheduleByTicketIdCache(schedule.ticketId)
|
||||||
|
|
||||||
await DeleteSchedulingNotifyService(scheduleId);
|
await DeleteSchedulingNotifyService(scheduleId);
|
||||||
|
|
||||||
return res.status(200).send();
|
return res.status(200).send();
|
||||||
|
|
|
@ -94,7 +94,7 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
await stopWhoIsOnlineMonitor()
|
// await stopWhoIsOnlineMonitor()
|
||||||
await startWhoIsOnlineMonitor()
|
await startWhoIsOnlineMonitor()
|
||||||
|
|
||||||
return res.status(200).json(user);
|
return res.status(200).json(user);
|
||||||
|
|
|
@ -0,0 +1,219 @@
|
||||||
|
|
||||||
|
import Redis from 'ioredis'
|
||||||
|
import { type } from 'os'
|
||||||
|
const unflatten = require('flat').unflatten
|
||||||
|
var flatten = require('flat')
|
||||||
|
import ListContactsServiceCache from "../services/ContactServices/ListContactsServiceCache"
|
||||||
|
import { redisConn } from './TicketCache'
|
||||||
|
|
||||||
|
import SchedulingNotify from '../models/SchedulingNotify'
|
||||||
|
|
||||||
|
import { format } from "date-fns";
|
||||||
|
import ptBR from 'date-fns/locale/pt-BR';
|
||||||
|
|
||||||
|
import { escapeCharCache } from './ContactsCache'
|
||||||
|
|
||||||
|
|
||||||
|
const deleteScheduleByTicketIdCache = async (ticketId: string | number) => {
|
||||||
|
|
||||||
|
const redis: any = await redisConn();
|
||||||
|
|
||||||
|
if (!redis) return
|
||||||
|
|
||||||
|
if (redis.status !== 'connect') return
|
||||||
|
|
||||||
|
const schedule_cache: any = await redis.hgetall(`schedule:${ticketId}`)
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (schedule_cache && Object.keys(schedule_cache).length > 0) {
|
||||||
|
|
||||||
|
await redis.del(`schedule:${ticketId}`)
|
||||||
|
|
||||||
|
console.log(`Schedule cache ticketId ${schedule_cache.ticketId} deleted!`)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log('SCHEDULE CACHE NOT FOUND!')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`There was an error on deleteScheduleByTicketIdCache: ${error}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
redis.quit()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const updateScheduleCacheByTicketId = async (scheduleNotify: any) => {
|
||||||
|
|
||||||
|
const redis: any = await redisConn();
|
||||||
|
|
||||||
|
if (!redis) return
|
||||||
|
|
||||||
|
if (redis.status !== 'connect') return
|
||||||
|
|
||||||
|
const pipeline = redis.pipeline()
|
||||||
|
|
||||||
|
let entries = Object.entries(scheduleNotify)
|
||||||
|
|
||||||
|
entries.forEach((e: any) => {
|
||||||
|
pipeline.hset(`schedule:${scheduleNotify.ticketId}`, e[0], e[1])
|
||||||
|
})
|
||||||
|
|
||||||
|
await pipeline.exec(() => { console.log("schedule Key/value inserted/updated") });
|
||||||
|
|
||||||
|
redis.quit()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const createSchedulingNotifyCache = async (scheduleNotify: any) => {
|
||||||
|
|
||||||
|
const redis: any = await redisConn();
|
||||||
|
|
||||||
|
if (!redis) return
|
||||||
|
|
||||||
|
if (redis.status !== 'connect') return
|
||||||
|
|
||||||
|
let date_time: any = format(new Date(scheduleNotify.schedulingTime), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR }).split(' ')
|
||||||
|
|
||||||
|
delete scheduleNotify.schedulingTime
|
||||||
|
delete scheduleNotify.updatedAt
|
||||||
|
delete scheduleNotify.createdAt
|
||||||
|
delete scheduleNotify.schedulingDate
|
||||||
|
|
||||||
|
console.log('created date_time: ', date_time)
|
||||||
|
|
||||||
|
scheduleNotify.date = date_time[0]
|
||||||
|
scheduleNotify.date_escaped = escapeCharCache(date_time[0])
|
||||||
|
scheduleNotify.hour = date_time[1].split(':')[0]
|
||||||
|
scheduleNotify.minute = date_time[1].split(':')[1]
|
||||||
|
|
||||||
|
await redis.hmset(`schedule:${scheduleNotify.ticketId}`, scheduleNotify);
|
||||||
|
|
||||||
|
console.log(`${scheduleNotify.length} SCHEDULE NOTIFY INSERTED IN CACHE!`)
|
||||||
|
|
||||||
|
redis.quit()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function searchScheduleCache(date: string, hour: number | string, minute: number | string) {
|
||||||
|
|
||||||
|
const redis: any = await redisConn();
|
||||||
|
|
||||||
|
if (!redis) return
|
||||||
|
|
||||||
|
if (redis.status !== 'connect') return null
|
||||||
|
|
||||||
|
date = escapeCharCache(date).trim()
|
||||||
|
|
||||||
|
const response: any = await redis.call('FT.SEARCH', 'idx_schedule', `(@date_escaped:${date}) (@hour:${hour}) (@minute:${minute})`)
|
||||||
|
redis.quit()
|
||||||
|
|
||||||
|
|
||||||
|
if (response.length === 1) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const results: any = []
|
||||||
|
|
||||||
|
for (let n = 2; n < response.length; n += 2) {
|
||||||
|
const result: any = {}
|
||||||
|
const fieldNamesAndValues = response[n]
|
||||||
|
|
||||||
|
for (let m = 0; m < fieldNamesAndValues.length; m += 2) {
|
||||||
|
const k = fieldNamesAndValues[m]
|
||||||
|
const v = fieldNamesAndValues[m + 1]
|
||||||
|
result[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
results.push(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadSchedulesCache = async () => {
|
||||||
|
|
||||||
|
await createScheduleIndexCache('idx_schedule')
|
||||||
|
|
||||||
|
const redis: any = await redisConn();
|
||||||
|
|
||||||
|
if (!redis) return
|
||||||
|
|
||||||
|
if (redis.status !== 'connect') return
|
||||||
|
|
||||||
|
let schedules: any = await SchedulingNotify.findAll({ raw: true, attributes: ["id", "statusChatEndId", "ticketId", "schedulingTime", "message"] });
|
||||||
|
|
||||||
|
// console.log('SCHEDULE NOTIFY CACHE2: ', schedules)
|
||||||
|
|
||||||
|
|
||||||
|
const pipeline = redis.pipeline()
|
||||||
|
|
||||||
|
for (let i = 0; i < schedules.length; i++) {
|
||||||
|
|
||||||
|
let date_time: any = format(new Date(schedules[i].schedulingTime), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR }).split(' ')
|
||||||
|
|
||||||
|
delete schedules[i].schedulingTime
|
||||||
|
|
||||||
|
console.log('date_time: ', date_time)
|
||||||
|
|
||||||
|
schedules[i].date = date_time[0]
|
||||||
|
schedules[i].date_escaped = escapeCharCache(date_time[0])
|
||||||
|
|
||||||
|
schedules[i].hour = date_time[1].split(':')[0]
|
||||||
|
schedules[i].minute = date_time[1].split(':')[1]
|
||||||
|
|
||||||
|
pipeline.hmset(`schedule:${schedules[i].ticketId}`, schedules[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
await pipeline.exec(() => { console.log(`${schedules.length} SCHEDULES NOTIFY INSERTED IN CACHE!`) });
|
||||||
|
|
||||||
|
redis.quit()
|
||||||
|
|
||||||
|
|
||||||
|
// let test = await searchScheduleCache('2022-12-16', '18', '30')
|
||||||
|
|
||||||
|
// console.log('--------------> TEST: ', test)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const createScheduleIndexCache = async (hashIndex: string) => {
|
||||||
|
|
||||||
|
const redis: any = await redisConn();
|
||||||
|
|
||||||
|
if (!redis) return
|
||||||
|
|
||||||
|
if (redis.status !== 'connect') return
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
const lst_index_redis: any = await redis.call('FT._LIST')
|
||||||
|
|
||||||
|
if (lst_index_redis.includes(hashIndex)) {
|
||||||
|
console.log('entrou...')
|
||||||
|
await redis.call('FT.DROPINDEX', hashIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await redis.call('FT.CREATE', hashIndex, 'ON', 'HASH', 'PREFIX', '1', 'schedule:', 'SCHEMA', 'id', 'TEXT', 'SORTABLE', 'date_escaped', 'TEXT', 'SORTABLE', 'hour', 'TEXT', 'SORTABLE', 'minute', 'TEXT', 'SORTABLE')
|
||||||
|
|
||||||
|
console.log('Schedule index created: ', response)
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log('There was an error on createScheduleIndexCache: ', error)
|
||||||
|
}
|
||||||
|
|
||||||
|
redis.quit()
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
loadSchedulesCache,
|
||||||
|
searchScheduleCache,
|
||||||
|
updateScheduleCacheByTicketId,
|
||||||
|
createSchedulingNotifyCache,
|
||||||
|
deleteScheduleByTicketIdCache
|
||||||
|
}
|
|
@ -8,6 +8,8 @@ import { getIO } from "../libs/socket";
|
||||||
import ListWhatsAppsService from "../services/WhatsappService/ListWhatsAppsService";
|
import ListWhatsAppsService from "../services/WhatsappService/ListWhatsAppsService";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { convertBytes } from "./ConvertBytes";
|
import { convertBytes } from "./ConvertBytes";
|
||||||
|
import { deleteScheduleByTicketIdCache } from "./SchedulingNotifyCache";
|
||||||
|
import SchedulingNotify from "../models/SchedulingNotify";
|
||||||
|
|
||||||
const fastFolderSize = require('fast-folder-size')
|
const fastFolderSize = require('fast-folder-size')
|
||||||
const { promisify } = require('util')
|
const { promisify } = require('util')
|
||||||
|
@ -15,6 +17,8 @@ const fs = require('fs')
|
||||||
|
|
||||||
const { exec } = require("child_process");
|
const { exec } = require("child_process");
|
||||||
|
|
||||||
|
let _fifo: any
|
||||||
|
|
||||||
let scheduler_monitor: any;
|
let scheduler_monitor: any;
|
||||||
let timeInterval = 5
|
let timeInterval = 5
|
||||||
|
|
||||||
|
@ -36,23 +40,35 @@ const monitor = async () => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// const { schedulingNotifies, count, hasMore } = await ListSchedulingNotifyService({ searchParam: dateParm, pageNumber: "1" });
|
const { schedulingNotifies, count, hasMore } = await ListSchedulingNotifyService({ searchParam: dateParm, pageNumber: "1" });
|
||||||
|
|
||||||
// // console.log('schedulingNotifies: ',schedulingNotifies)
|
if (schedulingNotifies && schedulingNotifies.length > 0) {
|
||||||
|
|
||||||
// if (schedulingNotifies && schedulingNotifies.length > 0) {
|
for (let i = 0; i < schedulingNotifies.length; i++) {
|
||||||
|
|
||||||
// const ticket = await ShowTicketService(schedulingNotifies[0].ticketId);
|
|
||||||
|
|
||||||
// SetTicketMessagesAsRead(ticket);
|
const ticket = await ShowTicketService(+schedulingNotifies[i].ticketId);
|
||||||
|
|
||||||
// await SendWhatsAppMessage({
|
await new Promise(f => setTimeout(f, 3000));
|
||||||
// body: schedulingNotifies[0].message, ticket
|
|
||||||
// });
|
|
||||||
|
|
||||||
// DeleteSchedulingNotifyService(schedulingNotifies[0].id)
|
if(!ticket.queue){
|
||||||
|
await ticket.update({status: 'open'})
|
||||||
|
}
|
||||||
|
|
||||||
// }
|
SetTicketMessagesAsRead(ticket);
|
||||||
|
|
||||||
|
await SendWhatsAppMessage({
|
||||||
|
body: schedulingNotifies[i].message, ticket
|
||||||
|
});
|
||||||
|
|
||||||
|
await deleteScheduleByTicketIdCache(schedulingNotifies[i].ticketId)
|
||||||
|
|
||||||
|
await DeleteSchedulingNotifyService(schedulingNotifies[i].id)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
exec("df -h /", (error: any, stdout: any, stderr: any) => {
|
exec("df -h /", (error: any, stdout: any, stderr: any) => {
|
||||||
|
@ -132,27 +148,32 @@ const monitor = async () => {
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('>>> SchedulingNotifiySendMessage.ts error: ', error)
|
console.log('>>> SchedulingNotifiySendMessage.ts error: ', error)
|
||||||
stopSchedulingMonitor()
|
|
||||||
startSchedulingMonitor(timeInterval)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export const startSchedulingMonitor = async (mileseconds: number) => {
|
const SchedulingNotifySendMessage = async () => {
|
||||||
|
|
||||||
timeInterval = mileseconds
|
try {
|
||||||
|
clearInterval(_fifo);
|
||||||
|
|
||||||
scheduler_monitor = setInterval(monitor, mileseconds)
|
await monitor()
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log('error on SchedulingNotifySendMessage: ', error)
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
_fifo = setInterval(SchedulingNotifySendMessage, 5000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_fifo = setInterval(SchedulingNotifySendMessage, 5000);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = SchedulingNotifySendMessage
|
||||||
|
|
||||||
export const stopSchedulingMonitor = async () => {
|
|
||||||
|
|
||||||
clearInterval(scheduler_monitor)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { date } from "faker";
|
||||||
import sumOnlineTimeNow from '../helpers/SumOlineTimeNow'
|
import sumOnlineTimeNow from '../helpers/SumOlineTimeNow'
|
||||||
import UserOnlineTime from "../models/UserOnlineTime";
|
import UserOnlineTime from "../models/UserOnlineTime";
|
||||||
|
|
||||||
|
let _fifo: any
|
||||||
|
|
||||||
let whoIsOnline_monitor: any;
|
let whoIsOnline_monitor: any;
|
||||||
// const listUserId:any[] = [{'id':8, status: 'offline'},{'id':3, status: 'offline'},{'id':5, status: 'offline'}]
|
// const listUserId:any[] = [{'id':8, status: 'offline'},{'id':3, status: 'offline'},{'id':5, status: 'offline'}]
|
||||||
|
@ -175,38 +175,70 @@ const monitor = async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('>>> There was an error no WhoIsOnlineMonitor.ts: ',error)
|
console.log('>>> There was an error no WhoIsOnlineMonitor.ts: ', error)
|
||||||
stopWhoIsOnlineMonitor()
|
|
||||||
startWhoIsOnlineMonitor()
|
listUserId = []
|
||||||
|
count = 0
|
||||||
|
countTest = 0
|
||||||
|
uuid = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export const startWhoIsOnlineMonitor = async (mileseconds?: number) => {
|
|
||||||
|
const WhoIsOnlineMonitor = async () => {
|
||||||
|
|
||||||
|
try {
|
||||||
|
clearInterval(_fifo);
|
||||||
|
|
||||||
|
await monitor()
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log('error on WhoIsOnlineMonitor: ', error)
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
_fifo = setInterval(WhoIsOnlineMonitor, 3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_fifo = setInterval(WhoIsOnlineMonitor, 3000);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const startWhoIsOnlineMonitor = async (mileseconds?: number) => {
|
||||||
|
|
||||||
listUserId = []
|
listUserId = []
|
||||||
count = 0
|
count = 0
|
||||||
countTest = 0
|
countTest = 0
|
||||||
uuid = 0
|
uuid = 0
|
||||||
|
|
||||||
if (mileseconds) {
|
clearInterval(_fifo);
|
||||||
timeInterval = mileseconds
|
_fifo = setInterval(WhoIsOnlineMonitor, 3000);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
whoIsOnline_monitor = setInterval(monitor, timeInterval)
|
|
||||||
|
|
||||||
|
// if (mileseconds) {
|
||||||
|
// timeInterval = mileseconds
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const stopWhoIsOnlineMonitor = async () => {
|
const stopWhoIsOnlineMonitor = async () => {
|
||||||
|
|
||||||
clearInterval(whoIsOnline_monitor)
|
clearInterval(_fifo);
|
||||||
|
// _fifo = setInterval(WhoIsOnlineMonitor, 3000);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export { WhoIsOnlineMonitor, startWhoIsOnlineMonitor, stopWhoIsOnlineMonitor }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,8 @@ import app from "./app";
|
||||||
import { initIO } from "./libs/socket";
|
import { initIO } from "./libs/socket";
|
||||||
import { logger } from "./utils/logger";
|
import { logger } from "./utils/logger";
|
||||||
import { StartAllWhatsAppsSessions } from "./services/WbotServices/StartAllWhatsAppsSessions";
|
import { StartAllWhatsAppsSessions } from "./services/WbotServices/StartAllWhatsAppsSessions";
|
||||||
|
import "./helpers/SchedulingNotifySendMessage"
|
||||||
import { startSchedulingMonitor } from "./helpers/SchedulingNotifySendMessage"
|
import "./helpers/WhoIsOnlineMonitor"
|
||||||
import { startWhoIsOnlineMonitor } from "./helpers/WhoIsOnlineMonitor"
|
|
||||||
|
|
||||||
import { loadTicketsCache, flushCache, cacheSize } from './helpers/TicketCache'
|
import { loadTicketsCache, flushCache, cacheSize } from './helpers/TicketCache'
|
||||||
import { loadContactsCache } from './helpers/ContactsCache'
|
import { loadContactsCache } from './helpers/ContactsCache'
|
||||||
|
|
||||||
|
@ -14,6 +12,7 @@ import "./helpers/CloseBotTickets";
|
||||||
import { loadWhatsappCache } from './helpers/WhatsCache'
|
import { loadWhatsappCache } from './helpers/WhatsCache'
|
||||||
import { delRestoreControllFile } from "./helpers/RestoreControll";
|
import { delRestoreControllFile } from "./helpers/RestoreControll";
|
||||||
import { createSessionDir } from "./helpers/CreateSessionDir";
|
import { createSessionDir } from "./helpers/CreateSessionDir";
|
||||||
|
import { loadSchedulesCache, } from "./helpers/SchedulingNotifyCache";
|
||||||
|
|
||||||
const server = app.listen(process.env.PORT, () => {
|
const server = app.listen(process.env.PORT, () => {
|
||||||
logger.info(`Server started on port: ${process.env.PORT}`);
|
logger.info(`Server started on port: ${process.env.PORT}`);
|
||||||
|
@ -31,19 +30,19 @@ gracefulShutdown(server);
|
||||||
|
|
||||||
console.log('cacheSize: ', cacheLength)
|
console.log('cacheSize: ', cacheLength)
|
||||||
|
|
||||||
if(cacheLength == 0){
|
if (cacheLength == 0) {
|
||||||
console.log('Loading from cache...')
|
console.log('Loading from cache...')
|
||||||
await flushCache()
|
await flushCache()
|
||||||
await loadContactsCache()
|
await loadContactsCache()
|
||||||
await loadTicketsCache()
|
await loadTicketsCache()
|
||||||
await loadWhatsappCache()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await loadWhatsappCache()
|
||||||
|
await loadSchedulesCache()
|
||||||
|
|
||||||
})()
|
})()
|
||||||
|
|
||||||
createSessionDir()
|
createSessionDir()
|
||||||
delRestoreControllFile()
|
delRestoreControllFile()
|
||||||
|
|
||||||
startSchedulingMonitor(5000)
|
|
||||||
startWhoIsOnlineMonitor(3000)
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import AppError from "../../errors/AppError";
|
import AppError from "../../errors/AppError";
|
||||||
|
import { createSchedulingNotifyCache } from "../../helpers/SchedulingNotifyCache";
|
||||||
import SchedulingNotify from "../../models/SchedulingNotify";
|
import SchedulingNotify from "../../models/SchedulingNotify";
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,9 +57,10 @@ const CreateSchedulingNotifyService = async ({
|
||||||
message
|
message
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await createSchedulingNotifyCache(JSON.parse(JSON.stringify(schedulingNotify)))
|
||||||
|
|
||||||
|
|
||||||
return schedulingNotify
|
return schedulingNotify
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
import { Op, Sequelize } from "sequelize";
|
import { Op, Sequelize } from "sequelize";
|
||||||
|
import { searchScheduleCache } from "../../helpers/SchedulingNotifyCache";
|
||||||
import SchedulingNotify from "../../models/SchedulingNotify";
|
import SchedulingNotify from "../../models/SchedulingNotify";
|
||||||
|
|
||||||
interface Request {
|
interface Request {
|
||||||
searchParam?: string;
|
searchParam?: string;
|
||||||
pageNumber?: string;
|
pageNumber?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Response {
|
interface Response {
|
||||||
schedulingNotifies: SchedulingNotify[];
|
schedulingNotifies: SchedulingNotify[];
|
||||||
count: number;
|
count: number;
|
||||||
hasMore: boolean;
|
hasMore: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ListSchedulingNotifyService = async ({
|
const ListSchedulingNotifyService = async ({
|
||||||
searchParam = "",
|
searchParam = "",
|
||||||
pageNumber = "1"
|
pageNumber = "1"
|
||||||
}: Request): Promise<Response> => {
|
}: Request): Promise<Response> => {
|
||||||
// const whereCondition = {
|
// const whereCondition = {
|
||||||
// message: Sequelize.where(
|
// message: Sequelize.where(
|
||||||
|
|
||||||
|
@ -29,6 +30,21 @@ interface Request {
|
||||||
let hour = searchParam.split(' ')[1].split(':')[0]
|
let hour = searchParam.split(' ')[1].split(':')[0]
|
||||||
let minute = searchParam.split(' ')[1].split(':')[1]
|
let minute = searchParam.split(' ')[1].split(':')[1]
|
||||||
|
|
||||||
|
let fromCache = null
|
||||||
|
|
||||||
|
fromCache = await searchScheduleCache(date, hour, minute)
|
||||||
|
|
||||||
|
if (fromCache) {
|
||||||
|
|
||||||
|
return {
|
||||||
|
schedulingNotifies: fromCache,
|
||||||
|
count: 0,
|
||||||
|
hasMore: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const whereCondition = {
|
const whereCondition = {
|
||||||
[Op.and]: [
|
[Op.and]: [
|
||||||
{
|
{
|
||||||
|
@ -62,7 +78,6 @@ interface Request {
|
||||||
count,
|
count,
|
||||||
hasMore
|
hasMore
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ListSchedulingNotifyService;
|
|
||||||
|
|
||||||
|
export default ListSchedulingNotifyService;
|
||||||
|
|
|
@ -128,8 +128,14 @@ const verifyMediaMessage = async (
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// await writeFileAsync(
|
||||||
|
// join(__dirname, "..", "..", "..", "public", media.filename),
|
||||||
|
// media.data,
|
||||||
|
// "base64"
|
||||||
|
// );
|
||||||
|
|
||||||
await writeFileAsync(
|
await writeFileAsync(
|
||||||
join(__dirname, "..", "..", "..", "public", media.filename),
|
join(__dirname, "..", "..", "..", "..", "..", "public", media.filename),
|
||||||
media.data,
|
media.data,
|
||||||
"base64"
|
"base64"
|
||||||
);
|
);
|
||||||
|
@ -821,20 +827,12 @@ const botSendMessage = (ticket: Ticket, contact: Contact, wbot: Session, msg: st
|
||||||
|
|
||||||
const _clear_lst = () => {
|
const _clear_lst = () => {
|
||||||
|
|
||||||
console.log('WHATSAPP MESSAGE ID MULTI SESSION: ', lst.length)
|
|
||||||
|
|
||||||
if (lst.length <= 200 ) return
|
if (lst.length <= 200 ) return
|
||||||
|
|
||||||
console.log('BEFORE lst SLICE: ', lst)
|
|
||||||
|
|
||||||
console.log('lst whatsapp message id sliced! | lst.length: ', lst.length)
|
|
||||||
|
|
||||||
const chunk: any = Math.floor((lst.length / 2))
|
const chunk: any = Math.floor((lst.length / 2))
|
||||||
|
|
||||||
lst = lst.slice(chunk, chunk + lst.length);
|
lst = lst.slice(chunk, chunk + lst.length);
|
||||||
|
|
||||||
console.log('AFTER lst SLICE: ', lst)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -884,37 +882,6 @@ const handleMessage = async (
|
||||||
|
|
||||||
console.log('PASSOU.................................FROM: ', msg.from.split("@")[0], ' | ID: ', msg.id.id)
|
console.log('PASSOU.................................FROM: ', msg.from.split("@")[0], ' | ID: ', msg.id.id)
|
||||||
|
|
||||||
// const contact_message = await getLastId(`contact_message:5517988310949`)
|
|
||||||
|
|
||||||
// if (contact_message && contact_message.id == msg.id.id) {
|
|
||||||
// console.log('IGNORED MESSAGE SAME ID FROM CLIENT: ', contact_message.id)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// await insertMessageContactCache(`contact_message:5517988310949`,
|
|
||||||
// {
|
|
||||||
// from: msg.from.split("@")[0],
|
|
||||||
// to: msg.to.split("@")[0],
|
|
||||||
// id: msg.id.id
|
|
||||||
// })
|
|
||||||
|
|
||||||
// console.log('PASSOU............................................... contact_message.id: ',contact_message.id)
|
|
||||||
|
|
||||||
|
|
||||||
// if (testLastId == msg.id.id) {
|
|
||||||
// console.log('IGNORED MESSAGE SAME ID!')
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// testLastId = msg.id.id
|
|
||||||
|
|
||||||
// console.log('PASSOU............................................... msg.id.id: ',msg.id.id)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!isValidMsg(msg)) {
|
if (!isValidMsg(msg)) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -26,6 +26,8 @@ import ErrorIcon from "@material-ui/icons/Error";
|
||||||
import RemoveCircleIcon from "@material-ui/icons/RemoveCircle";
|
import RemoveCircleIcon from "@material-ui/icons/RemoveCircle";
|
||||||
import PowerSettingsNewIcon from "@material-ui/icons/PowerSettingsNew";
|
import PowerSettingsNewIcon from "@material-ui/icons/PowerSettingsNew";
|
||||||
|
|
||||||
|
import { i18n } from "../../translate/i18n";
|
||||||
|
|
||||||
const TableUser = ({ classes, usersOnlineInfo, logout }) => {
|
const TableUser = ({ classes, usersOnlineInfo, logout }) => {
|
||||||
const [search, setSearch] = React.useState("");
|
const [search, setSearch] = React.useState("");
|
||||||
const [filterStatus, setFilterStatus] = React.useState(null);
|
const [filterStatus, setFilterStatus] = React.useState(null);
|
||||||
|
@ -48,7 +50,8 @@ const TableUser = ({ classes, usersOnlineInfo, logout }) => {
|
||||||
color="primary"
|
color="primary"
|
||||||
style={{ marginBottom: "16px" }}
|
style={{ marginBottom: "16px" }}
|
||||||
>
|
>
|
||||||
Lista de Usuários
|
|
||||||
|
{i18n.t("dashboard.table_users.title")}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item sx={8} width="100%">
|
<Grid item sx={8} width="100%">
|
||||||
|
@ -84,12 +87,12 @@ const TableUser = ({ classes, usersOnlineInfo, logout }) => {
|
||||||
<Table>
|
<Table>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow className={classes.tableRowHead}>
|
<TableRow className={classes.tableRowHead}>
|
||||||
<TableCell>Nome</TableCell>
|
<TableCell>{i18n.t("dashboard.table_users.column0")}</TableCell>
|
||||||
<TableCell>Em Atendimento/Finalizado(s)</TableCell>
|
<TableCell>{i18n.t("dashboard.table_users.column1")}</TableCell>
|
||||||
<TableCell>abertos Por Fila</TableCell>
|
<TableCell>{i18n.t("dashboard.table_users.column2")}</TableCell>
|
||||||
<TableCell>Fechados Por Fila</TableCell>
|
<TableCell>{i18n.t("dashboard.table_users.column3")}</TableCell>
|
||||||
<TableCell>Tempo Online</TableCell>
|
<TableCell>{i18n.t("dashboard.table_users.column4")}</TableCell>
|
||||||
<TableCell>Ações</TableCell>
|
<TableCell>{i18n.t("dashboard.table_users.column5")}</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ import chat from '@material-ui/icons/Chat';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import { i18n } from '../../../translate/i18n';
|
||||||
|
|
||||||
const MTable = (props) => {
|
const MTable = (props) => {
|
||||||
|
|
||||||
const tableRef = React.useRef();
|
const tableRef = React.useRef();
|
||||||
|
@ -79,7 +81,7 @@ const MTable = (props) => {
|
||||||
if (props.hasChild) {
|
if (props.hasChild) {
|
||||||
render(<Modal data={selectedRow.messages}
|
render(<Modal data={selectedRow.messages}
|
||||||
hasChild={false}
|
hasChild={false}
|
||||||
modal_header={'Chat do atendimento pelo Whatsapp'}
|
modal_header={i18n.t("reports.listTitles.title2_1")}
|
||||||
user={selectedRow.user.name}
|
user={selectedRow.user.name}
|
||||||
clientContactNumber={selectedRow.contact.number} />)
|
clientContactNumber={selectedRow.contact.number} />)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,23 +10,25 @@ import DialogTitle from '@mui/material/DialogTitle';
|
||||||
//import DataGridTable from '../Table';
|
//import DataGridTable from '../Table';
|
||||||
import MTable from "../MTable";
|
import MTable from "../MTable";
|
||||||
|
|
||||||
|
import { i18n } from '../../../translate/i18n';
|
||||||
|
|
||||||
import ExportCSV from '../ExportCSV'
|
import ExportCSV from '../ExportCSV'
|
||||||
//import { margin } from '@mui/system';
|
//import { margin } from '@mui/system';
|
||||||
|
|
||||||
let columns = [
|
let columns = [
|
||||||
{
|
{
|
||||||
title: 'Atendente/Cliente',
|
title: `${i18n.t("reports.listColumns.column2_1")}`,
|
||||||
field: 'fromMe',
|
field: 'fromMe',
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: 'Mensagem',
|
title: `${i18n.t("reports.listColumns.column0_8")}`,
|
||||||
field: 'body',
|
field: 'body',
|
||||||
//cellStyle: {whiteSpace: 'nowrap'},
|
//cellStyle: {whiteSpace: 'nowrap'},
|
||||||
},
|
},
|
||||||
|
|
||||||
{ title: 'Criado', field: 'createdAt' }
|
{ title: `${i18n.t("reports.listColumns.column1_7")}`, field: 'createdAt' }
|
||||||
|
|
||||||
/*cellStyle: {
|
/*cellStyle: {
|
||||||
backgroundColor: '#039be5',
|
backgroundColor: '#039be5',
|
||||||
|
|
|
@ -23,6 +23,9 @@ import fileDownload from 'js-file-download'
|
||||||
|
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from "socket.io-client";
|
||||||
|
|
||||||
|
import { i18n } from "../../translate/i18n";
|
||||||
|
|
||||||
|
|
||||||
const report = [{ 'value': '1', 'label': 'Atendimento por atendentes' }, { 'value': '2', 'label': 'Usuários online/offline' }]
|
const report = [{ 'value': '1', 'label': 'Atendimento por atendentes' }, { 'value': '2', 'label': 'Usuários online/offline' }]
|
||||||
|
|
||||||
|
|
||||||
|
@ -206,17 +209,17 @@ Item.propTypes = {
|
||||||
|
|
||||||
|
|
||||||
let columnsData = [
|
let columnsData = [
|
||||||
{ title: 'Unidade', field: 'whatsapp.name' },
|
{ title: `${i18n.t("reports.listColumns.column1_1")}`, field: 'whatsapp.name' },
|
||||||
{ title: 'Atendente', field: 'user.name' },
|
{ title: `${i18n.t("reports.listColumns.column1_2")}`, field: 'user.name' },
|
||||||
{ title: 'Contato', field: 'contact.number' },
|
{ title: `${i18n.t("reports.listColumns.column0_4")}`, field: 'contact.number' },
|
||||||
{ title: 'Nome', field: 'contact.name' },
|
{ title: `${i18n.t("reports.listColumns.column0_3")}`, field: 'contact.name' },
|
||||||
{ title: 'Assunto', field: 'queue.name' },
|
{ title: `${i18n.t("reports.listColumns.column1_5")}`, field: 'queue.name' },
|
||||||
|
|
||||||
{ title: 'Status', field: 'status' },
|
{ title: 'Status', field: 'status' },
|
||||||
|
|
||||||
{ title: 'Criado', field: 'createdAt' },
|
{ title: `${i18n.t("reports.listColumns.column1_7")}`, field: 'createdAt' },
|
||||||
{title: 'Atualizado', field: 'updatedAt'},
|
{title: `${i18n.t("reports.listColumns.column1_8")}`, field: 'updatedAt'},
|
||||||
{ title: 'Status de encerramento', field: 'statusChatEnd' }];
|
{ title: `${i18n.t("reports.listColumns.column1_9")}`, field: 'statusChatEnd' }];
|
||||||
|
|
||||||
|
|
||||||
const Report = () => {
|
const Report = () => {
|
||||||
|
@ -630,12 +633,12 @@ const Report = () => {
|
||||||
<MainContainer>
|
<MainContainer>
|
||||||
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)' }}>
|
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)' }}>
|
||||||
|
|
||||||
<Item><SelectField func={textFieldSelectUser} emptyField={true} header={'Usuário'} currencies={users.map((obj) => {
|
<Item><SelectField func={textFieldSelectUser} emptyField={true} header={i18n.t("reports.user")} currencies={users.map((obj) => {
|
||||||
return { 'value': obj.id, 'label': obj.name }
|
return { 'value': obj.id, 'label': obj.name }
|
||||||
})} /></Item>
|
})} /></Item>
|
||||||
|
|
||||||
<Item><DatePicker1 func={datePicker1Value} minDate={false} startEmpty={false} title={'Data inicio'} /></Item>
|
<Item><DatePicker1 func={datePicker1Value} minDate={false} startEmpty={false} title={i18n.t("reports.dateStart")} /></Item>
|
||||||
<Item><DatePicker2 func={datePicker2Value} minDate={false} startEmpty={false} title={'Data fim'} /></Item>
|
<Item><DatePicker2 func={datePicker2Value} minDate={false} startEmpty={false} title={i18n.t("reports.dateEnd")} /></Item>
|
||||||
|
|
||||||
<Item sx={{ display: 'grid', gridColumn: '4 / 5', }}>
|
<Item sx={{ display: 'grid', gridColumn: '4 / 5', }}>
|
||||||
|
|
||||||
|
@ -672,7 +675,7 @@ const Report = () => {
|
||||||
|
|
||||||
handleScroll={handleScroll}
|
handleScroll={handleScroll}
|
||||||
|
|
||||||
table_title={'Atendimento por atendentes'} />
|
table_title={i18n.t("reports.listTitles.title1_1")} />
|
||||||
|
|
||||||
</>
|
</>
|
||||||
|
|
||||||
|
@ -689,7 +692,7 @@ const Report = () => {
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
title="Usuários online/offline"
|
title={i18n.t("reports.listTitles.title3_1")}
|
||||||
columns={
|
columns={
|
||||||
[
|
[
|
||||||
|
|
||||||
|
@ -724,8 +727,8 @@ const Report = () => {
|
||||||
},
|
},
|
||||||
|
|
||||||
{ title: 'Tempo online', field: 'sumOnlineTime.sum' },
|
{ title: 'Tempo online', field: 'sumOnlineTime.sum' },
|
||||||
{ title: 'Data inicio', field: 'startDate' },
|
{ title: `${i18n.t("reports.dateStart")}`, field: 'startDate' },
|
||||||
{ title: 'Data fim', field: 'endDate' },
|
{ title: `${i18n.t("reports.dateStart")}`, field: 'endDate' },
|
||||||
{ title: 'Em atendimento', field: 'sumOpen.count' },
|
{ title: 'Em atendimento', field: 'sumOpen.count' },
|
||||||
{ title: 'Finalizado', field: 'sumClosed.count' },
|
{ title: 'Finalizado', field: 'sumClosed.count' },
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ import { toast } from "react-toastify";
|
||||||
import toastError from "../../errors/toastError";
|
import toastError from "../../errors/toastError";
|
||||||
import ConfirmationModal from "../../components/ConfirmationModal";
|
import ConfirmationModal from "../../components/ConfirmationModal";
|
||||||
|
|
||||||
|
import { i18n } from "../../translate/i18n";
|
||||||
|
|
||||||
const reducerQ = (state, action) => {
|
const reducerQ = (state, action) => {
|
||||||
|
|
||||||
|
@ -467,8 +467,8 @@ const SchedulesReminder = () => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Item><DatePicker1 func={datePicker1Value} minDate={false} startEmpty={true} reset={resetChild} setReset={setReset} title={i18n.t("report.date.dateStart")} /></Item>
|
<Item><DatePicker1 func={datePicker1Value} minDate={false} startEmpty={true} reset={resetChild} setReset={setReset} title={i18n.t("reports.dateStart")} /></Item>
|
||||||
<Item><DatePicker2 func={datePicker2Value} minDate={false} startEmpty={true} reset={resetChild} setReset={setReset} title={'Data fim'} /></Item>
|
<Item><DatePicker2 func={datePicker2Value} minDate={false} startEmpty={true} reset={resetChild} setReset={setReset} title={i18n.t("reports.dateEnd")} /></Item>
|
||||||
|
|
||||||
<Item sx={{ gridColumn: '4 / 5' }}>
|
<Item sx={{ gridColumn: '4 / 5' }}>
|
||||||
{/* <Button size="small" variant="contained" onClick={()=>{handleQuery()}}>GO</Button>*/}
|
{/* <Button size="small" variant="contained" onClick={()=>{handleQuery()}}>GO</Button>*/}
|
||||||
|
@ -503,18 +503,26 @@ const SchedulesReminder = () => {
|
||||||
</ConfirmationModal>
|
</ConfirmationModal>
|
||||||
|
|
||||||
<MaterialTable
|
<MaterialTable
|
||||||
// title="Lembretes/Agendamentos"
|
|
||||||
title={i18n.t("report.listTitle.title1")}
|
localization={{
|
||||||
|
|
||||||
|
header: {
|
||||||
|
actions: `${i18n.t("reports.listColumns.column0_1")}`
|
||||||
|
},
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
title={i18n.t("reports.listTitles.title0_1")}
|
||||||
columns={
|
columns={
|
||||||
[
|
[
|
||||||
|
|
||||||
{ title: 'Foto', field: 'ticket.contact.profilePicUrl', render: rowData => <img src={rowData['ticket.contact.profilePicUrl']} alt="imagem de perfil do whatsapp" style={{ width: 40, borderRadius: '50%' }} /> },
|
{ title: `${i18n.t("reports.listColumns.column0_2")}`, field: 'ticket.contact.profilePicUrl', render: rowData => <img src={rowData['ticket.contact.profilePicUrl']} alt="imagem de perfil do whatsapp" style={{ width: 40, borderRadius: '50%' }} /> },
|
||||||
{ title: 'Nome', field: 'ticket.contact.name' },
|
{ title: `${i18n.t("reports.listColumns.column0_3")}`, field: 'ticket.contact.name' },
|
||||||
{ title: 'Contato', field: 'ticket.contact.number' },
|
{ title: `${i18n.t("reports.listColumns.column0_4")}`, field: 'ticket.contact.number' },
|
||||||
{ title: 'Lemb/Agen', field: 'scheduleReminder' },
|
{ title: `${i18n.t("reports.listColumns.column0_5")}`, field: 'scheduleReminder' },
|
||||||
{ title: 'Envio', field: 'schedulingTime' },
|
{ title: `${i18n.t("reports.listColumns.column0_6")}`, field: 'schedulingTime' },
|
||||||
{ title: 'Data', field: 'schedulingDate' },
|
{ title: `${i18n.t("reports.listColumns.column0_7")}`, field: 'schedulingDate' },
|
||||||
{ title: 'Mensagem', field: 'message', width: "80%" },
|
{ title: `${i18n.t("reports.listColumns.column0_8")}`, field: 'message', width: "80%" },
|
||||||
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,16 @@ const messages = {
|
||||||
closed: {
|
closed: {
|
||||||
title: "Closed"
|
title: "Closed"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
table_users:{
|
||||||
|
title: 'User List',
|
||||||
|
column0: 'Name',
|
||||||
|
column1: 'In Service/Finished',
|
||||||
|
column2: 'Open by Queue',
|
||||||
|
column3: 'Closed by Queue',
|
||||||
|
column4: 'Online time',
|
||||||
|
column5: 'Actions',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
connections: {
|
connections: {
|
||||||
|
@ -314,6 +324,7 @@ const messages = {
|
||||||
administration: "Administration",
|
administration: "Administration",
|
||||||
users: "Users",
|
users: "Users",
|
||||||
settings: "Settings",
|
settings: "Settings",
|
||||||
|
schedules: "Schedules",
|
||||||
dialogflow: "Dialogflow",
|
dialogflow: "Dialogflow",
|
||||||
},
|
},
|
||||||
appBar: {
|
appBar: {
|
||||||
|
@ -323,13 +334,39 @@ const messages = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
report: {
|
reports: {
|
||||||
listTitle: {
|
listTitles: {
|
||||||
title1: "Reminders/Schedules",
|
title0_1: "Reminders/Schedulings",
|
||||||
|
title1_1: "Calls by attendants",
|
||||||
|
title2_1: "Whatsapp chat",
|
||||||
|
title3_1: "Users online/offline"
|
||||||
},
|
},
|
||||||
search: {
|
listColumns:{
|
||||||
search1: "Number/Name...",
|
column0_1: 'Actions',
|
||||||
}
|
column0_2: 'Pic',
|
||||||
|
column0_3: 'Name',
|
||||||
|
column0_4: 'Contact',
|
||||||
|
column0_5: 'Remin/Sched',
|
||||||
|
column0_6: 'Send',
|
||||||
|
column0_7: 'Date',
|
||||||
|
column0_8: 'Message',
|
||||||
|
|
||||||
|
column1_1: 'Store',
|
||||||
|
column1_2: 'Attendant',
|
||||||
|
column1_5: 'Subject',
|
||||||
|
column1_6: 'Status',
|
||||||
|
column1_7: 'Created',
|
||||||
|
column1_8: 'Updated',
|
||||||
|
column1_9: 'Closing status',
|
||||||
|
|
||||||
|
column2_1: 'Attendant/Client',
|
||||||
|
},
|
||||||
|
search: 'Number/Name...',
|
||||||
|
dateStart: 'Start date',
|
||||||
|
dateEnd: 'End date',
|
||||||
|
user: 'User'
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
notifications: {
|
notifications: {
|
||||||
noTickets: "No notifications.",
|
noTickets: "No notifications.",
|
||||||
|
|
|
@ -50,6 +50,17 @@ const messages = {
|
||||||
closed: {
|
closed: {
|
||||||
title: "Finalizado"
|
title: "Finalizado"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
table_users:{
|
||||||
|
|
||||||
|
title: 'Lista de usuarios',
|
||||||
|
column0: 'Nombre',
|
||||||
|
column1: 'En servicio/Terminado(S)',
|
||||||
|
column2: 'Abrir por cola',
|
||||||
|
column3: 'Cerrado por cola',
|
||||||
|
column4: 'Tiempo Online',
|
||||||
|
column5: 'Actions',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
connections: {
|
connections: {
|
||||||
|
@ -319,6 +330,7 @@ const messages = {
|
||||||
administration: "Administración",
|
administration: "Administración",
|
||||||
users: "Usuarios",
|
users: "Usuarios",
|
||||||
settings: "Configuración",
|
settings: "Configuración",
|
||||||
|
schedules: "Recordatorio",
|
||||||
dialogflow: "Dialogflow",
|
dialogflow: "Dialogflow",
|
||||||
},
|
},
|
||||||
appBar: {
|
appBar: {
|
||||||
|
@ -328,13 +340,38 @@ const messages = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
report: {
|
reports: {
|
||||||
listTitle: {
|
listTitles: {
|
||||||
title1: "Recordatorios/Programación",
|
title0_1: "Recordatorios/Programación",
|
||||||
|
title1_1: "Llamadas de asistentes",
|
||||||
|
title2_1: "Chat de whatsapp",
|
||||||
|
title3_1: "Usuarios online/offline"
|
||||||
},
|
},
|
||||||
search: {
|
listColumns:{
|
||||||
search1: "Número/Nombre...",
|
column0_1: 'Acción',
|
||||||
}
|
column0_2: 'Pic',
|
||||||
|
column0_3: 'Nombre',
|
||||||
|
column0_4: 'Contacto',
|
||||||
|
column0_5: 'Record/Progr',
|
||||||
|
column0_6: 'Envío',
|
||||||
|
column0_7: 'Fecha',
|
||||||
|
column0_8: 'Mensaje',
|
||||||
|
|
||||||
|
column1_1: 'Almacenar',
|
||||||
|
column1_2: 'Secretario',
|
||||||
|
column1_5: 'Tema',
|
||||||
|
column1_6: 'Status',
|
||||||
|
column1_7: 'Creado',
|
||||||
|
column1_8: 'Actualizado',
|
||||||
|
column1_9: 'Estado de cierre',
|
||||||
|
|
||||||
|
column2_1: 'Secretario/Cliente',
|
||||||
|
},
|
||||||
|
search: 'Número/Nombre...',
|
||||||
|
dateStart: 'Fecha de inicio',
|
||||||
|
dateEnd: 'Fecha final',
|
||||||
|
user: 'Usuario'
|
||||||
|
|
||||||
},
|
},
|
||||||
notifications: {
|
notifications: {
|
||||||
noTickets: "Sin notificaciones.",
|
noTickets: "Sin notificaciones.",
|
||||||
|
|
|
@ -49,6 +49,16 @@ const messages = {
|
||||||
closed: {
|
closed: {
|
||||||
title: "Finalizado"
|
title: "Finalizado"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
table_users:{
|
||||||
|
title: 'Lista De Usuários',
|
||||||
|
column0: 'Nome',
|
||||||
|
column1: 'Em Atendimento/Finalizado(S)',
|
||||||
|
column2: 'Abertos Por Fila',
|
||||||
|
column3: 'Fechados Por Fila',
|
||||||
|
column4: 'Tempo Online',
|
||||||
|
column5: 'Ações',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
connections: {
|
connections: {
|
||||||
|
@ -317,6 +327,7 @@ const messages = {
|
||||||
administration: "Administração",
|
administration: "Administração",
|
||||||
users: "Usuários",
|
users: "Usuários",
|
||||||
settings: "Configurações",
|
settings: "Configurações",
|
||||||
|
schedules: "Lembretes",
|
||||||
dialogflow: "Dialogflow",
|
dialogflow: "Dialogflow",
|
||||||
},
|
},
|
||||||
appBar: {
|
appBar: {
|
||||||
|
@ -326,20 +337,40 @@ const messages = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
report: {
|
reports: {
|
||||||
listTitle: {
|
listTitles: {
|
||||||
title1: "Lembretes/Agendamentos",
|
title0_1: "Lembretes/Agendamentos",
|
||||||
|
title1_1: "Atendimento por atendentes",
|
||||||
|
title2_1: "Chat do atendimento pelo Whatsapp",
|
||||||
|
title3_1: "Usuários online/offline"
|
||||||
},
|
},
|
||||||
search: {
|
listColumns:{
|
||||||
search1: "Numero/Nome...",
|
column0_1: 'Ações',
|
||||||
},
|
column0_2: 'Foto',
|
||||||
date:{
|
column0_3: 'Nome',
|
||||||
dateStart: "Data início",
|
column0_4: 'Contato',
|
||||||
dateEnd: "Data fim"
|
column0_5: 'Lemb/Agen',
|
||||||
},
|
column0_6: 'Envio',
|
||||||
button:{
|
column0_7: 'Data',
|
||||||
|
column0_8: 'Mensagem',
|
||||||
|
|
||||||
|
column1_1: 'Unidade',
|
||||||
|
column1_2: 'Atendente',
|
||||||
|
column1_5: 'Assunto',
|
||||||
|
column1_6: 'Status',
|
||||||
|
column1_7: 'Criado',
|
||||||
|
column1_8: 'Atualizado',
|
||||||
|
column1_9: 'Status de encerramento',
|
||||||
|
|
||||||
|
column2_1: 'Atendente/Cliente',
|
||||||
|
|
||||||
|
},
|
||||||
|
search: 'Numer/Nome...',
|
||||||
|
dateStart: 'Data início',
|
||||||
|
dateEnd: 'Data fim',
|
||||||
|
user: 'Usuário'
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
notifications: {
|
notifications: {
|
||||||
noTickets: "Nenhuma notificação.",
|
noTickets: "Nenhuma notificação.",
|
||||||
|
|
Loading…
Reference in New Issue