|
|
|
|
/**
|
|
|
|
|
* EVENTOS GERADOS PELO USU<EFBFBD>RIO DA APLICA<EFBFBD><EFBFBD>O
|
|
|
|
|
*/
|
|
|
|
|
$(function(){
|
|
|
|
|
connect(ws)
|
|
|
|
|
notifications()
|
|
|
|
|
/**
|
|
|
|
|
* VOICE RECORDER
|
|
|
|
|
*/
|
|
|
|
|
$('.modal-content-body').on('click', '#stoprecorder', () => {
|
|
|
|
|
$('#msgRecorder').text('Paramos de gravar sua voz!')
|
|
|
|
|
mediaRecorder.stop()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
$('#voicerecorder').on('click', () => {
|
|
|
|
|
recorderVoice()
|
|
|
|
|
})
|
|
|
|
|
/** FIM VOICE RECORDER */
|
|
|
|
|
|
|
|
|
|
/** EVENTOS DE CLICK NO BODY */
|
|
|
|
|
$("body").mouseup(function(){
|
|
|
|
|
$('#uploadfiles').fadeOut('slow')
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/** INICIO DAS FUNCIONALIDADES */
|
|
|
|
|
startSendImage()
|
|
|
|
|
startSendFile()
|
|
|
|
|
startPause()
|
|
|
|
|
startTransfer()
|
|
|
|
|
startFinalizar()
|
|
|
|
|
exitSystem()
|
|
|
|
|
|
|
|
|
|
/** INICIA COM O HEADER DO CONTATO VAZIO */
|
|
|
|
|
startChannelMessage()
|
|
|
|
|
|
|
|
|
|
/** INICIA O CHAT NO FINAL DA CONVERSA */
|
|
|
|
|
$('.chats').on('click', function(){
|
|
|
|
|
scrollDown()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
/** ENVIA AS MSG PELO ENTER */
|
|
|
|
|
$('#fieldsendmessage').bind('keyup', function(ev){
|
|
|
|
|
if(ev.keyCode == 13){
|
|
|
|
|
sendMessage()
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
$('.type-message-bar-right').on('click',() => {
|
|
|
|
|
sendMessage()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
$('#imgclip').on('click', function(){
|
|
|
|
|
modalStart()
|
|
|
|
|
$("#uploadimage").val('')
|
|
|
|
|
$('#uploadfile').val('')
|
|
|
|
|
if($('#uploadfiles').is(':hidden')){
|
|
|
|
|
$('#uploadfiles').fadeIn('slow')
|
|
|
|
|
} else {
|
|
|
|
|
$('#uploadfiles').fadeOut('slow')
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
$('#footer-content-right').on('click', '#footersend', () => {
|
|
|
|
|
sendMedia(mediaRecorder)
|
|
|
|
|
$('#modalselect').css({display: 'none'})
|
|
|
|
|
})
|
|
|
|
|
supervisorAgente()
|
|
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* EVENTOS DE CLICK PARA SELECIONAR A SESS<EFBFBD>O DE MENSAGEM/CONVERSA E RECUPERAR AS MENSAGENS J<EFBFBD> TROCADAS NO ATENDIMENTO
|
|
|
|
|
* @param {*} id
|
|
|
|
|
*/
|
|
|
|
|
const selectNotification = (id) => {
|
|
|
|
|
marcarMensagemVista(id)
|
|
|
|
|
|
|
|
|
|
listaMensagem(id).then(() => {
|
|
|
|
|
let uniqueid
|
|
|
|
|
let number
|
|
|
|
|
let name
|
|
|
|
|
let dataContact
|
|
|
|
|
let protocolo
|
|
|
|
|
|
|
|
|
|
const dataRequest = JSON.parse(localStorage.getItem('obj_contact'))
|
|
|
|
|
listarAtendimentoAgente(localStorage.getItem('my_uniqueid'))
|
|
|
|
|
const allNotifications = JSON.parse(localStorage.getItem('obj_notification'))
|
|
|
|
|
|
|
|
|
|
hideButtons(false)
|
|
|
|
|
allNotifications.data.forEach(e => {
|
|
|
|
|
$('#' + e.uniqueid.replace('.', `\\.`)).removeClass('select-notification')
|
|
|
|
|
if(e.uniqueid == id && e.status == 0){
|
|
|
|
|
hideButtons(true)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
$('#' + id.replace('.', `\\.`)).addClass('select-notification')
|
|
|
|
|
|
|
|
|
|
allNotifications.data.forEach(e => {
|
|
|
|
|
if(e.uniqueid == id && e.status == 0){
|
|
|
|
|
hideButtons(true)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if(dataRequest.data.length > 0){
|
|
|
|
|
dataContact = dataRequest.data.filter(e => {
|
|
|
|
|
if(id.trim() == e.event?.mensagem.uniqueid){
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
allNotifications.data.forEach(e => {
|
|
|
|
|
if(id === e.uniqueid){
|
|
|
|
|
uniqueid = e.uniqueid
|
|
|
|
|
name = e.nome
|
|
|
|
|
number = e.cliente_id
|
|
|
|
|
protocolo = e.protocolo
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
localStorage.removeItem('session_window')
|
|
|
|
|
localStorage.removeItem('session_uniqueid')
|
|
|
|
|
localStorage.setItem('session_uniqueid', uniqueid)
|
|
|
|
|
localStorage.setItem('session_window', number)
|
|
|
|
|
|
|
|
|
|
$('.chat-window-contact-name').text(name)
|
|
|
|
|
$('.chat-window-contact-status').text('Protocolo: ' + protocolo)
|
|
|
|
|
|
|
|
|
|
/** REMOVE AS MSG NA E CONSTRIO A TELA NOVAMENTE (EVITAR DUPLICAR) */
|
|
|
|
|
$('.chat-window .sender').remove()
|
|
|
|
|
$('.chat-window .receiver').remove()
|
|
|
|
|
$('.chat-window .events').remove()
|
|
|
|
|
alertNotification(localStorage.getItem('session_uniqueid'),'remove')
|
|
|
|
|
|
|
|
|
|
dataContact.forEach(e => {
|
|
|
|
|
const datesend = e.event?.mensagem.datetime ? converdata(new Date(e.event?.mensagem.datetime).getTime()) : 'algumas horas';
|
|
|
|
|
let typesend = localStorage.getItem('my_uniqueid') == e.event.contact.number ? 'sender': 'receiver'
|
|
|
|
|
|
|
|
|
|
if(e.event?.mensagem.type == 'text'){
|
|
|
|
|
$('.chat-window').append(`
|
|
|
|
|
<div class="${typesend}">
|
|
|
|
|
<span class="${typesend}-message">${e.event.mensagem.content}</span>
|
|
|
|
|
<br/>
|
|
|
|
|
<span class="message-time">${datesend}</span>
|
|
|
|
|
</div>`
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(e.event?.mensagem.type == 'finish' || e.event?.mensagem.type == 're_start'){
|
|
|
|
|
$('.chat-window').append(`
|
|
|
|
|
<div class="events">
|
|
|
|
|
<span class="events-message">${e.event.mensagem.content}</span>
|
|
|
|
|
</div>`
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(e.event?.mensagem.type != 'text'){
|
|
|
|
|
const sendobj = {
|
|
|
|
|
filename: e.event?.mensagem.file_name,
|
|
|
|
|
id_provedor: e.event?.mensagem.id_provedor,
|
|
|
|
|
type: e.event?.mensagem.type,
|
|
|
|
|
mimetype: e.event?.mensagem.mimetype,
|
|
|
|
|
from: typesend
|
|
|
|
|
}
|
|
|
|
|
messageTypeMedia(sendobj)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(e.de == localStorage.getItem('my_uniqueid')){
|
|
|
|
|
const datereceived = e.datetime ? converdata(e.datetime) : 'algumas horas';
|
|
|
|
|
if(e.type == 'text'){
|
|
|
|
|
$('.chat-window').append(`
|
|
|
|
|
<div class="${typesend}">
|
|
|
|
|
<span class="${typesend}-message">${e.msg}</span>
|
|
|
|
|
<br/>
|
|
|
|
|
<span class="message-time">${datereceived}</span>
|
|
|
|
|
</div>`)
|
|
|
|
|
} else if (e.type == 'audio' || e.type == 'voice'){
|
|
|
|
|
const audio = `<audio controls>
|
|
|
|
|
<source src="data:audio/mpeg;base64,${e.msg}"></source>
|
|
|
|
|
</audio>`
|
|
|
|
|
$('.chat-window').append(`
|
|
|
|
|
<div class="${typesend}">
|
|
|
|
|
<span class="${typesend}-message">${audio}</span>
|
|
|
|
|
<br/>
|
|
|
|
|
<span class="message-time">${datereceived}</span>
|
|
|
|
|
</div>`)
|
|
|
|
|
} else if (e.type == 'document'){
|
|
|
|
|
icontypes.forEach(l => {
|
|
|
|
|
if(e.filename.indexOf(l) >= 0){
|
|
|
|
|
$('.chat-window').append(`
|
|
|
|
|
<div class="${typesend}">
|
|
|
|
|
<span class="${typesend}-message message-column">
|
|
|
|
|
<a href="http://${server_api}/integracao/media/link/${e.uniqueid}/${window.btoa('application/' + l)}" target="_blank">
|
|
|
|
|
<img src="integracao/simpleschat/images/icons/${l}-file.png" style="max-width: 60px">
|
|
|
|
|
</a>
|
|
|
|
|
</span>
|
|
|
|
|
${e.filename}
|
|
|
|
|
<br/>
|
|
|
|
|
<span class="message-time">${datereceived}</span>
|
|
|
|
|
</div>`)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
} else if (e.type == 'image'){
|
|
|
|
|
const fileimg = `data:${e.mimetype};base64,` + e.msg
|
|
|
|
|
$('.chat-window').append(`
|
|
|
|
|
<div class="${typesend}">
|
|
|
|
|
<span class="${typesend}-message"><img src="${fileimg}" style="max-width: 200px; max-height: 150px"></span>
|
|
|
|
|
<br/>
|
|
|
|
|
<span class="message-time">${datereceived}</span>
|
|
|
|
|
</div>`)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
scrollDown()
|
|
|
|
|
})
|
|
|
|
|
startNotification()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* REALIZA O ENVIO DE MENSAGEM ATRAVEZ DA API
|
|
|
|
|
* @param {*} obj
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
|
|
|
|
const sendMessage = (obj = {}) => {
|
|
|
|
|
const sendNumber = localStorage.getItem('session_window')
|
|
|
|
|
const myUniqueid = localStorage.getItem('my_uniqueid')
|
|
|
|
|
const agent = JSON.parse(localStorage.getItem('obj_status'))
|
|
|
|
|
|
|
|
|
|
let sendContent = (typeof obj.fileContent === "undefined") ? $('#fieldsendmessage').val() : obj.content
|
|
|
|
|
let name = agent.data.nome ? agent.data.nome : 'Atendente'
|
|
|
|
|
let uniqueid = localStorage.getItem('session_uniqueid')
|
|
|
|
|
let media = obj.media ? obj.media : 'whatsapp'
|
|
|
|
|
let type = obj.type ? obj.type : 'text'
|
|
|
|
|
let mimetype = obj.mimetype ? obj.mimetype : 'text'
|
|
|
|
|
let filename = obj.filename ? obj.filename : Date.now()
|
|
|
|
|
|
|
|
|
|
if(!sendContent){
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let dataSend = {
|
|
|
|
|
"event": {
|
|
|
|
|
"type": "mensagem",
|
|
|
|
|
"contact": {
|
|
|
|
|
"name": name,
|
|
|
|
|
"number": myUniqueid,
|
|
|
|
|
"matricula": myUniqueid
|
|
|
|
|
},
|
|
|
|
|
"mensagem": {
|
|
|
|
|
"uniqueid": uniqueid,
|
|
|
|
|
"dst": sendNumber,
|
|
|
|
|
"id_provedor": `${uniqueid}_${Date.now()}`,
|
|
|
|
|
"type": type,
|
|
|
|
|
"mimetype": mimetype,
|
|
|
|
|
"media": media,
|
|
|
|
|
"content": sendContent,
|
|
|
|
|
"status": "sended"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(type != 'audio'){
|
|
|
|
|
dataSend.event.mensagem.file_name = filename
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enviarMensagem(dataSend)
|
|
|
|
|
|
|
|
|
|
let msgContent = type == 'text' ? sendContent : obj.fileContent
|
|
|
|
|
$('.chat-window').append(`
|
|
|
|
|
<div class="sender">
|
|
|
|
|
<span class="sender-message">${msgContent}</span>
|
|
|
|
|
<br/>
|
|
|
|
|
<span class="message-time">${converdata(Date.now())}</span>
|
|
|
|
|
</div>`)
|
|
|
|
|
scrollDown()
|
|
|
|
|
|
|
|
|
|
/** LIMPA O CAMPO DE ENVIO DE MENSAGEM */
|
|
|
|
|
$('#fieldsendmessage').val("")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* ATUALIZA AS MENSAGEM QUE S<EFBFBD>O RECEBIDAS NA TELA DO ATENDIMENTO
|
|
|
|
|
* @param {*} ev
|
|
|
|
|
*/
|
|
|
|
|
const viewMessage = (ev) => {
|
|
|
|
|
const sessionOpen = localStorage.getItem('session_uniqueid')
|
|
|
|
|
const datesend = ev.event?.mensagem.datetime ? converdata(ev.event?.mensagem.datetime, true) : 'algumas horas';
|
|
|
|
|
|
|
|
|
|
if(ev.event?.mensagem.uniqueid == sessionOpen){
|
|
|
|
|
marcarMensagemVista(sessionOpen)
|
|
|
|
|
switch(ev.event?.mensagem.type){
|
|
|
|
|
case 'text':
|
|
|
|
|
$('.chat-window').append(`
|
|
|
|
|
<div class="receiver">
|
|
|
|
|
<span class="receiver-message">${ev.event.mensagem.content}</span>
|
|
|
|
|
<br/>
|
|
|
|
|
<span class="message-time">${datesend}</span>
|
|
|
|
|
</div>`)
|
|
|
|
|
break
|
|
|
|
|
case 'finish':
|
|
|
|
|
case 're_start':
|
|
|
|
|
$('.chat-window').append(`
|
|
|
|
|
<div class="events">
|
|
|
|
|
<span class="events-message">${ev.event.mensagem.content}</span>
|
|
|
|
|
</div>`)
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const mediaDownload = ["image", "voice", "document", "audio", "video", "sticker"]
|
|
|
|
|
if(mediaDownload.indexOf(ev.event?.mensagem.type) >= 0){
|
|
|
|
|
const sendobj = {
|
|
|
|
|
filename: ev.event?.mensagem.file_name,
|
|
|
|
|
id_provedor: ev.event?.mensagem.id_provedor,
|
|
|
|
|
type: ev.event?.mensagem.type,
|
|
|
|
|
mimetype: ev.event?.mensagem.mimetype,
|
|
|
|
|
from: 'receiver'
|
|
|
|
|
}
|
|
|
|
|
messageTypeMedia(sendobj)
|
|
|
|
|
}
|
|
|
|
|
scrollDown()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* APRESENTA AS NOVAS NOTIFICACOES DE ATENDIMENTO NA TELA DO ATENDENTE
|
|
|
|
|
* -> CADA ATENDIMENTO DEVE POSSUIR APENAS UMA NOTIFICACAO
|
|
|
|
|
* @param {*} data
|
|
|
|
|
*/
|
|
|
|
|
const receiveNotification = (data) => {
|
|
|
|
|
let validate = null
|
|
|
|
|
|
|
|
|
|
switch(data.event?.type){
|
|
|
|
|
case "mensagem":
|
|
|
|
|
if(data.event.mensagem.uniqueid != localStorage.getItem('session_uniqueid')){
|
|
|
|
|
notifyMe(data.event.contact.name, {
|
|
|
|
|
body: data.event.mensagem.content,
|
|
|
|
|
icon: `images/${data.event.mensagem.media}.png`,
|
|
|
|
|
silent: true
|
|
|
|
|
})
|
|
|
|
|
soundNotification(`integracao/simpleschat/sound/notification.mp3`)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** VALIDA O NUMERO, VERIFICA SE O TEM ALGMA MSG INICIAL, SE J<EFBFBD> TEVE UM NUMERO NA VERIFICACAO */
|
|
|
|
|
listarAtendimentoAgente(localStorage.getItem('my_uniqueid'))
|
|
|
|
|
validate = JSON.parse(localStorage.getItem('obj_notification'))
|
|
|
|
|
|
|
|
|
|
const vald = validate.data.filter((e) => {
|
|
|
|
|
return data.event?.mensagem.uniqueid == e.uniqueid
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if(data.event?.contact.number != localStorage.getItem('session_window')){
|
|
|
|
|
alertNotification(data.event?.mensagem.uniqueid)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (data.event?.mensagem.uniqueid && data.event?.contact.number && vald.length == 0) {
|
|
|
|
|
notifications(
|
|
|
|
|
{
|
|
|
|
|
uniqueid: data.event?.mensagem.uniqueid,
|
|
|
|
|
cliente_id: data.event?.contact.number,
|
|
|
|
|
context: data.event?.mensagem.media,
|
|
|
|
|
profile_name: data.event?.contact.name,
|
|
|
|
|
data_reg: data.event?.mensagem.datetime,
|
|
|
|
|
status: 1,
|
|
|
|
|
action: 'mensagem',
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
case "actions":
|
|
|
|
|
let obj
|
|
|
|
|
switch(data.event.mensagem.type){
|
|
|
|
|
case 'start':
|
|
|
|
|
case 'transfer':
|
|
|
|
|
case 'att_status':
|
|
|
|
|
obj = {}
|
|
|
|
|
break
|
|
|
|
|
case 'finish':
|
|
|
|
|
case 're_start':
|
|
|
|
|
obj = {
|
|
|
|
|
uniqueid: data.event?.mensagem.uniqueid,
|
|
|
|
|
action: data.event.mensagem.type,
|
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
notifications(obj)
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* MANTEM TODAS AS MENSAGENS ARMAZENADAS NO LOCALSTORAGE, SEMPRE QUE ENVIA E RECEBE SER<EFBFBD> GUARDADO
|
|
|
|
|
* @param {*} ev
|
|
|
|
|
*/
|
|
|
|
|
const keepMensage = (ev) => {
|
|
|
|
|
let msg = JSON.parse(localStorage.getItem('keep_msg'))
|
|
|
|
|
if(!msg){
|
|
|
|
|
msg = { data: [] }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(ev.event?.contact && ev.event?.mensagem.content){
|
|
|
|
|
msg.data.push(ev)
|
|
|
|
|
localStorage.removeItem('keep_msg');
|
|
|
|
|
localStorage.setItem('keep_msg', JSON.stringify(msg))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* FUN<EFBFBD><EFBFBD>O PARA CAPTURAR O ARQUIVO A SER ENVIADO
|
|
|
|
|
*/
|
|
|
|
|
const sendMedia = (media = null) => {
|
|
|
|
|
let rec
|
|
|
|
|
let filename
|
|
|
|
|
if($("#footer-content-left audio").length){
|
|
|
|
|
if(media.state == 'recording'){
|
|
|
|
|
media.stop();
|
|
|
|
|
}
|
|
|
|
|
let el = $("#footer-content-left audio")[0].src
|
|
|
|
|
fileContent = $("#footer-content-left audio")[0].outerHTML
|
|
|
|
|
sendMessage({ content: el.replace("data:", "").replace(/^.+,/, ""), type: 'audio', mimetype: 'audio/mpeg', fileContent })
|
|
|
|
|
return
|
|
|
|
|
} else if($("#uploadfile")[0].files[0]) {
|
|
|
|
|
let el = $("#uploadfile")[0].files[0]
|
|
|
|
|
rec = new Blob([el], { type : el.type })
|
|
|
|
|
let filesent = $("#myImg")
|
|
|
|
|
filesent[0].id = Date.now()
|
|
|
|
|
imgContent = filesent.css({'max-width': '60px'})[0].outerHTML
|
|
|
|
|
fileContent = `<a href="${URL.createObjectURL(rec)}" target="_blank">${imgContent}</a>`
|
|
|
|
|
filename = el.name
|
|
|
|
|
} else {
|
|
|
|
|
rec = $("#uploadimage")[0].files[0]
|
|
|
|
|
let filesent = $("#myImg")
|
|
|
|
|
filesent[0].id = Date.now()
|
|
|
|
|
fileContent = filesent.css({'max-width': '350px'})[0].outerHTML
|
|
|
|
|
$("#myImg").empty()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const file = new FileReader();
|
|
|
|
|
file.onload = function() {
|
|
|
|
|
const typefile = rec.type.split("/")[0].indexOf('image') >= 0 ? rec.type.split("/")[0] : 'document'
|
|
|
|
|
sendMessage({ content: file.result.replace("data:", "").replace(/^.+,/, ""), type: typefile, mimetype: rec.type, fileContent, filename })
|
|
|
|
|
}
|
|
|
|
|
file.readAsDataURL(rec);
|
|
|
|
|
}
|