feat: add notification and sound alert for new tickets in user's service queue
Details: - Implemented functionality to notify users with a sound alert when new tickets arrive in their service queues. fix: include responsible person's name when generating ticket already opened error in all languages Details: - Fixed the error generation process to include the name of the responsible person for the ticket when the system detects an attempt to create an already opened ticket.pull/22/head
parent
e864e0b97f
commit
d7019ffb1a
|
@ -40,6 +40,8 @@ WWebJS
|
||||||
.env.development.local
|
.env.development.local
|
||||||
.env.test.local
|
.env.test.local
|
||||||
.env.production.local
|
.env.production.local
|
||||||
|
.env.save
|
||||||
|
nano.save
|
||||||
|
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class AppError {
|
class AppError {
|
||||||
public readonly message: string;
|
public message: string;
|
||||||
|
|
||||||
public readonly statusCode: number;
|
public readonly statusCode: number;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Op } from "sequelize";
|
import { Op } from "sequelize";
|
||||||
import AppError from "../errors/AppError";
|
import AppError from "../errors/AppError";
|
||||||
import Ticket from "../models/Ticket";
|
import Ticket from "../models/Ticket";
|
||||||
|
import User from "../models/User";
|
||||||
import ListWhatsAppsNumber from "../services/WhatsappService/ListWhatsAppsNumber";
|
import ListWhatsAppsNumber from "../services/WhatsappService/ListWhatsAppsNumber";
|
||||||
import { getSettingValue } from "./WhaticketSettings";
|
import { getSettingValue } from "./WhaticketSettings";
|
||||||
import ListWhatsAppsForQueueService from "../services/WhatsappService/ListWhatsAppsForQueueService";
|
import ListWhatsAppsForQueueService from "../services/WhatsappService/ListWhatsAppsForQueueService";
|
||||||
|
@ -38,8 +39,13 @@ const CheckContactOpenTickets = async (
|
||||||
|
|
||||||
if (ticket) {
|
if (ticket) {
|
||||||
if (handle) return true;
|
if (handle) return true;
|
||||||
|
const userName = await User.findOne({
|
||||||
throw new AppError("ERR_OTHER_OPEN_TICKET");
|
where:{ id: ticket.userId }
|
||||||
|
});
|
||||||
|
const error = new AppError("ERR_OTHER_OPEN_TICKET");
|
||||||
|
error.message = `Erro: já existe um ticket criado com esse contato. Responsável: ${userName? userName.name.toUpperCase() : 'Aguardando'}`;
|
||||||
|
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -409,7 +409,7 @@ const verifyQueue = async (
|
||||||
//test del transfere o atendimento se entrar na ura infinita
|
//test del transfere o atendimento se entrar na ura infinita
|
||||||
const repet: any = await mostRepeatedPhrase(ticket.id);
|
const repet: any = await mostRepeatedPhrase(ticket.id);
|
||||||
|
|
||||||
if (repet.occurrences > 4) {
|
if (repet.occurrences > 10) {
|
||||||
await UpdateTicketService({
|
await UpdateTicketService({
|
||||||
ticketData: { status: "pending", queueId: queues[0].id },
|
ticketData: { status: "pending", queueId: queues[0].id },
|
||||||
ticketId: ticket.id
|
ticketId: ticket.id
|
||||||
|
@ -884,7 +884,7 @@ const handleMessage = async (
|
||||||
|
|
||||||
console.log("repet.occurrences: ", repet.occurrences);
|
console.log("repet.occurrences: ", repet.occurrences);
|
||||||
|
|
||||||
if (repet.occurrences > 4) {
|
if (repet.occurrences > 10) {
|
||||||
await transferTicket(0, wbot, ticket);
|
await transferTicket(0, wbot, ticket);
|
||||||
|
|
||||||
await SendWhatsAppMessage({
|
await SendWhatsAppMessage({
|
||||||
|
|
|
@ -217,43 +217,76 @@ const NotificationsPopOver = () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
socket.on('notifyPeding', data =>{
|
||||||
|
handleNotifications("", data);
|
||||||
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
socket.disconnect()
|
socket.disconnect()
|
||||||
}
|
}
|
||||||
}, [user])
|
}, [user])
|
||||||
|
|
||||||
const handleNotifications = data => {
|
const handleNotifications = (data, notify) => {
|
||||||
const { message, contact, ticket } = data
|
let isQueue = false;
|
||||||
|
if(!notify){
|
||||||
|
const { message, contact, ticket } = data
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
body: `${message.body} - ${format(new Date(), "HH:mm")}`,
|
body: `${message.body} - ${format(new Date(), "HH:mm")}`,
|
||||||
icon: contact.profilePicUrl,
|
icon: contact.profilePicUrl,
|
||||||
tag: ticket.id,
|
tag: ticket.id,
|
||||||
renotify: true,
|
renotify: true,
|
||||||
}
|
|
||||||
|
|
||||||
const notification = new Notification(
|
|
||||||
`${i18n.t("tickets.notification.message")} ${contact.name}`,
|
|
||||||
options
|
|
||||||
)
|
|
||||||
|
|
||||||
notification.onclick = e => {
|
|
||||||
e.preventDefault()
|
|
||||||
window.focus()
|
|
||||||
historyRef.current.push(`/tickets/${ticket.id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
setDesktopNotifications(prevState => {
|
|
||||||
const notfiticationIndex = prevState.findIndex(
|
|
||||||
n => n.tag === notification.tag
|
|
||||||
)
|
|
||||||
if (notfiticationIndex !== -1) {
|
|
||||||
prevState[notfiticationIndex] = notification
|
|
||||||
return [...prevState]
|
|
||||||
}
|
}
|
||||||
return [notification, ...prevState]
|
|
||||||
})
|
|
||||||
|
|
||||||
|
const notification = new Notification(
|
||||||
|
`${i18n.t("tickets.notification.message")} ${contact.name}`,
|
||||||
|
options
|
||||||
|
)
|
||||||
|
|
||||||
|
notification.onclick = e => {
|
||||||
|
e.preventDefault()
|
||||||
|
window.focus()
|
||||||
|
historyRef.current.push(`/tickets/${ticket.id}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
setDesktopNotifications(prevState => {
|
||||||
|
const notfiticationIndex = prevState.findIndex(
|
||||||
|
n => n.tag === notification.tag
|
||||||
|
)
|
||||||
|
if (notfiticationIndex !== -1) {
|
||||||
|
prevState[notfiticationIndex] = notification
|
||||||
|
return [...prevState]
|
||||||
|
}
|
||||||
|
return [notification, ...prevState]
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
user.queues.forEach(queue =>{
|
||||||
|
if(queue.id === notify.data.queue?.id){
|
||||||
|
isQueue = true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if(!isQueue && notify){
|
||||||
|
return;
|
||||||
|
}else{
|
||||||
|
const notification = new Notification(`${i18n.t("tickets.notification.messagePeding")} ${notify.data.queue?.name}`);
|
||||||
|
notification.onclick = e => {
|
||||||
|
e.preventDefault()
|
||||||
|
window.focus()
|
||||||
|
historyRef.current.push(`/tickets`)
|
||||||
|
}
|
||||||
|
|
||||||
|
setDesktopNotifications(prevState => {
|
||||||
|
const notfiticationIndex = prevState.findIndex(
|
||||||
|
n => n.tag === notification.tag
|
||||||
|
)
|
||||||
|
if (notfiticationIndex !== -1) {
|
||||||
|
prevState[notfiticationIndex] = notification
|
||||||
|
return [...prevState]
|
||||||
|
}
|
||||||
|
return [notification, ...prevState]
|
||||||
|
})
|
||||||
|
}
|
||||||
soundAlertRef.current()
|
soundAlertRef.current()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -241,6 +241,7 @@ const messages = {
|
||||||
},
|
},
|
||||||
notification: {
|
notification: {
|
||||||
message: "Message from",
|
message: "Message from",
|
||||||
|
messagePeding: "new ticket in queue",
|
||||||
},
|
},
|
||||||
tabs: {
|
tabs: {
|
||||||
open: { title: "Inbox" },
|
open: { title: "Inbox" },
|
||||||
|
|
|
@ -245,6 +245,7 @@ const messages = {
|
||||||
},
|
},
|
||||||
notification: {
|
notification: {
|
||||||
message: "Mensaje de",
|
message: "Mensaje de",
|
||||||
|
messagePeding: "Nuevo billete en cola",
|
||||||
},
|
},
|
||||||
tabs: {
|
tabs: {
|
||||||
open: { title: "Bandeja" },
|
open: { title: "Bandeja" },
|
||||||
|
|
|
@ -244,6 +244,7 @@ const messages = {
|
||||||
},
|
},
|
||||||
notification: {
|
notification: {
|
||||||
message: "Mensagem de",
|
message: "Mensagem de",
|
||||||
|
messagePeding: "Novo ticket na fila",
|
||||||
},
|
},
|
||||||
tabs: {
|
tabs: {
|
||||||
open: { title: "Inbox" },
|
open: { title: "Inbox" },
|
||||||
|
|
Loading…
Reference in New Issue