Correção do queuChoice
parent
6f48e9aa1e
commit
be3320e883
|
@ -21,6 +21,7 @@
|
||||||
"cookie-parser": "^1.4.5",
|
"cookie-parser": "^1.4.5",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"date-fns": "^2.16.1",
|
"date-fns": "^2.16.1",
|
||||||
|
"date-fns-tz": "^1.3.4",
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"express-async-errors": "^3.1.1",
|
"express-async-errors": "^3.1.1",
|
||||||
|
|
|
@ -36,6 +36,10 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const store = async (req: Request, res: Response): Promise<Response> => {
|
export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const { ticketId } = req.params;
|
const { ticketId } = req.params;
|
||||||
const { body, quotedMsg }: MessageData = req.body;
|
const { body, quotedMsg }: MessageData = req.body;
|
||||||
const medias = req.files as Express.Multer.File[];
|
const medias = req.files as Express.Multer.File[];
|
||||||
|
@ -52,7 +56,7 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
console.log('------- quotedMsg: ', quotedMsg)
|
console.log('------- quotedMsg: ', quotedMsg, ' | ticket: ', ticket)
|
||||||
|
|
||||||
await SendWhatsAppMessage({ body, ticket, quotedMsg });
|
await SendWhatsAppMessage({ body, ticket, quotedMsg });
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ import AppError from "../errors/AppError";
|
||||||
import ShowTicketReport from "../services/TicketServices/ShowTicketReport";
|
import ShowTicketReport from "../services/TicketServices/ShowTicketReport";
|
||||||
import ShowMessageReport from "../services/MessageServices/ShowMessageReport";
|
import ShowMessageReport from "../services/MessageServices/ShowMessageReport";
|
||||||
|
|
||||||
|
import onlineUserService from "../services/UserServices/CreateOrUpdateOnlineUserService";
|
||||||
|
|
||||||
|
|
||||||
type IndexQuery = {
|
type IndexQuery = {
|
||||||
userId: string;
|
userId: string;
|
||||||
|
@ -15,6 +17,10 @@ type IndexQuery = {
|
||||||
|
|
||||||
export const reportUserByDateStartDateEnd = async (req: Request, res: Response): Promise<Response> => {
|
export const reportUserByDateStartDateEnd = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
|
||||||
|
|
||||||
|
//const test = await onlineUserService({userId: 3, status: 'offline'})
|
||||||
|
|
||||||
|
|
||||||
if (req.user.profile !== "master" && req.user.profile !== "admin") {
|
if (req.user.profile !== "master" && req.user.profile !== "admin") {
|
||||||
throw new AppError("ERR_NO_PERMISSION", 403);
|
throw new AppError("ERR_NO_PERMISSION", 403);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ interface TicketData {
|
||||||
|
|
||||||
|
|
||||||
import ListStatusChatEndService from "../services/StatusChatEndService/ListStatusChatEndService";
|
import ListStatusChatEndService from "../services/StatusChatEndService/ListStatusChatEndService";
|
||||||
|
import Ticket from "../models/Ticket";
|
||||||
|
|
||||||
export const index = async (req: Request, res: Response): Promise<Response> => {
|
export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
const {
|
const {
|
||||||
|
@ -82,13 +83,33 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
// `contactId: ${contactId} \n| status: ${status} \n| userId: ${userId}`
|
// `contactId: ${contactId} \n| status: ${status} \n| userId: ${userId}`
|
||||||
// )
|
// )
|
||||||
|
|
||||||
const ticket = await CreateTicketService({ contactId, status, userId });
|
|
||||||
|
|
||||||
const io = getIO();
|
// test del
|
||||||
io.to(ticket.status).emit("ticket", {
|
let ticket = await Ticket.findOne({where: { contactId, status: 'queueChoice' } });
|
||||||
action: "update",
|
|
||||||
ticket
|
if(ticket){
|
||||||
});
|
await UpdateTicketService({ ticketData: { status: 'open',userId: userId,}, ticketId: ticket.id});
|
||||||
|
console.log('TICKET QUEUE CHOICE !!!!!!!')
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
ticket = await CreateTicketService({ contactId, status, userId });
|
||||||
|
}
|
||||||
|
|
||||||
|
const io = getIO();
|
||||||
|
io.to(ticket.status).emit("ticket", {
|
||||||
|
action: "update",
|
||||||
|
ticket
|
||||||
|
});
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
// const ticket = await CreateTicketService({ contactId, status, userId });
|
||||||
|
|
||||||
|
// const io = getIO();
|
||||||
|
// io.to(ticket.status).emit("ticket", {
|
||||||
|
// action: "update",
|
||||||
|
// ticket
|
||||||
|
// });
|
||||||
|
|
||||||
return res.status(200).json(ticket);
|
return res.status(200).json(ticket);
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,6 +13,7 @@ import QuickAnswer from "../models/QuickAnswer";
|
||||||
|
|
||||||
import SchedulingNotify from "../models/SchedulingNotify";
|
import SchedulingNotify from "../models/SchedulingNotify";
|
||||||
import StatusChatEnd from "../models/StatusChatEnd";
|
import StatusChatEnd from "../models/StatusChatEnd";
|
||||||
|
import UserOnlineTime from "../models/UserOnlineTime";
|
||||||
|
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
|
@ -36,6 +37,7 @@ const models = [
|
||||||
|
|
||||||
SchedulingNotify,
|
SchedulingNotify,
|
||||||
StatusChatEnd,
|
StatusChatEnd,
|
||||||
|
UserOnlineTime,
|
||||||
];
|
];
|
||||||
|
|
||||||
sequelize.addModels(models);
|
sequelize.addModels(models);
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.createTable("UserOnlineTimes", {
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
autoIncrement: true,
|
||||||
|
primaryKey: true,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
userId: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
references: { model: "Users", key: "id" },
|
||||||
|
onUpdate: "CASCADE",
|
||||||
|
onDelete: "CASCADE",
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
status: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
onlineTime: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: true
|
||||||
|
},
|
||||||
|
createdAt: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
updatedAt: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.dropTable("UserOnlineTimes");
|
||||||
|
}
|
||||||
|
};
|
|
@ -6,6 +6,7 @@ import ListSchedulingNotifyService from "../services/SchedulingNotifyServices/L
|
||||||
import DeleteSchedulingNotifyService from "../services/SchedulingNotifyServices/DeleteSchedulingNotifyService";
|
import DeleteSchedulingNotifyService from "../services/SchedulingNotifyServices/DeleteSchedulingNotifyService";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let scheduler_monitor:any;
|
let scheduler_monitor:any;
|
||||||
|
|
||||||
const monitor = async () => {
|
const monitor = async () => {
|
||||||
|
@ -41,6 +42,7 @@ const monitor = async () => {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
|
||||||
|
export const splitDateTime = (date: Date) => {
|
||||||
|
|
||||||
|
|
||||||
|
let day = date.getDate().toString().padStart(2, '0');
|
||||||
|
let month = (date.getMonth()+1).toString().padStart(2, '0');
|
||||||
|
let year = date.getFullYear();
|
||||||
|
let hour = date.getHours().toString().padStart(2, '0');
|
||||||
|
let minute = date.getMinutes().toString().padStart(2, '0');
|
||||||
|
let seconds = date.getSeconds().toString().padStart(2, '0');
|
||||||
|
|
||||||
|
return {fullDate: `${year}-${month}-${day}`, fullTime: `${hour}:${minute}:${seconds}`}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
|
||||||
|
import { getIO } from "../libs/socket";
|
||||||
|
// import usersOnline from '../libs/socket'
|
||||||
|
|
||||||
|
|
||||||
|
let whoIsOnline_monitor:any;
|
||||||
|
|
||||||
|
const monitor = async () => {
|
||||||
|
|
||||||
|
const io = getIO();
|
||||||
|
io.emit("isOnline");
|
||||||
|
|
||||||
|
//const test = require('./../libs/socket');
|
||||||
|
// console.log('*usersOnline: ', test.listOnlineUsers)
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const startWhoIsOnlinegMonitor =async (mileseconds: number) => {
|
||||||
|
|
||||||
|
whoIsOnline_monitor = setInterval(monitor, mileseconds)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const stopWhoIsOnlineMonitor =async ( ) => {
|
||||||
|
|
||||||
|
clearInterval(whoIsOnline_monitor)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,12 @@ import { logger } from "../utils/logger";
|
||||||
|
|
||||||
let io: SocketIO;
|
let io: SocketIO;
|
||||||
|
|
||||||
|
//test del
|
||||||
|
let listOnlineUsers:any[]=[]
|
||||||
|
let count:number = 0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
export const initIO = (httpServer: Server): SocketIO => {
|
export const initIO = (httpServer: Server): SocketIO => {
|
||||||
io = new SocketIO(httpServer, {
|
io = new SocketIO(httpServer, {
|
||||||
cors: {
|
cors: {
|
||||||
|
@ -12,13 +18,38 @@ export const initIO = (httpServer: Server): SocketIO => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
io.on("connection", socket => {
|
io.on("connection", socket => {
|
||||||
logger.info("Client Connected");
|
logger.info("Client Connected");
|
||||||
|
|
||||||
// // test del
|
|
||||||
// let userId = socket.handshake.query;
|
socket.on("online", (userId: string) => {
|
||||||
// console.log('SOCKET userId: ', userId)
|
|
||||||
// //
|
|
||||||
|
logger.info(`CLIENT ID ${userId}` );
|
||||||
|
|
||||||
|
|
||||||
|
const indexUser = listOnlineUsers.findIndex((e) => e.userId == userId)
|
||||||
|
|
||||||
|
if(indexUser == -1){
|
||||||
|
//listOnlineUsers.push({userId: userId, status: 'online'})
|
||||||
|
}
|
||||||
|
|
||||||
|
count++
|
||||||
|
|
||||||
|
//console.log('count: ', count)
|
||||||
|
|
||||||
|
if(count >= listOnlineUsers.length){
|
||||||
|
//console.log('listOnlineUsers1: ', listOnlineUsers)
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log('listOnlineUsers1: ', listOnlineUsers)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
socket.on("joinChatBox", (ticketId: string) => {
|
socket.on("joinChatBox", (ticketId: string) => {
|
||||||
logger.info("A client joined a ticket channel");
|
logger.info("A client joined a ticket channel");
|
||||||
|
@ -48,3 +79,7 @@ export const getIO = (): SocketIO => {
|
||||||
}
|
}
|
||||||
return io;
|
return io;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
exports.listOnlineUsers = listOnlineUsers
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,13 @@ import {
|
||||||
AutoIncrement,
|
AutoIncrement,
|
||||||
Default,
|
Default,
|
||||||
HasMany,
|
HasMany,
|
||||||
BelongsToMany
|
BelongsToMany,
|
||||||
} from "sequelize-typescript";
|
} from "sequelize-typescript";
|
||||||
import { hash, compare } from "bcryptjs";
|
import { hash, compare } from "bcryptjs";
|
||||||
import Ticket from "./Ticket";
|
import Ticket from "./Ticket";
|
||||||
import Queue from "./Queue";
|
import Queue from "./Queue";
|
||||||
import UserQueue from "./UserQueue";
|
import UserQueue from "./UserQueue";
|
||||||
|
import UserOnlineTime from "./UserOnlineTime";
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
class User extends Model<User> {
|
class User extends Model<User> {
|
||||||
|
@ -54,6 +55,11 @@ class User extends Model<User> {
|
||||||
@HasMany(() => Ticket)
|
@HasMany(() => Ticket)
|
||||||
tickets: Ticket[];
|
tickets: Ticket[];
|
||||||
|
|
||||||
|
//test del
|
||||||
|
@HasMany(() => UserOnlineTime)
|
||||||
|
UserOnlineTime: UserOnlineTime[];
|
||||||
|
//
|
||||||
|
|
||||||
@BelongsToMany(() => Queue, () => UserQueue)
|
@BelongsToMany(() => Queue, () => UserQueue)
|
||||||
queues: Queue[];
|
queues: Queue[];
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
AutoIncrement,
|
||||||
|
Column,
|
||||||
|
CreatedAt,
|
||||||
|
UpdatedAt,
|
||||||
|
Model,
|
||||||
|
PrimaryKey,
|
||||||
|
HasMany,
|
||||||
|
ForeignKey,
|
||||||
|
BelongsTo
|
||||||
|
} from "sequelize-typescript";
|
||||||
|
|
||||||
|
import User from "./User";
|
||||||
|
|
||||||
|
@Table
|
||||||
|
class UserOnlineTime extends Model<UserOnlineTime> {
|
||||||
|
@PrimaryKey
|
||||||
|
@AutoIncrement
|
||||||
|
@Column
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
status: string;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
onlineTime: Date;
|
||||||
|
|
||||||
|
@CreatedAt
|
||||||
|
createdAt: Date;
|
||||||
|
|
||||||
|
@UpdatedAt
|
||||||
|
updatedAt: Date;
|
||||||
|
|
||||||
|
@ForeignKey(() => User)
|
||||||
|
@Column
|
||||||
|
userId: number;
|
||||||
|
|
||||||
|
@BelongsTo(() => User)
|
||||||
|
user: User;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default UserOnlineTime;
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { logger } from "./utils/logger";
|
||||||
import { StartAllWhatsAppsSessions } from "./services/WbotServices/StartAllWhatsAppsSessions";
|
import { StartAllWhatsAppsSessions } from "./services/WbotServices/StartAllWhatsAppsSessions";
|
||||||
|
|
||||||
import { startSchedulingMonitor } from "./helpers/SchedulingNotifySendMessage"
|
import { startSchedulingMonitor } from "./helpers/SchedulingNotifySendMessage"
|
||||||
|
import { startWhoIsOnlinegMonitor } from "./helpers/WhoIsOnlineMonitor"
|
||||||
|
|
||||||
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}`);
|
||||||
|
@ -15,3 +16,4 @@ StartAllWhatsAppsSessions();
|
||||||
gracefulShutdown(server);
|
gracefulShutdown(server);
|
||||||
|
|
||||||
startSchedulingMonitor(5000)
|
startSchedulingMonitor(5000)
|
||||||
|
startWhoIsOnlinegMonitor(3000)
|
||||||
|
|
|
@ -39,14 +39,7 @@ const CreateMessageService = async ({messageData}: Request): Promise<Message> =>
|
||||||
throw new Error("ERR_CREATING_MESSAGE");
|
throw new Error("ERR_CREATING_MESSAGE");
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.log('SERVER SIDE MESSAGE: ', message)
|
|
||||||
|
|
||||||
// console.log('>>>>>>>>>>>>>>>>>>>>>> TICKET STATUS: ',message.ticket.status)
|
|
||||||
|
|
||||||
//test del
|
|
||||||
// const ticketInfo = await Ticket.findByPk(message.ticket.id)
|
|
||||||
// console.log('&&&&&&&&&&&&&&&&& TICKET INFO queueId: ', ticketInfo?.queueId)
|
|
||||||
//
|
|
||||||
|
|
||||||
if(message.ticket.status!='queueChoice'){
|
if(message.ticket.status!='queueChoice'){
|
||||||
|
|
||||||
|
@ -61,7 +54,7 @@ const CreateMessageService = async ({messageData}: Request): Promise<Message> =>
|
||||||
contact: message.ticket.contact
|
contact: message.ticket.contact
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
import AppError from "../../errors/AppError";
|
||||||
|
import UserOnlineTime from "../../models/UserOnlineTime";
|
||||||
|
import { splitDateTime } from "../../helpers/SplitDateTime";
|
||||||
|
import { Op, Sequelize } from "sequelize";
|
||||||
|
import { addHours, addMinutes, addSeconds, intervalToDuration, add } from "date-fns";
|
||||||
|
import format from 'date-fns/format';
|
||||||
|
import ptBR from 'date-fns/locale/pt-BR';
|
||||||
|
import { stat } from "fs";
|
||||||
|
|
||||||
|
interface Request {
|
||||||
|
userId: string | number,
|
||||||
|
status: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const CreateOrUpdateUserOnlineTime = async ({
|
||||||
|
userId,
|
||||||
|
status,
|
||||||
|
}: Request): Promise<UserOnlineTime> => {
|
||||||
|
|
||||||
|
let userOnlineTime = null;
|
||||||
|
// let dateTime = splitDateTime(new Date(new Date() + 'UTC'))
|
||||||
|
|
||||||
|
let dateTime = splitDateTime(new Date(format(new Date(), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR }) ))
|
||||||
|
|
||||||
|
|
||||||
|
userOnlineTime = await UserOnlineTime.findOne({
|
||||||
|
where: {
|
||||||
|
[Op.and]: [
|
||||||
|
{
|
||||||
|
userId: userId
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$createdAt$": Sequelize.where(Sequelize.fn("date", Sequelize.col("createdAt")), `${dateTime.fullDate}`)
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(userOnlineTime){
|
||||||
|
try{
|
||||||
|
|
||||||
|
if(status === 'offline'){
|
||||||
|
//updatedAt
|
||||||
|
let newtTime = intervalToDuration({ start: userOnlineTime.updatedAt, end: new Date()})
|
||||||
|
console.log('TESTANDO INTERVAL DURATION: ', newtTime)
|
||||||
|
|
||||||
|
console.log('hours: ', newtTime.hours, ' | minutes: ', newtTime.minutes, ' | seconds: ', newtTime.seconds)
|
||||||
|
|
||||||
|
let onlineTime = new Date()
|
||||||
|
|
||||||
|
onlineTime.setUTCHours(userOnlineTime.onlineTime.getHours())
|
||||||
|
onlineTime.setUTCMinutes(userOnlineTime.onlineTime.getMinutes())
|
||||||
|
onlineTime.setUTCSeconds(userOnlineTime.onlineTime.getSeconds())
|
||||||
|
|
||||||
|
console.log('userOnlineTime.onlineTime: ',userOnlineTime.onlineTime)
|
||||||
|
console.log('userOnlineTime.onlineTime.getHours(): ',userOnlineTime.onlineTime.getHours())
|
||||||
|
console.log('userOnlineTime.onlineTime.getMinutes(): ',userOnlineTime.onlineTime.getMinutes())
|
||||||
|
console.log('userOnlineTime.onlineTime.getSeconds(): ',userOnlineTime.onlineTime.getSeconds())
|
||||||
|
|
||||||
|
console.log('online time 3: ', onlineTime)
|
||||||
|
|
||||||
|
|
||||||
|
if(newtTime.hours && +newtTime.hours > 0){
|
||||||
|
onlineTime = addHours(onlineTime, newtTime.hours)
|
||||||
|
}
|
||||||
|
if(newtTime.minutes && +newtTime.minutes > 0){
|
||||||
|
onlineTime = addMinutes(onlineTime,newtTime.minutes)
|
||||||
|
}
|
||||||
|
if(newtTime.seconds && +newtTime.seconds > 0){
|
||||||
|
onlineTime = addSeconds(onlineTime, newtTime.seconds)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('online time 4: ', onlineTime)
|
||||||
|
|
||||||
|
const isoDate = new Date(onlineTime);
|
||||||
|
const mySQLDateString = isoDate.toJSON().slice(0, 19).replace('T', ' ');
|
||||||
|
console.log('mySQLDateString: ', mySQLDateString)
|
||||||
|
|
||||||
|
await userOnlineTime.update({ status, onlineTime: mySQLDateString })
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(status === 'online'){
|
||||||
|
await userOnlineTime.update({ status })
|
||||||
|
}
|
||||||
|
|
||||||
|
}catch(err){
|
||||||
|
|
||||||
|
throw new AppError("ERR_NO_USER_ONLINE_FOUND", 404);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!userOnlineTime){
|
||||||
|
|
||||||
|
userOnlineTime = await UserOnlineTime.create(
|
||||||
|
{
|
||||||
|
userId,
|
||||||
|
status,
|
||||||
|
onlineTime: `${dateTime.fullDate} 00:00:00`
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return userOnlineTime
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default CreateOrUpdateUserOnlineTime
|
|
@ -0,0 +1,74 @@
|
||||||
|
import Ticket from "../../models/Ticket";
|
||||||
|
import AppError from "../../errors/AppError";
|
||||||
|
import Contact from "../../models/Contact";
|
||||||
|
import User from "../../models/User";
|
||||||
|
import Queue from "../../models/Queue";
|
||||||
|
|
||||||
|
import Message from "../../models/Message";
|
||||||
|
import { userInfo } from "os";
|
||||||
|
|
||||||
|
import { Op, where } from "sequelize";
|
||||||
|
|
||||||
|
import { Sequelize } from "sequelize";
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
import { startOfDay, endOfDay, parseISO, getDate} from "date-fns";
|
||||||
|
import { string } from "yup/lib/locale";
|
||||||
|
import Whatsapp from "../../models/Whatsapp";
|
||||||
|
|
||||||
|
//Report by user, startDate, endDate
|
||||||
|
const ShowUserServiceReport = async (id: string | number, startDate: string, endDate: string): Promise<Ticket[]> => {
|
||||||
|
|
||||||
|
let where_clause = {}
|
||||||
|
|
||||||
|
if(id=='0'){
|
||||||
|
where_clause = {
|
||||||
|
createdAt: {
|
||||||
|
[Op.gte]: startDate+' 00:00:00.000000',
|
||||||
|
[Op.lte]: endDate +' 23:59:59.999999'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
where_clause = {
|
||||||
|
userid: id,
|
||||||
|
createdAt: {
|
||||||
|
[Op.gte]: startDate+' 00:00:00.000000',
|
||||||
|
[Op.lte]: endDate +' 23:59:59.999999'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const ticket = await Ticket.findAll({
|
||||||
|
|
||||||
|
// where: where_clause ,
|
||||||
|
|
||||||
|
// attributes: ['id', 'status', [Sequelize.fn("DATE_FORMAT",Sequelize.col("Ticket.createdAt"),"%d/%m/%Y %H:%i:%s"),"createdAt"],
|
||||||
|
// [Sequelize.fn("DATE_FORMAT",Sequelize.col("Ticket.updatedAt"),"%d/%m/%Y %H:%i:%s"),"updatedAt"]],
|
||||||
|
|
||||||
|
// include: [
|
||||||
|
// {
|
||||||
|
// model: Message,
|
||||||
|
// required:true,
|
||||||
|
// separate: true,
|
||||||
|
|
||||||
|
// attributes: ['body', 'read', 'mediaType','fromMe', 'mediaUrl', [Sequelize.fn("DATE_FORMAT",Sequelize.col("createdAt"),"%d/%m/%Y %H:%i:%s"),"createdAt"]],
|
||||||
|
|
||||||
|
// order: [
|
||||||
|
// ['createdAt', 'ASC']
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
if (!ticket) {
|
||||||
|
throw new AppError("ERR_NO_TICKET_FOUND", 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ticket;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ShowUserServiceReport;
|
|
@ -28,7 +28,7 @@ const SendWhatsAppMessage = async ({
|
||||||
quotedMsgSerializedId = SerializeWbotMsgId(ticket, quotedMsg);
|
quotedMsgSerializedId = SerializeWbotMsgId(ticket, quotedMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// test del
|
|
||||||
const whatsapp = await ShowWhatsAppService(ticket.whatsappId);
|
const whatsapp = await ShowWhatsAppService(ticket.whatsappId);
|
||||||
|
|
||||||
if(whatsapp.status!='CONNECTED'){
|
if(whatsapp.status!='CONNECTED'){
|
||||||
|
@ -42,10 +42,12 @@ const SendWhatsAppMessage = async ({
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
//
|
|
||||||
|
|
||||||
const wbot = await GetTicketWbot(ticket);
|
const wbot = await GetTicketWbot(ticket);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const sentMessage = await wbot.sendMessage(
|
const sentMessage = await wbot.sendMessage(
|
||||||
`${ticket.contact.number}@${ticket.isGroup ? "g" : "c"}.us`,
|
`${ticket.contact.number}@${ticket.isGroup ? "g" : "c"}.us`,
|
||||||
|
|
|
@ -1,53 +1,33 @@
|
||||||
|
|
||||||
const data = [
|
const data:any[] = [
|
||||||
{
|
{
|
||||||
"id":"1",
|
"id":"1",
|
||||||
"option":"Status do Pedido",
|
"option":"Conhecer a história da HiT",
|
||||||
"description":"Digite aqui umas das opções abaixo para iniciarmos o atendimento, tá? 🧡",
|
"description":"Conheça nossa história acessando o link abaixo:\nhttp://www.hittelco.com/br/hit-communications.html",
|
||||||
"subOptions": [{"subOpt":"Digitar meu CPF","responseToClient":"Digite o seu CPF"}, {"subOpt":"Digitar o Número do Pedido", "responseToClient":"Digite o numero do pedido"}],
|
// "subOptions": [{"subOpt":"Digitar meu CPF","responseToClient":"Digite o seu CPF"}, {"subOpt":"Digitar o Número do Pedido", "responseToClient":"Digite o numero do pedido"}],
|
||||||
"atendente":false
|
"atendente":false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id":"2",
|
"id":"2",
|
||||||
"option":"Status do Reembolso",
|
"option":"Conhecer os produtos da HIT",
|
||||||
"description":"Digite aqui umas das opções abaixo para iniciarmos o atendimento, tá? 🧡",
|
"description":"Conheça nossos produtos acessando o link abaixo:\nhttp://www.hittelco.com/br/index.html",
|
||||||
"subOptions": [{"subOpt":"Digitar meu CPF","responseToClient":"Digite o seu CPF"}, {"subOpt":"Digitar o Número do Pedido", "responseToClient":"Digite o numero do pedido"}],
|
|
||||||
"atendente":false
|
"atendente":false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id":"3",
|
"id":"3",
|
||||||
"option":"Quero Trocar ou Devolver",
|
"option":"Conhecer nossa Estrutura",
|
||||||
"description":"Para solicitar, é bem simples! Disponibilizamos um passo-a-passo bem completo em nossa loja online. \nBasta acessar www.dressto.com.br, ir até nosso rodapé, e clicar em “Como Trocar”, indicamos que leia atentamente nossa política de troca. 😉 \nCaso ainda precise de atendimento",
|
"description":"Conheça nossa estrutura acessando o link abaixo\nhttp://www.hittelco.com/br/infraestrutura.html",
|
||||||
"subOptions": [{"subOpt":"Para continuar", "responseToClient":"Aguarde, um de nossos atendentes vai te atender em breve!"}],
|
|
||||||
"atendente":false
|
"atendente":false
|
||||||
},
|
} ,
|
||||||
{
|
{
|
||||||
"id":"4",
|
"id":"4",
|
||||||
"option":"Quero Rastrear meu Pedido",
|
"option":"Finalizar atendimento",
|
||||||
"description":"Digite aqui umas das opções abaixo para iniciarmos o atendimento, tá? 🧡",
|
"description":"Seu atendimento foi encerrado!\nFoi um prazer conhece-lo, volte sempre.",
|
||||||
"subOptions": [{"subOpt":"Digitar meu CPF","responseToClient":"Digite o seu CPF"}, {"subOpt":"Digitar o Número do Pedido", "responseToClient":"Digite o numero do pedido"}],
|
|
||||||
"atendente":false
|
"atendente":false,
|
||||||
},
|
"closeChat": true
|
||||||
{
|
|
||||||
"id":"5",
|
|
||||||
"option":"Cancelamento de Pedido",
|
|
||||||
"description":"Digite aqui umas das opções abaixo para iniciarmos o atendimento, tá? 🧡",
|
|
||||||
"subOptions": [{"subOpt":"Digitar meu CPF","responseToClient":"Digite o seu CPF"}, {"subOpt":"Digitar o Número do Pedido", "responseToClient":"Digite o numero do pedido"}],
|
|
||||||
"atendente":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id":"6",
|
|
||||||
"option":"Cupons",
|
|
||||||
"description":"Digite o número da opção desejada",
|
|
||||||
"subOptions": [{"subOpt":"Primeira Compra", "responseToClient":"Primeira Compra\nAguarde, um de nossos atendentes vai te atender em breve!"}, {"subOpt":"Aniversariante", "responseToClient":"Aniversariante\nAguarde, um de nossos atendentes vai te atender em breve!"}],
|
|
||||||
"atendente":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id":"7",
|
|
||||||
"option":"Outros Assuntos",
|
|
||||||
"description":"7 - Prezado cliente, você está sendo direcionado para um atendente disponível 😊.\nPedimos gentilmente que aguarde para ser atendido.\nLembramos que nosso atendimento está sempre disponível de segunda a sexta-feira, das 08:00 às 17:00 horas. Um beijo! !",
|
|
||||||
"subOptions": [],
|
|
||||||
"atendente":true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -34,7 +34,8 @@ import fs from 'fs';
|
||||||
// test del
|
// test del
|
||||||
import data_ura from './ura'
|
import data_ura from './ura'
|
||||||
import msg_client_transfer from './ura_msg_transfer'
|
import msg_client_transfer from './ura_msg_transfer'
|
||||||
import final_message from "./ura _final_message";
|
import final_message from "./ura_final_message";
|
||||||
|
import SendWhatsAppMessage from "./SendWhatsAppMessage";
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
@ -242,24 +243,41 @@ const verifyQueue = async (
|
||||||
|
|
||||||
await verifyMessage(sentMessage, ticket, contact);
|
await verifyMessage(sentMessage, ticket, contact);
|
||||||
} else {
|
} else {
|
||||||
let options = "";
|
|
||||||
|
|
||||||
queues.forEach((queue, index) => {
|
|
||||||
options += `*${index + 1}* - ${queue.name}\n`;
|
|
||||||
});
|
|
||||||
|
|
||||||
const body = `\u200e${greetingMessage}\n${options}`;
|
//test del transfere o atendimento se entrar na ura infinita
|
||||||
|
let ticket_message = await ShowTicketMessage(ticket.id, false);
|
||||||
|
if(ticket_message.length > 10){
|
||||||
|
|
||||||
const debouncedSentMessage = debounce(
|
await UpdateTicketService({ ticketData: {status: 'pending', queueId: queues[0].id }, ticketId: ticket.id });
|
||||||
async () => {
|
|
||||||
const sentMessage = await wbot.sendMessage(`${contact.number}@c.us`, body);
|
}
|
||||||
verifyMessage(sentMessage, ticket, contact);
|
else{
|
||||||
},
|
|
||||||
3000,
|
let options = "";
|
||||||
ticket.id
|
|
||||||
);
|
queues.forEach((queue, index) => {
|
||||||
|
options += `*${index + 1}* - ${queue.name}\n`;
|
||||||
|
});
|
||||||
|
|
||||||
|
const body = `\u200e${greetingMessage}\n${options}`;
|
||||||
|
|
||||||
|
const debouncedSentMessage = debounce(
|
||||||
|
async () => {
|
||||||
|
const sentMessage = await wbot.sendMessage(`${contact.number}@c.us`, body);
|
||||||
|
verifyMessage(sentMessage, ticket, contact);
|
||||||
|
},
|
||||||
|
3000,
|
||||||
|
ticket.id
|
||||||
|
);
|
||||||
|
|
||||||
|
debouncedSentMessage();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('TICKET MESSAGE ON QUEUE CHOICE: ', ticket_message)
|
||||||
|
//
|
||||||
|
|
||||||
debouncedSentMessage();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -447,12 +465,14 @@ const handleMessage = async (
|
||||||
|
|
||||||
let indexAttendant = data_ura.findIndex((u) => u.atendente )
|
let indexAttendant = data_ura.findIndex((u) => u.atendente )
|
||||||
|
|
||||||
let opt_user_attendant = ''
|
let opt_user_attendant = '-1'
|
||||||
|
|
||||||
if(indexAttendant != -1){
|
if(indexAttendant != -1){
|
||||||
opt_user_attendant = data_ura[indexAttendant].id
|
opt_user_attendant = data_ura[indexAttendant].id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// console.log('¨¨¨¨¨¨¨¨¨¨¨¨¨¨ indexAttendant: ',indexAttendant, ' | opt_user_attendant: ', opt_user_attendant)
|
||||||
|
|
||||||
let ticket_message = await ShowTicketMessage(ticket.id, true, ura_length, `^[0-${ura_length}}]$`);
|
let ticket_message = await ShowTicketMessage(ticket.id, true, ura_length, `^[0-${ura_length}}]$`);
|
||||||
|
|
||||||
if(ticket_message.length > 1){
|
if(ticket_message.length > 1){
|
||||||
|
@ -483,18 +503,25 @@ const handleMessage = async (
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// console.log('----------------- ticket_message: ', ticket_message)
|
// console.log('----------------- ticket_message: ', ticket_message)
|
||||||
|
|
||||||
|
//console.log('¨¨¨¨¨¨¨¨¨¨¨¨¨¨ MSG.BODY: ', msg.body , ' | opt_user_attendant: ',opt_user_attendant, ' | lastOption: ', lastOption)
|
||||||
|
|
||||||
// È numero
|
// È numero
|
||||||
if( !Number.isNaN(Number(msg.body.trim())) && (+msg.body >= 0 && +msg.body <= data_ura.length) ) {
|
if( !Number.isNaN(Number(msg.body.trim())) && (+msg.body >= 0 && +msg.body <= data_ura.length) ) {
|
||||||
|
|
||||||
const indexUra = data_ura.findIndex((ura) => ura.id == msg.body.trim())
|
const indexUra = data_ura.findIndex((ura) => ura.id == msg.body.trim())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(indexUra != -1){
|
if(indexUra != -1){
|
||||||
|
|
||||||
if(data_ura[indexUra].id != opt_user_attendant && lastOption != opt_user_attendant){
|
if(data_ura[indexUra].id != opt_user_attendant && lastOption != opt_user_attendant){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
console.log('TICKET MESSAGE: ', ticket_message)
|
console.log('TICKET MESSAGE: ', ticket_message)
|
||||||
|
|
||||||
// test del
|
// test del
|
||||||
|
@ -536,10 +563,11 @@ const handleMessage = async (
|
||||||
id = listMessage[listMessage.length-1].body
|
id = listMessage[listMessage.length-1].body
|
||||||
subUra = data_ura.filter((e)=>e.id == id )[0]
|
subUra = data_ura.filter((e)=>e.id == id )[0]
|
||||||
|
|
||||||
if(subUra.subOptions){
|
if(subUra.subOptions && subUra.subOptions.length > 0){
|
||||||
|
|
||||||
if( !Number.isNaN(Number(msg.body.trim())) && (+msg.body >= 0 && +msg.body <= subUra.subOptions?.length) && subUra.subOptions ) {
|
if( !Number.isNaN(Number(msg.body.trim())) && (+msg.body >= 0 && +msg.body <= subUra.subOptions?.length) && subUra.subOptions ) {
|
||||||
|
|
||||||
|
|
||||||
if(subUra.subOptions[+msg.body - 1].responseToClient){
|
if(subUra.subOptions[+msg.body - 1].responseToClient){
|
||||||
|
|
||||||
botSendMessage(ticket, contact, wbot, `*${subUra.option}*\n\n${subUra.subOptions[+msg.body - 1].responseToClient}`)
|
botSendMessage(ticket, contact, wbot, `*${subUra.option}*\n\n${subUra.subOptions[+msg.body - 1].responseToClient}`)
|
||||||
|
@ -564,7 +592,7 @@ const handleMessage = async (
|
||||||
else{
|
else{
|
||||||
|
|
||||||
let options = "";
|
let options = "";
|
||||||
let subOptions = subUra.subOptions
|
let subOptions:any[] = subUra.subOptions
|
||||||
|
|
||||||
subOptions?.forEach((s, index) => { options += `*${index + 1}* - ${s.subOpt}\n` });
|
subOptions?.forEach((s, index) => { options += `*${index + 1}* - ${s.subOpt}\n` });
|
||||||
|
|
||||||
|
@ -581,11 +609,11 @@ const handleMessage = async (
|
||||||
|
|
||||||
//
|
//
|
||||||
if(next){
|
if(next){
|
||||||
if(data_ura[indexUra].subOptions){
|
if(data_ura[indexUra].subOptions && data_ura[indexUra].subOptions.length > 0){
|
||||||
|
|
||||||
let options = "";
|
let options = "";
|
||||||
let option = data_ura[indexUra].option
|
let option = data_ura[indexUra].option
|
||||||
let subOptions = data_ura[indexUra].subOptions
|
let subOptions:any[] = data_ura[indexUra].subOptions
|
||||||
let description = data_ura[indexUra].description
|
let description = data_ura[indexUra].description
|
||||||
|
|
||||||
subOptions?.forEach((s, index) => { options += `*${index + 1}* - ${s.subOpt}\n` });
|
subOptions?.forEach((s, index) => { options += `*${index + 1}* - ${s.subOpt}\n` });
|
||||||
|
@ -597,7 +625,32 @@ const handleMessage = async (
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|
||||||
botSendMessage(ticket, contact, wbot, `${data_ura[indexUra].description}\n\n *0* - Voltar ao menu principal`)
|
//test del deletar isso (Usar somente na hit)
|
||||||
|
if(data_ura[indexUra].closeChat){
|
||||||
|
|
||||||
|
|
||||||
|
const {ticket :res} = await UpdateTicketService({
|
||||||
|
ticketData:{'status': 'closed', 'userId': botInfo.userIdBot}, ticketId: ticket.id
|
||||||
|
});
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
const whatsapp = await ShowWhatsAppService(ticket.whatsappId);
|
||||||
|
|
||||||
|
const { farewellMessage } = whatsapp;
|
||||||
|
|
||||||
|
if (farewellMessage) {
|
||||||
|
await SendWhatsAppMessage({ body: farewellMessage, ticket: res });
|
||||||
|
}
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
botSendMessage(ticket, contact, wbot, `${data_ura[indexUra].description}\n\n *0* - Voltar ao menu principal`)
|
||||||
|
}
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
// botSendMessage(ticket, contact, wbot, `${data_ura[indexUra].description}\n\n *0* - Voltar ao menu principal`)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue