Compare commits

...

33 Commits

Author SHA1 Message Date
Felipe Fontana a18cc02a2b correção enviar media 10 months ago
Felipe Fontana 9ee43368bc Correção enviar audio 10 months ago
Felipe Fontana 2409c30b23 att link config 10 months ago
Felipe Fontana 4353716a21 correção link config 10 months ago
Felipe Fontana 9778b3f4fb correção link 10 months ago
Felipe Fontana 74fcbf6db7 correção link server_api 10 months ago
Felipe Fontana 4d8cede59e corrigindo link 10 months ago
Felipe Fontana fea7aacebb adicionando channel id ao enviar hsm e atualizando exibição de contatos com 9 numeros 10 months ago
Felipe Fontana 8ef4dfbe9c alterando link chumbado do server api 11 months ago
Felipe Fontana 3defb867ed Adicionando botão de salvar contato 11 months ago
guilherme guia 6d77a24a9f Adicionando configs de busca 12 months ago
guilherme guia 20295efdba Adicionando evento que captura resposta ao um envio de hsm template e renderiza o chat do atendente 12 months ago
guilherme guia bc1b038a0f Habilitando o cadastro de contatos 12 months ago
guilherme guia b93ff58453 Habilitando a pesquisa de atendimentos na fila de espera e em conversasao 12 months ago
guilherme guia f7beaab989 Adicionando funcao de loading button no envio de hsm message 12 months ago
guilherme guia 25c9da610d Adicionando pesquisa por protocolo/nome/numero 12 months ago
guilherme guia fb06f15d0b Adicionado notificação toast 12 months ago
guilherme guia f9a8b7fb4e retirando chevron do select pausa 12 months ago
guilherme guia eb3dc30875 Adicionando loading no botao de transferencia 12 months ago
guilherme guia 6f3d7c72f3 Funcionalidade de recuperar atendimento 1 year ago
guilherme guia b2b79b380b Funcionalidade em andamento 1 year ago
guilherme guia 1f8798a145 Alteracao http 1 year ago
guilherme guia aefcf635c1 Correcao de tamanho de badge 1 year ago
guilherme guia 4db89dcb5f Adicao funcionalidade envio de Mensagem e correcao envio de media 1 year ago
guilherme guia 334c71d045 Adicionando modal de contatos 1 year ago
Lucas Awade 95e868c944 Atualizar 'Dockerfile' 1 year ago
Lucas Awade 242f4d8277 Atualizar 'Dockerfile' 1 year ago
Lucas Awade 5813e5108b Merge pull request 'lucas' (#24) from lucas into dev 1 year ago
Lucas Awade 69b2607059 Merge pull request 'v.0.0.2' (#22) from v.0.0.2 into dev 1 year ago
Lucas Awade 0e2ca867ef ajustes, correções na transferencia 1 year ago
Lucas Awade 3929691013 novas correções na API 1 year ago
Lucas Awade 55b74571cd Merge pull request 'adicição do nome do agente as mensagens' (#15) from lucas into dev 2 years ago
Lucas Awade 1131016f76 Merge pull request 'atualização fila' (#13) from gguia into dev 2 years ago
  1. 3
      .vscode/settings.json
  2. 7
      Dockerfile
  3. 181
      app/view/content.php
  4. 100
      index.php
  5. 627
      public/css/styles.css
  6. BIN
      public/images/cuidado.png
  7. 12
      public/js/config.js
  8. 384
      public/js/main.js
  9. 249
      public/js/requests.js
  10. 696
      public/js/util.js
  11. 4
      storage/logs/display_erros.log
  12. 2
      ws.php

3
.vscode/settings.json vendored

@ -1,3 +1,4 @@
{
"svn.ignoreMissingSvnWarning": true
"svn.ignoreMissingSvnWarning": true,
"files.encoding": "utf8"
}

7
Dockerfile

@ -1,4 +1,6 @@
FROM php:7.4-fpm
ENV TZ=America/Cuiaba
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
@ -8,9 +10,10 @@ RUN apt-get update && apt-get install -y \
&& docker-php-ext-install -j$(nproc) gd
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php -r "if (hash_file('sha384', 'composer-setup.php') === '55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
RUN php composer-setup.php
RUN php -r "if (hash_file('sha384', 'composer-setup.php') === 'e21205b207c3ff031906575712edab6f13eb0b361f2085f1f1237b7126d785e826a450292b6cfd1d64d92e6563bbde02') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
RUN php composer-setup.php --filename=composer --install-dir=/bin
RUN php -r "unlink('composer-setup.php');"
WORKDIR /var/www/html

181
app/view/content.php

@ -11,33 +11,33 @@
<span class="sidebar-span">STATUS: <span class="status-connect" id="status_agent"></span></span>
</div>
<div class="sidebar-header-icons">
<div id="btnsPause"></div>
<img src="<?= $files ?>/images/power.svg" id="exitSystem" alt="Desconectar do Chat" title="Sair do sistema" />
<!-- <img src="<?= $files ?>/images/settings.png" title="Configurações" id="configs"/> -->
<input type="checkbox" class="checkbox-switch" id="input-checkbox-switch">
<label for="input-checkbox-switch" class="label-switch">
<!-- <span><i class="fas fa-sun"></i></span>
<span><i class="fas fa-moon"></i></span> -->
<div class="switch-ball light-mode">
<span><i class="fas fa-sun"></i></span>
</div>
</label>
<span>
<i class="fas fa-power-off icon" id="exitSystem" alt="Desconectar do Chat" title="Sair do sistema"></i>
</span>
<span id="btnsPause">
</span>
<span class="relative" id="abrirContato">
<i class="fas fa-comment-alt icon" title="Nova conversa"></i>
<i class="fas fa-plus plus absolute" title="Nova conversa"></i>
</span>
<!-- <span>
<i class="fas fa-ellipsis-v icon" title="Mais opções"></i>
</span> -->
</div>
</div>
<div class="box-event-buttons">
<button class="btn-atendimento button-selected" id="btnAtendimento">Em atendimento </button>
<button class="btn-fila" id="btnFila">Em espera</button>
</div>
<button class="btn-atendimento button-selected" id="btnAtendimento">Em atendimento </button>
<button class="btn-fila" id="btnFila">Em espera</button>
</div>
<div class="search">
<i class="fas fa-search search-icon"></i>
<input type="text" class="search-form" placeholder="Search" id="search-form">
<input type="text" class="search-form" placeholder="Pesquisar atendimento" id="search-form">
</div>
<div class="chats" id="chats">
</div>
</div>
<div class="main">
<div class="fade"></div>
<div class="fade"></div>
<div class="chat-window-header">
<div class="chat-window-header-left" id="headermediaagent">
@ -49,14 +49,22 @@
</div>
</div>
<div class="chat-window-header-right" id="headerbuttonsagent">
<div class="chat-window-header-right-commands btn-info" id="salvarcontato" title="Salvar contato">
<i class="fas fa-user-plus btn-icon"></i>
<span class="chat-window-menu-span"> Salvar Contato</span>
</div>
<div class="chat-window-header-right-commands btn-info" id="tranferagent" title="Transferir atendimento">
<img class="chat-window-menu-icon" src="<?= $files ?>/images/redo.svg" />
<i class="fas fa-exchange-alt btn-icon"></i>
<span class="chat-window-menu-span"> Transferir</span>
</div>
<div class="chat-window-header-right-commands btn-danger" id="finalizaratendimento" title="Finalizar atendimento">
<img class="chat-window-menu-icon" src="<?= $files ?>/images/cross-circle.svg" />
<i class="fas fa-check btn-icon"></i>
<span class="chat-window-menu-span"> Finalizar</span>
</div>
<div class="chat-window-header-right-commands btn-info" id="recuperaratendimento" title="Recuperar atendimento">
<i class="fas fa-undo-alt btn-icon"></i>
<span class="chat-window-menu-span"> Recuperar</span>
</div>
</div>
<span id="chat-window-header-right-icon" class="responsive-icon-header"><i class="fas fa-ellipsis-v"></i></span>
</div>
@ -78,26 +86,50 @@
</label>
<input id="uploadimage" accept="image/*,video/mp4,video/3gpp,video/quicktime" type="file" multiple="" style="display: none;">
</div>
<div class="type-message-bar" id="typemessagebar">
<div class="template-messages">
<div class="container-template-header">
<h1 class="template-title"><i class="fas fa-folder icon"></i>Escolha um template para ser enviado</h1>
</div>
<div class="container-template-body">
<div class="select">
<div id="category-select">
<input type="checkbox" id="option-view-button">
<div id="select-button">
<div id="selected-value">Selecione o template</div>
<div id="chevrons">
<i class="fas fa-chevron-down"></i>
<i class="fas fa-chevron-up"></i>
</div>
</div>
</div>
<ul id="options" class="hidden"></ul>
</div>
<div class="template">
</div>
<button class="btn" id="btn-enviar-template">Enviar Mensagem</button>
</div>
</div>
<div class="type-message-bar-center">
<textarea rows="1" type="text" id="fieldsendmessage" placeholder="Escreva uma mensagem" style="resize: none;"></textarea>
</div>
<div class="type-message-bar-right flex-center">
<img src="<?= $files ?>/images/microphone.svg" id="voicerecorder" title="Enviar mensagem de audio" class="icons file"/>
<img src="<?= $files ?>/images/clip.svg" id="imgclip" title="Anexar arquivo ou imagem" class="icons file"/>
<img src="<?= $files ?>/images/send-message.png" title="Enviar mensagem" class="icons send"/>
<img src="<?= $files ?>/images/microphone.svg" id="voicerecorder" title="Enviar mensagem de audio" class="icons file" />
<img src="<?= $files ?>/images/clip.svg" id="imgclip" title="Anexar arquivo ou imagem" class="icons file" />
<img src="<?= $files ?>/images/send-message.png" title="Enviar mensagem" class="icons send" />
</div>
</div>
</div>
</div>
</div>
</div>
<?php } ?>
<div id="modalselect" class="modal">
<div class="modal-content">
<div class="modal-header">
@ -114,31 +146,90 @@
</div>
</div>
<div id="offcanvas" class="offcanvas listar-contato">
<div class="offcanvas-header">
<span class="btn-box" id="btn-inicial">
<i class="fas fa-arrow-left icon"></i>
</span>
<h1>Nova conversa</h1>
</div>
<div class="offcanvas-body">
<div class="pesquisa">
<i class="fas fa-arrow-left icon"></i>
<input type="text" placeholder="Pesquise nome ou numero">
</div>
<div class="contatos-header">
<div class="btn-box" id="btn-add">
<div class="circle">
<i class="fas fa-user-plus icon"></i>
</div>
<h1>Novo contato</h1>
</div>
</div>
<h1 class="contatos-title">Lista de contatos</h1>
<div class="contatos">
</div>
</div>
</div>
<div id="offcanvas" class="offcanvas cadastro-contato">
<form id="form-contato">
<div class="offcanvas-header">
<span class="btn-box" id="btn-contatos">
<i class="fas fa-arrow-left icon"></i>
</span>
<h1>Adicionar contato</h1>
</div>
<div class="offcanvas-body">
<div class="input-container">
<label for="">Nome: </label>
<input type="text" name="nome" placeholder="Digite o nome: " required>
</div>
<div class="input-container">
<label for="">Número: </label>
<input type="text" name="contato" placeholder="+55 XX XXXXX-XXXX" required maxlength="19">
</div>
<div class="input-container">
<label for="">Email: (opcional) </label>
<input type="text" name="email" placeholder="Digite o email: ">
</div>
<div class="input-container">
<label for="">Ativo: </label>
<div class="radio-container">
<input type="radio" name="ativo" checked value="on"> <span>Sim</span>
<input type="radio" name="ativo" value="off"> <span>Não</span>
</div>
</div>
<div class="input-container">
<label for="">Descrição: (opcional)</label>
<textarea name="descricao" rows="5" placeholder="Digite uma descrição"></textarea>
</div>
</div>
<div class="offcanvas-footer">
<button type="submit" id="btn-contato">Cadastrar</button>
</div>
</form>
</div>
<div class="toast">
<div class="toast-content">
<div class="toast-img">
</div>
<div class="toast-body">
</div>
<span class="close-toast">&times;</span>
</div>
</div>
<script>
let modal = document.getElementById("modalselect");
let span = document.getElementsByClassName("close")[0];
span.onclick = function() {
modal.style.display = "none";
}
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
<?php
foreach ($jsStartup as $key => $jquery) {
echo "<script id='myscript{$key}' type='text/javascript'>{$jquery}</script>";
}
?>
<script src="<?= $files ?>/js/jquery-3.6.0.min.js"></script>
<script src="<?= $files ?>/js/config.js"></script>
<script src="<?= $files ?>/js/cronometro.js"></script>
<script src="<?= $files ?>/js/requests.js"></script>
<script src="<?= $files ?>/js/util.js"></script>
<script src="<?= $files ?>/js/main.js"></script>
<?php
foreach ($jsStartup as $jquery) {
echo "<script type='text/javascript'>{$jquery}</script>";
}
?>
<script src="<?= $files ?>/js/main.js"></script>

100
index.php

@ -1,5 +1,4 @@
<?php
include "config/includes.php";
use app\Provider\Crypt;
@ -10,33 +9,12 @@ $geturl = bootstrap();
$post = is_postback();
$connected = false;
if ($geturl['t'] == 'gerar' && $post['passwd'] == 'S1MPL3S1P_CH4T') {
$expireToken = strtotime("+{$post['expire']} days", time());
$info = [
"id_number" => $post['id_number'],
"id_empresa" => $post['id_empresa'],
"servidor" => $post['servidor'],
"websocket" => "ws://{$post['servidor']}:8080",
"matricula" => $post['matricula'],
"fila" => $post['fila'],
"expire" => $expireToken
];
$token = $crypt->encrypt(json_encode($info, true));
echo "Token: <input type='text' value='{$token}' size='90'><br><br>";
// echo "<a href='http://{$post['servidor']}:8001/?t=$token' target='_blank'><b>Ir para</b></a>";
echo "<a href='http://localhost:8001/?t=$token' target='_blank'><b>Ir para</b></a>";
exit;
}
if ($geturl['t']) {
if ($geturl['t'] != 'gerar') {
$json = json_decode($crypt->decrypt(str_replace(' ', '+', $geturl['t'])), true);
$objs = [
'token' => $json['token'],
'id_number' => $json['id_number'],
'id_empresa' => $json['id_empresa'],
'obj_server' => $json['servidor'],
'my_uniqueid' => $json['matricula'],
'obj_queue' => $json['fila'],
'obj_ws' => $json['websocket'],
'session_uniqueid' => null,
@ -45,7 +23,6 @@ if ($geturl['t']) {
'obj_status' => null,
'session_window' => null
];
foreach ($objs as $key => $val) {
$jsStartup[] = "localStorage.removeItem('{$key}')";
if ($val) {
@ -54,6 +31,64 @@ if ($geturl['t']) {
}
$connected = true;
}
if ($geturl['t'] == 'gerar' && isset($post['btnSend'])) {
$bearertoken = login($post['servidor'], $post['email'], $post['password']);
if (!$bearertoken) {
echo "Não foi possível gerar o token, confirme seu email e senha!";
exit;
}
$info = [
"token" => $bearertoken,
"id_number" => $post['id_number'],
"id_empresa" => $post['id_empresa'],
"servidor" => $post['servidor'],
"websocket" => "ws://192.168.115.132:8080",
"matricula" => $post['matricula'],
"fila" => $post['fila'],
"expire" => $expireToken
];
$token = $crypt->encrypt(json_encode($info, true));
echo "Token: <input type='text' value='{$token}' size='90'><br><br>";
//echo "<a href='http://192.168.115.244:8001/?t=$token' target='_blank'><b>Ir para</b></a>";
echo "<a href='http://192.168.115.132:8001/?t={$token}' target='_blank'><b>Ir para</b></a>";
exit;
}
function login($url, $email, $password)
{
$json = ['email' => $email, "senha" => $password];
$url = "https://{$url}/access/login";
$response = request($url, $json);
$response = json_decode($response, true);
if ($response['status'] == 'success' || strpos($response['message'], 'sucesso') !== false) {
return $response['data']['token'];
}
return false;
}
function request($url, array $post = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post));
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
$response = curl_exec($ch);
if (curl_error($ch)) {
print_r(curl_error($ch, CURLINFO_HTTP_CODE));
}
curl_close($ch);
return $response;
}
?>
<!DOCTYPE html>
@ -61,24 +96,19 @@ if ($geturl['t']) {
<?php include "app/view/header.php" ?>
<body>
<?php if ($geturl['t'] == 'gerar') { ?>
<form method="post">
<p>Informe o id da empresa:</p>
<input type="number" name="id_empresa" placeholder="Informe o ID da empresa"><br>
<p>Email:</p>
<input type="text" name="email" placeholder="Informe o seu email de autenticacao"><br>
<p>Senha:</p>
<input type="password" name="password" placeholder="Informe a senha para autenticar"><br>
<hr>
<p>Informe o id do numero:</p>
<input type="number" name="id_number" placeholder="Informe o ID do numero"><br>
<p>Informe o Servidor:</p>
<input type="text" name="servidor" placeholder="Informe o IP/Host do servidor"><br>
<p>Informe a Matricula:</p>
<input type="text" name="matricula" placeholder="Informe matricula do agente"><br>
<p>Informe a fila:</p>
<input type="number" name="fila" placeholder="Informe o numero da fila"><br>
<p>Token expira dias:</p>
<input type="number" name="expire" value="1" placeholder="Informe o numero da fila"><br>
<p>Password To generate token:</p>
<input type="text" name="passwd" placeholder="Informe a senha para gerar o token"><br>
<input type="submit" name="btnSend" value="Gerar Token">
</form>
<?php } else { ?>

627
public/css/styles.css

@ -49,6 +49,7 @@ html {
--whatsapp-color: #24d366;
--telegram-color: #26a4e3;
--scrollbar-color: #cccccc;
--icon-color: #54656f;
--chat-window-scrollbar-color: #bab3ae;
--box-shadow-color: #d5d5d5;
--backround-chat-panel: #fdfdfd;
@ -69,41 +70,502 @@ html {
--color-moon: #f1c40f;
}
/* UTILITARIAS */
.relative {
position: relative;
}
.absolute {
position: absolute;
}
.fixed {
position: fixed;
}
.static {
position: static;
}
.sticky {
position: sticky;
}
.none {
display: none;
}
/* Personalizações */
.toast{
display: none;
position: fixed;
right: 20px;
bottom: 30px;
z-index: 999;
border-left: 15px solid rgb(250, 204, 21);
background-color: #fff;
min-width: 400px;
max-width: 400px;
border-radius: 5px;
padding: 20px;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
}
.toast-content{
display: flex;
align-items: center;
gap: 15px;
}
.toast-text{
font-size: 1.3rem;
}
.close-toast{
position: absolute;
font-size: 24px;
font-weight: bold;
top: 10px;
cursor: pointer;
right: 15px;
}
.btn {
font-size: 1.5rem;
height: 4.2rem;
padding: 0 2rem;
background: #2e5ee9;
color: #fff;
outline: 0;
border: 0;
border-radius: 5px;
cursor: pointer;
}
.modal-content-body-item {
color: var(--text-secondary);
}
.template-title {
display: flex;
gap: 10px;
align-items: center;
}
.template-messages {
padding: 20px 20px 20px 30px;
transition: opacity .2s ease;
color: var(--text-primary);
background-color: var(--bg-light-dark);
position: absolute;
bottom: 0;
left: 0;
width: 100%;
min-height: 300px;
}
.select {
margin-top: 1rem;
max-width: 400px;
position: relative;
}
#select-button {
display: flex;
align-items: center;
justify-content: space-between;
background-color: var(--bg);
font-size: 1.5rem;
padding: 15px;
border-radius: 10px;
flex: 1;
}
#option-view-button:checked+#select-button #chevrons .fa-chevron-down {
display: none;
}
#option-view-button:checked+#select-button #chevrons .fa-chevron-up {
display: block;
}
#chevrons .fa-chevron-up {
display: none;
}
#category-select {
position: relative;
display: flex;
align-items: center;
gap: 10px;
}
#btn-enviar-template{
margin-top: 2.5rem;
display: none;
}
#option-view-button {
all: unset;
position: absolute;
inset: 0;
cursor: pointer;
z-index: 3;
}
#options {
z-index: -1;
position: absolute;
background-color: var(--bg);
margin-top: 1rem;
border-radius: 10px;
max-height: 200px;
overflow-y: scroll;
width: 100%;
opacity: 0;
transition: opacity .2s ease;
}
#options::-webkit-scrollbar {
width: 0.6rem;
height: 5rem;
}
#options::-webkit-scrollbar-thumb {
background-color: var(--scrollbar-color);
}
.option {
font-size: 1.5rem;
display: flex;
align-items: center;
gap: .5rem;
padding: 15px;
position: relative;
width: 100%;
border-bottom: 1px solid var(--bg-light-dark);
}
.option:hover {
background-color: var(--bg-light-dark);
}
.option input[type="radio"] {
all: unset;
position: absolute;
inset: 0;
cursor: pointer;
}
.template-main p {
font-size: 1.5rem;
font-weight: 300;
}
.template-main .template-header p {
font-weight: bold;
}
.template-main .template-body p {
font-weight: 400;
}
.container-template-body::-webkit-scrollbar {
width: 0.6rem;
height: 5rem;
}
.container-template-body::-webkit-scrollbar-thumb {
background-color: var(--scrollbar-color);
}
.template {
margin-top: 1.5rem;
opacity: 0;
transition: opacity .2s ease;
}
.template > h1 {
font-size: 1.8rem;
margin-bottom: 10px;
}
.template-main {
display: flex;
flex-direction: column;
gap: 10px;
background: var(--sender-message);
max-width: 80%;
border-radius: 1rem;
border-bottom-right-radius: 0;
padding: 10px;
}
.template .template-body {
font-size: 1.5rem;
}
.template-buttons {
margin-top: 10px;
}
.template .template-buttons button {
margin-bottom: 10px;
padding: 10px 20px;
border: 0;
outline: 0;
border-radius: 5px;
background-color: var(--sender-message);
color: var(--text-primary);
width: 80%;
}
.sidebar-header-icons span {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border-radius: 100%;
}
.sidebar-header-icons span:hover {
background-color: var(--bg);
}
.icon {
font-size: 2rem;
color: var(--icon-color);
}
.icon.fa-pause-circle {
font-size: 2.5rem;
}
.plus {
color: var(--bg-light-dark);
left: 15px;
top: 14px;
font-size: 10px;
}
.box-event-buttons {
width: 100%;
padding: 1rem 1.5rem;
background-color: var(--bg);
/* padding: 1rem 1.5rem; */
/* border-radius: 1rem; */
display: flex;
justify-content: space-around;
}
.estatisticas {
border-top: 2px solid var(--bg);
/* background-color: var(--bg); */
padding: 1rem 1.5rem;
display: grid;
grid-template-columns: repeat(2, 1fr);
text-align: center;
/* gap: 0.5rem;
.offcanvas {
align-items: center;
background-color: var(--bg-light-dark);
color: #fcfcfc;
height: 100vh;
left: 0;
position: fixed;
top: 60px;
transform: translateX(-100%);
transition: all 235ms cubic-bezier(.95, .05, .795, .035);
width: 422px;
border-right: 1px solid #3b3636;
overflow: scroll;
}
.offcanvas.is-active {
transform: none;
transition: all 205ms cubic-bezier(.19, 1, .22, 1);
}
.offcanvas::-webkit-scrollbar {
width: 0.6rem;
height: 5rem;
}
.offcanvas::-webkit-scrollbar-thumb {
background-color: var(--bg);
}
.offcanvas h1 {
font-size: 1.8rem;
}
.offcanvas-header {
display: flex;
align-items: center;
gap: 20px;
background: var(--bg);
padding: 10px 20px;
}
.offcanvas .icon {
color: var(--text-primary);
font-size: 1.7rem;
}
.offcanvas-header span {
padding: 12px;
border-radius: 100%;
cursor: pointer;
}
.offcanvas-header span:hover {
background-color: var(--bg-light-dark);
}
.offcanvas-body {
display: flex;
flex-direction: column;
align-items: start; */
}
.estatisticas span {
font-size: 1.4rem;
font-weight: 700;
line-height: 14px;
.btn-box {
padding: 10px 20px;
display: flex;
align-items: center;
gap: 20px;
cursor: pointer;
}
.contatos {
margin-bottom: 20px;
display: flex;
flex-direction: column;
}
.contatos-title {
margin: 15px 20px;
font-size: 2rem;
}
.contato {
padding: 15px 20px;
display: flex;
align-items: center;
gap: 10px;
cursor: pointer;
border-bottom: 1px solid var(--bg);
}
.contato:hover {
background-color: var(--bg);
}
.contato-container {
display: flex;
flex-direction: column;
gap: 5px;
}
.contato img {
width: 45px;
height: 45px;
}
.btn-box:hover {
background-color: var(--bg);
}
.circle {
background: var(--bg);
width: 45px;
height: 45px;
border-radius: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.offcanvas .pesquisa {
margin: 15px;
padding: 15px;
display: flex;
align-items: center;
gap: 20px;
justify-content: space-between;
background: var(--bg);
border-radius: 10px;
}
.offcanvas-body .pesquisa input {
background-color: transparent;
border-radius: 0;
width: 100%;
padding: 0;
border: 0;
outline: 0;
color: var(--text-primary);
font-size: 1.5rem;
}
.offcanvas-body .pesquisa input::placeholder {
color: var(--text-primary);
}
.input-container {
margin: 15px;
display: flex;
gap: 10px;
flex-direction: column;
}
.input-container label {
font-size: 1.6rem;
}
.offcanvas-footer {
margin: 15px;
padding-bottom: 10px;
}
.offcanvas-footer button {
background-color: transparent;
border: 0;
outline: 0;
background: #3B82F6;
/* width: 100%; */
color: var(--text-primary);
padding: 10px 24px;
font-size: 1.5rem;
cursor: pointer;
border-radius: 0.25rem;
}
.offcanvas button .icon {
font-size: 2rem;
}
.input-container input,
textarea {
font-size: 1.5rem;
color: var(--text-primary);
padding: 1rem;
background: var(--bg);
line-height: 1.5;
border: 1px solid #6b7280;
outline: 0;
}
.input-container input::placeholder {
color: var(--text-primary);
}
.input-container textarea::placeholder {
color: var(--text-primary);
}
.input-container input:focus {
border-color: var(--telegram-color);
}
.radio-container span {
color: var(--text-primary);
font-size: 1.5rem;
}
.responsive-icon-header {
@ -136,26 +598,23 @@ html {
}
.search {
position: relative;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem 3rem;
justify-content: space-between;
margin: 1rem 1.5rem;
background-color: var(--bg);
border-radius: 10px;
padding: 15px;
gap: 20px;
}
.search input {
width: 100%;
font-size: 1.5rem;
background: transparent;
color: var(--text-primary);
outline: 0;
border-radius: 1.5rem;
background-color: var(--bg);
border: 0;
/* outline-color: var(--); */
padding: 1.5rem 2rem 1.5rem 3rem;
}
.search input::placeholder {
@ -163,10 +622,7 @@ html {
}
.search-icon {
position: absolute;
left: 3.9rem;
font-size: 1.7rem;
width: 1.8rem;
color: var(--text-primary);
}
@ -174,6 +630,7 @@ html {
display: none;
padding: 0.5rem;
}
.btn-exit-chat i {
font-size: 1.5rem;
color: var(--text-primary);
@ -210,7 +667,7 @@ html {
************/
.sidebar {
grid-column: 1 / 2;
/* grid-column: 1 / 2; */
/* background: var(--white); */
border-right: 1px solid rgb(43 48 59);
}
@ -242,7 +699,7 @@ html {
}
/* Profile image */
.sidebar-header > img {
.sidebar-header>img {
width: 4rem;
height: 4rem;
border-radius: 50%;
@ -252,8 +709,8 @@ html {
.sidebar-header-icons {
display: flex;
align-items: center;
flex: 1;
justify-content: flex-end;
gap: 10px;
justify-content: space-between;
cursor: pointer;
}
@ -278,7 +735,7 @@ html {
cursor: pointer;
}
.sidebar-notifications > img {
.sidebar-notifications>img {
margin-right: 2rem;
}
@ -318,7 +775,7 @@ html {
border-bottom: 1px solid var(--chat-border);
}
.search-bar > img {
.search-bar>img {
width: 2.8rem;
background: var(--white);
border-top-left-radius: 2rem;
@ -347,7 +804,9 @@ html {
display: flex;
flex-direction: column;
gap: 1rem;
padding: 0.5rem 3rem;
/* margin: 0.5rem 3rem; */
/* margin: 1rem 1.5rem; */
padding: 1rem 1.5rem;
/* background-color: red; */
}
@ -365,13 +824,11 @@ html {
.chat {
display: flex;
align-items: center;
/* background: var(--white); */
padding: 0.5rem 1.5rem;
border-radius: 1rem;
/* border-radius: 1rem; */
background-color: var(--bg);
border-radius: 10px;
/* padding: 1rem 0 0 2rem; */
cursor: pointer;
}
@ -398,7 +855,7 @@ html {
display: flex;
flex-direction: column;
margin-left: 1.5rem;
padding-right: 2rem;
/* padding-right: 2rem; */
padding-bottom: 1rem;
/* border-bottom: 1px solid var(--chat-border); */
}
@ -479,6 +936,7 @@ html {
.chat-right-bottom-right {
display: flex;
gap: 5px;
align-items: center;
}
@ -493,6 +951,7 @@ html {
text-align: center;
line-height: 2rem;
}
.qtde-fila {
display: inline-block;
width: 2rem;
@ -567,6 +1026,8 @@ html {
.chat-window-header-right-commands {
display: flex;
gap: 2px;
align-items: center;
margin-right: 5px;
}
@ -616,6 +1077,11 @@ html {
line-height: 14px;
}
/* Chat-windon icon */
.btn-icon{
font-size: 1.3rem;
}
/* Chat window */
.chat-window {
@ -654,6 +1120,9 @@ html {
position: relative;
max-width: 70%;
}
.message-error{
color: red;
}
.events {
background: var(--events-message);
@ -666,14 +1135,14 @@ html {
background: var(--sender-message);
color: var(--text-primary);
align-self: flex-end;
border-bottom-right-radius: 0px;
border-bottom-right-radius: 20;
}
.receiver {
background: var(--receive-message);
color: var(--text-primary);
border-bottom-left-radius: 0px;
border-bottom-left-radius: 20;
align-self: flex-start;
}
@ -944,6 +1413,7 @@ textarea {
display: flex;
gap: 1rem;
}
.type-message-bar-right .icons {
padding: 1rem;
border-radius: 0.5rem;
@ -951,15 +1421,28 @@ textarea {
width: 38px;
height: 38px;
}
.file {
background-color: var(--bg-light-dark);
}
.send {
/* background-color: #268d61; */
/* background-color: #387aff; */
background-color: #7269e3;
}
.badge{
background-color: var(--whatsapp-color);
font-weight: bold;
padding: 3px 5px;
border-radius: 5px;
}
.badge.SENDED {
background-color: var(--telegram-color);
}
#myImg {
width: 100%;
height: 300px;
@ -987,11 +1470,16 @@ textarea {
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.4);
}
.text-modal {
color: var(--text-primary);
font-size: 1.2rem;
}
#footername{
color: var(--text-primary);
}
.fade {
display: none;
position: fixed;
@ -1030,6 +1518,7 @@ textarea {
.modal-content-body-itens {
flex-direction: column;
flex: 1;
color: var(--text-primary);
}
/* Add Animation */
@ -1133,6 +1622,7 @@ textarea {
.fa-sun {
color: #f39c12;
}
.fa-moon {
color: var(--color-moon);
}
@ -1142,7 +1632,7 @@ textarea {
position: absolute;
}
.checkbox-switch:checked + .label-switch .switch-ball {
.checkbox-switch:checked+.label-switch .switch-ball {
transform: translateX(22px);
}
@ -1162,6 +1652,7 @@ textarea {
background-color: var(--sender-message);
position: absolute;
}
/*
.select-pause {
-webkit-appearance: none;
@ -1184,29 +1675,18 @@ textarea {
width: 100%;
}
/*
audio {
display: none;
} */
.select-pause select {
-webkit-appearance: none;
/* -webkit-appearance: none;
-moz-appearance: none;
appearance: none;
appearance: none; */
border-radius: 0.5rem;
width: 100%;
height: 4.8rem;
font-size: 1.8rem;
outline: 0;
padding: 1.3rem 1.5rem;
background-color: var(--bg);
color: var(--text-primary);
position: relative;
text-indent: 0.01px;
text-overflow: "";
@ -1426,6 +1906,7 @@ audio {
} */
@media (max-width: 1240px) {
#welcometomessage h1,
h2 {
font-size: 30px;
@ -1467,6 +1948,10 @@ audio {
grid-template-columns: 35em 1fr;
}
.offcanvas {
width: 352px;
}
#welcometomessage h1,
h2 {
font-size: 20px;
@ -1501,9 +1986,14 @@ audio {
grid-template-columns: 1fr;
}
.offcanvas {
width: 100%;
}
.sidebar {
border-right: none;
}
.btn-exit-chat {
display: block;
}
@ -1511,6 +2001,7 @@ audio {
.main {
display: none;
}
.main.chatAtivo {
display: block;
grid-column: 1 / -1;
@ -1519,6 +2010,10 @@ audio {
.sidebar.chatAtivo {
display: none;
}
.offcanvas.chatAtivo {
display: none;
}
}
@media (max-width: 600px) {
@ -1537,9 +2032,11 @@ audio {
.audio audio {
width: 200px;
}
.audio {
gap: 0;
}
.chat-window {
padding: 5rem 2rem 4rem 2rem;
}
@ -1561,7 +2058,8 @@ audio {
transition: 0.3s;
}
.chat-window-header-right > div {
.chat-window-header-right>div {
width: 100%;
border-radius: 0.5rem;
}
@ -1577,21 +2075,19 @@ audio {
@media (max-width: 400px) {
.contact-name {
font-size: 1.3rem;
}
.sidebar-header-icons img:nth-child(2) {
margin: 0 1.5rem;
}
.main {
overflow: hidden;
}
.modal-footer-content {
.modal-footer-content {
flex: 0;
}
@ -1616,6 +2112,7 @@ audio {
}
@media (max-width: 330px) {
.type-message-bar-center input,
textarea {
font-size: 1.1rem;
@ -1625,13 +2122,13 @@ audio {
@media (max-height: 1380px) {
.chats {
height: 65vh;
height: 75vh;
padding-bottom: 20px;
}
}
@media (max-height: 800px) {
.chats {
height: 60vh;
height: 72vh;
}
}
}

BIN
public/images/cuidado.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

12
public/js/config.js

@ -1,10 +1,18 @@
const ws = localStorage.getItem('obj_ws')
const server_api = `http://${localStorage.getItem('obj_server')}`
const server_api = `${localStorage.getItem('obj_server')}`
const version_api = '/api/v1/'
const supervisor_api = localStorage.getItem('supervisor_api') ? localStorage.getItem('supervisor_api') : localStorage.getItem('obj_server')
let mediaRecorder
let mediaAudio
let mediaPrint
let mediaImage
let mediaDoc
const icontypes = ['csv', 'doc', 'pdf', 'txt', 'xls', 'zip', 'ppt']
const chatTypes = { search: 1, notification: 2}
const path = 'public'
const html = document.querySelector("html");
let abrirMensagem = false;
const sendTemplate = "SENDED";
let inputInterface = document.querySelector('#input-checkbox-switch');
let chatsArray = [];
const RecuperacaoAtendimentoLimite = 22;
let isAtend = true;

384
public/js/main.js

@ -2,8 +2,13 @@
* EVENTOS GERADOS PELO USUARIO DA APLICACAO
*/
$(function () {
connect(ws);
connect(localStorage.getItem('obj_ws'));
notifications();
startSearch();
changeColors(darkMode, html);
localStorage.removeItem('session_status');
localStorage.setItem('session_status', 0);
/**
* VOICE RECORDER
*/
@ -11,33 +16,104 @@ $(function () {
$("#msgRecorder").text("Paramos de gravar sua voz!");
mediaRecorder.stop();
});
/**
* HABILITA FECHAR O MODAL
*/
$(".close").on("click", () => {
$("#modalselect").hide();
recStart();
});
$(".close-toast").on("click", () => {
$(".toast").hide();
});
$(document).on('click', function (event) {
const modal = document.getElementById("modalselect");
if (event.target == modal) {
modal.style.display = "none";
recStart();
}
})
$("#voicerecorder").on("click", () => {
recorderVoice();
});
$("#search-form").on("keyup", ({ target }) => {
search(target);
});
$("#chat-window-header-right-icon").on("click", () => {
responsivoButtonsHeader();
});
$("#btn-enviar-template").on("click", ({ target }) => {
enviaHsm(target);
});
$("#btnFila").on("click", () => {
filaNotifications();
isAtend = false;
});
$("#btnAtendimento").on("click", () => {
notifications();
isAtend = true;
click_btn(document.querySelector("#btnAtendimento"));
});
$("#exitChat").on("click", () => {
abrirMensagem = false;
abrirTela();
// removeMensagemBody();
});
$("#abrirContato").on("click", () => {
abrirTelaContato();
buildContacts();
});
$("#btn-add").on("click", () => {
abrirTelaContatoCadastro();
});
$("#btn-contatos").on("click", () => {
voltarTelaCadastro();
});
$("#btn-contato").on("click", (e) => {
e.preventDefault();
const form = $("#form-contato");
cadastroContato(form[0]);
});
$("#btn-inicial").on("click", () => {
voltarTelaInicial();
});
$("#option-view-button").on('click', (e) => {
const checkbox = e.target;
mostraTemplatesOptions(checkbox);
});
$("#recuperaratendimento").on("click", () => {
if (confirm("Deseja recuperar o atendimento?")) {
recuperarAtendimento();
}
});
$("input[name=contato]").on("keyup", (event) => {
let input = event.target
input.value = phoneMask(input.value)
});
/**
* HABILITA O ENVIO DE MIDIAS CTRL+V
*/
$(document).on('keydown', function (e) {
if (e.ctrlKey || e.metaKey) {
if (e.keyCode == 86) { // 86 é o código da tecla "V"
if (+localStorage.getItem('session_status') === 0) return;
$(document).one('paste', function (event) {
// Verifica se o que foi colado é uma imagem
if (event.originalEvent.clipboardData.items && event.originalEvent.clipboardData.items.length) {
// Percorre todos os itens colados
for (let i = 0; i < event.originalEvent.clipboardData.items.length; i++) {
// Verifica se o item atual é uma imagem
if (event.originalEvent.clipboardData.items[i].type.indexOf("image") !== -1) {
// Cria um objeto File a partir da imagem colada
let imageFile = event.originalEvent.clipboardData.items[i].getAsFile();
startSendImagePrintScreen(imageFile)
mediaPrint = imageFile;
}
}
}
});
}
}
})
/** FIM VOICE RECORDER */
/** EVENTOS DE CLICK NO BODY */
@ -48,16 +124,14 @@ $(function () {
$(".chat-window-header-right").removeClass("ativo");
});
/** INICIO DAS FUNCIONALIDADES */
startSendImage();
startSendFile();
startPause();
startTransfer();
startFinalizar();
startSalvaContato();
exitSystem();
startFooter();
/** INICIA COM O HEADER DO CONTATO VAZIO */
startChannelMessage();
@ -91,8 +165,6 @@ $(function () {
});
$("#imgclip").on("click", function () {
modalStart();
$("#uploadimage").val("");
$("#uploadfile").val("");
if ($("#uploadfiles").is(":hidden")) {
$("#uploadfiles").fadeIn(200);
} else {
@ -104,13 +176,20 @@ $(function () {
$("#modalselect").css({ display: "none" });
});
supervisorAgente();
//REMOVE TAGS
for (x = 0; x <= 15; x++) {
$(`#myscript${x}`).remove()
}
});
/**
* EVENTOS DE CLICK PARA SELECIONAR A SESSAO DE MENSAGEM/CONVERSA E RECUPERAR AS MENSAGENS JA TROCADAS NO ATENDIMENTO
* @param {*} id
*/
const selectNotification = (id) => {
const selectNotification = (id, status, datetime, chatType) => {
marcarMensagemVista(id);
toggleEnvioTemplates(0);
listaMensagem(id).then(async () => {
let uniqueid;
let number;
@ -119,28 +198,35 @@ const selectNotification = (id) => {
let protocolo;
const dataRequest = JSON.parse(localStorage.getItem("obj_contact"));
listarAtendimentoAgente(
localStorage.getItem("id_empresa"),
localStorage.getItem("my_uniqueid")
);
const allNotifications = JSON.parse(
localStorage.getItem("obj_notification")
);
const allNotifications = typeChat(chatType);
const atendimentos = await buscarAtendimento(id);
hideButtons(false);
allNotifications.data.forEach((e) => {
allNotifications.forEach((e) => {
$("#" + e.uniqueid.replace(".", `\\.`)).removeClass(
"select-notification"
);
if (e.uniqueid == id && e.status == 0) {
hideButtons(true);
monitoraStatusRecuperacaoAtendimento(datetime);
}
const statusIsSended = e.evento === sendTemplate;
if (e.uniqueid == id && statusIsSended) {
hideButtons(true);
}
});
$("#" + id.replace(".", `\\.`)).addClass("select-notification");
allNotifications.data.forEach((e) => {
allNotifications.forEach((e) => {
if (e.uniqueid == id && e.status == 0) {
hideButtons(true);
monitoraStatusRecuperacaoAtendimento(datetime);
}
});
if (dataRequest.data.length > 0) {
dataContact = dataRequest.data.filter((e) => {
if (id.trim() == e.uniqueid) {
@ -148,7 +234,8 @@ const selectNotification = (id) => {
}
});
}
allNotifications.data.forEach((e) => {
allNotifications.forEach((e) => {
if (id === e.uniqueid) {
uniqueid = e.uniqueid;
name = e.nome;
@ -156,13 +243,32 @@ const selectNotification = (id) => {
protocolo = e.protocolo;
}
});
localStorage.removeItem("session_window");
localStorage.removeItem("session_uniqueid");
localStorage.removeItem("session_status");
localStorage.setItem("session_uniqueid", uniqueid);
localStorage.setItem("session_status", status);
localStorage.setItem("session_window", number);
localStorage.setItem("session_name", name);
// CHECA SE O CONTATO JA EXISTE NA LISTA DE CONTATO, SE NÃO, EXIBE O BOTÃO DE SALVAR CONTATO
var contactsString = localStorage.getItem("obj_contacts");
var contacts = JSON.parse(contactsString);
var numberExists = contacts.data.some(function (contact) {
return contact.contato === number;
});
if (numberExists) {
$("#salvarcontato").hide();
} else {
$("#salvarcontato").show();
}
$(".chat-window-contact-name").text(name);
$(".chat-window-contact-status").text("Protocolo: " + protocolo);
$(".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();
@ -172,32 +278,24 @@ const selectNotification = (id) => {
if (typeof dataContact === "undefined") return;
dataContact.forEach((e) => {
const datesend = e.msg_date
? converdata(new Date(e.msg_date).getTime())
: "algumas horas";
const datesend = e.msg_date ? converdata(new Date(e.msg_date).getTime()) : "algumas horas";
let typesend = atendimentos.data[0].cliente_id == e.src ? "receiver" : "sender";
let statusMessage = e.status != 'error' ? datesend : '<span style="color:red">Mensagem não foi enviada!</span>';
let statusMessage = e.status != 'error' ? datesend : '<span class="message-error" style="color:red">Mensagem não foi enviada!</span>';
if (e.type == "text") {
$(".chat-window").append(`
<div class="${typesend}">
<span class="${typesend}-message">${e.content.replace(/\r?\n/g,"<br>")}</span>
<span class="${typesend}-message">${e.content.replace(/\r?\n/g, "<br>")}</span>
<br/>
<span class="message-time">${statusMessage}</span>
</div>`);
}
if (e.type == "transfer") {
$(".chat-window").append(`
<div class="events">
<span class="events-message">${e.content} por ${e.profile_name}, ${datesend}.</span>
</div>`);
$(".chat-window").append(`<div class="events"><span class="events-message">${e.content} por ${e.profile_name}, ${datesend}.</span></div>`);
}
if (e.type == "finish" || e.type == "re_start") {
$(".chat-window").append(`
<div class="events">
<span class="events-message">${e.content}</span>
</div>`);
if (e.type == "finish" || e.type == "re_start" || e.type == "recover" || e.type == "timeout") {
$(".chat-window").append(`<div class="events"><span class="events-message">${e.content}</span></div>`);
}
if (e.type != "text") {
const sendobj = {
@ -210,9 +308,7 @@ const selectNotification = (id) => {
messageTypeMedia(sendobj);
}
if (e.de == localStorage.getItem("my_uniqueid")) {
const datereceived = e.datetime
? converdata(e.datetime)
: "algumas horas";
const datereceived = e.datetime ? converdata(e.datetime) : "algumas horas";
if (e.type == "text") {
$(".chat-window").append(`
<div class="${typesend}">
@ -232,18 +328,16 @@ const selectNotification = (id) => {
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}/link/${
e.uniqueid
}/${window.btoa("application/" + l)}" target="_blank">
<img src="${path}/images/icons/${l}-file.png" style="max-width: 60px">
</a>
</span>
${e.filename}
<br/>
<span class="message-time">${datereceived}</span>
</div>`);
<div class="${typesend}">
<span class="${typesend}-message message-column">
<a href="${server_api}/link/${e.uniqueid}/${window.btoa("application/" + l)}" target="_blank">
<img src="${path}/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") {
@ -260,22 +354,59 @@ const selectNotification = (id) => {
scrollDown();
});
abrirMensagem = true;
startNotification();
};
/**
* EVENTOS DE CLICK PARA SELECIONAR A SESSAO DE MENSAGEM/CONVERSA E RECUPERAR AS MENSAGENS JA TROCADAS NO ATENDIMENTO
* @param {*} id
*/
const selectContact = async (id) => {
let name;
let number;
const { data } = await listarTemplates();
localStorage.setItem("obj_templates", JSON.stringify(data));
const allNotifications = JSON.parse(
localStorage.getItem("obj_contacts")
);
allNotifications.data.forEach((contact) => {
if (+id === contact.id) {
name = contact.nome;
number = contact.contato;
}
});
localStorage.setItem('client_id', number);
$(".chat-window .sender").remove();
$(".chat-window .receiver").remove();
$(".chat-window .events").remove();
$(".chat-window-contact-status").text("");
$(".chat-window-contact-name").text(name);
abrirMensagem = true;
hideButtons(true);
startNotification();
montaSelectTemplateMessages(data);
};
/**
* 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"));
if(!sendNumber || !myUniqueid || !agent){
alert('Não foi possível carregar todas as informações do sessão do atendimento! Por favor, Tente novamente.');
if (!sendNumber || !myUniqueid || !agent) {
alert('Não foi possível carregar todas as informações da sessão do atendimento! Por favor, Tente novamente.');
return;
}
@ -308,7 +439,7 @@ const sendMessage = (obj = {}) => {
mimetype: mimetype,
media: media,
content: sendContent,
status: "sended",
status: "read",
},
},
};
@ -319,10 +450,7 @@ const sendMessage = (obj = {}) => {
let msgContent = type == "text" ? sendContent : obj.fileContent;
$(".chat-window").append(`
<div class="sender">
<span class="sender-message">${msgContent.replace(
/\r?\n/g,
"<br>"
)}</span>
<span class="sender-message">${msgContent.replace(/\r?\n/g, "<br>")}</span>
<br/>
<span class="message-time">${converdata(Date.now())}</span>
</div>`);
@ -353,10 +481,16 @@ const viewMessage = (ev) => {
break;
case "finish":
case "re_start":
$(".chat-window").append(`
<div class="events">
<span class="events-message">${ev.event.mensagem.content}</span>
</div>`);
$(".chat-window").append(`<div class="events"><span class="events-message">${ev.event.mensagem.content}</span></div>`);
break;
case "timeout":
$(".chat-window").append(`<div class="events"><span class="events-message">${ev.event.mensagem.content}</span></div>`);
break;
case "alert":
break;
case "recover":
$(".chat-window").append(`<div class="events"><span class="events-message">${ev.event.mensagem.content}</span></div>`);
hideButtons(false);
break;
}
const mediaDownload = [
@ -389,9 +523,7 @@ const receiveNotification = (data) => {
let validate = null;
switch (data.event?.type) {
case "mensagem":
if (
data.event.mensagem.uniqueid != localStorage.getItem("session_uniqueid")
) {
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`,
@ -400,25 +532,17 @@ const receiveNotification = (data) => {
soundNotification(`${path}/sound/notification.mp3`);
}
/** VALIDA O NUMERO, VERIFICA SE O TEM ALGMA MSG INICIAL, SE JA TEVE UM NUMERO NA VERIFICACAO */
listarAtendimentoAgente(
localStorage.getItem("id_empresa"),
localStorage.getItem("my_uniqueid")
);
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")
) {
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
) {
if (data.event?.mensagem.uniqueid && data.event?.contact.number && vald.length == 0) {
notifications({
uniqueid: data.event?.mensagem.uniqueid,
cliente_id: data.event?.contact.number,
@ -441,6 +565,7 @@ const receiveNotification = (data) => {
break;
case "finish":
case "re_start":
case "recover":
obj = {
uniqueid: data.event?.mensagem.uniqueid,
action: data.event.mensagem.type,
@ -470,44 +595,83 @@ const keepMensage = (ev) => {
* FUNCAO 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;
if (mediaAudio) {
sendAudio(media);
} else if (mediaDoc) {
sendFile();
} else if (mediaImage || mediaPrint) {
sendImage();
} else {
alert('opção invalida');
}
$("#uploadimage").val("");
$('#fieldsendmessage').focus();
};
const sendAudio = (media) => {
if (media.state == "recording") {
media.stop();
}
const el = mediaAudio.src;
const fileContent = mediaAudio.outerHTML;
sendMessage({
content: el.replace("data:", "").replace(/^.+,/, ""),
type: "audio",
mimetype: "audio/mpeg",
fileContent,
});
mediaAudio = null;
}
const sendFile = () => {
let el = mediaDoc;
let rec = new Blob([el], { type: el.type });
let filesent = $("#myImg");
filesent[0].id = Date.now();
imgContent = filesent.css({ "max-width": "120px" })[0].outerHTML;
fileContent = `<a href="${URL.createObjectURL(
rec
)}" target="_blank">${imgContent}</a>`;
filename = el.name;
const file = new FileReader();
file.onload = function () {
const typefile =
rec.type.split("/")[0].indexOf("image") >= 0
? rec.type.split("/")[0]
: "document";
sendMessage({
content: el.replace("data:", "").replace(/^.+,/, ""),
type: "audio",
mimetype: "audio/mpeg",
content: file.result.replace("data:", "").replace(/^.+,/, ""),
type: typefile,
mimetype: rec.type,
fileContent,
filename,
});
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": "200px" })[0].outerHTML;
$("#myImg").empty();
}
};
file.readAsDataURL(rec);
mediaDoc = null;
}
const sendImage = () => {
const el = mediaImage ?? mediaPrint;
const rec = new Blob([el], { type: el.type });
let filesent = $("#myImg");
filesent[0].id = Date.now();
fileContent = filesent.css({ "max-width": "200px" })[0].outerHTML;
filename = el.name;
$("#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,
@ -516,5 +680,7 @@ const sendMedia = (media = null) => {
filename,
});
};
file.readAsDataURL(rec);
};
mediaImage = null;
}

249
public/js/requests.js

@ -1,6 +1,63 @@
$.ajaxSetup({
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem('token'),
"ngrok-skip-browser-warning":"any"
}
});
const entrar = (id_fila, id_number) => new Promise((resolve) => {
$.ajax({
type: "POST",
url: `${server_api}${version_api}agente/conectar`,
data: JSON.stringify({
id_fila,
"id_number_channel": id_number
}),
success: function (res) {
resolve(res)
},
error: function (res) {
resolve(res)
}
});
})
const logoff = (matricula) => new Promise((resolve) => {
$.ajax({
type: "POST",
url: `${server_api}/access/logoff`,
data: JSON.stringify({
matricula
}),
success: function (res) {
resolve(res)
},
error: function (res) {
alert('Não foi possivel deslogar do sistema.')
}
});
})
const sair = (matricula) => new Promise((resolve) => {
$.ajax({
url: `${server_api}${version_api}agente/desconectar`,
type: "POST",
data: JSON.stringify({
matricula
}),
success: function (res) {
resolve(res)
},
error: function (res) {
alert('Não foi possivel desconectar do sistema.')
}
});
})
const enviarMensagem = (dataSend) => {
$.ajax({
url: `${server_api}/messages/sendMessage`,
url: `${server_api}${version_api}messages/sendMessage`,
type: "POST",
data: JSON.stringify(dataSend),
success: function (res) {
@ -13,7 +70,7 @@ const enviarMensagem = (dataSend) => {
}
const listaMensagem = (uniqueid) => new Promise((resolve) => {
$.ajax({
url: `${server_api}/messages/${uniqueid}`,
url: `${server_api}${version_api}messages/${uniqueid}`,
type: "GET",
success: function (res) {
localStorage.removeItem('obj_contact')
@ -25,9 +82,9 @@ const listaMensagem = (uniqueid) => new Promise((resolve) => {
}
})
})
const listarAgentesDisponivel = (id_empresa) => new Promise((resolve) => {
const listarAgentesDisponivel = () => new Promise((resolve) => {
$.ajax({
url: `${server_api}/supervisor/agentes/status/${id_empresa}/livre`,
url: `${server_api}${version_api}supervisor/agentes/status/livre`,
type: "GET",
success: function (res) {
resolve(res)
@ -37,9 +94,9 @@ const listarAgentesDisponivel = (id_empresa) => new Promise((resolve) => {
}
});
})
const listarAtendimentoAgente = (id_empresa, matricula) => new Promise((resolve) => {
const listarAtendimentoAgente = (matricula) => new Promise((resolve) => {
$.ajax({
url: `${server_api}/atendimentos/${id_empresa}/${matricula}`,
url: `${server_api}${version_api}atendimentos/${matricula}`,
type: "GET",
success: function (res) {
localStorage.removeItem('obj_notification')
@ -51,9 +108,21 @@ const listarAtendimentoAgente = (id_empresa, matricula) => new Promise((resolve)
});
})
const listarTodosAtendimentoAgente = (matricula) => new Promise((resolve) => {
$.ajax({
url: `${server_api}${version_api}atendimentos/listar/${matricula}`,
type: "GET",
success: function (res) {
resolve(res)
},
error: function (res) {
}
});
})
const listarPausasAgente = (id_empresa) => new Promise((resolve) => {
$.ajax({
url: `${server_api}/pausas/${id_empresa}`,
url: `${server_api}${version_api}pausas`,
type: "GET",
success: function (res) {
resolve(res)
@ -64,11 +133,9 @@ const listarPausasAgente = (id_empresa) => new Promise((resolve) => {
});
})
const listarAtendimentosFila = (id_queue, status) => new Promise((resolve) => {
$.ajax({
url: `${server_api}/atendimentos/buscar/status`,
url: `${server_api}${version_api}atendimentos/buscar/status`,
type: "POST",
data: JSON.stringify({
id_queue,
@ -85,7 +152,7 @@ const listarAtendimentosFila = (id_queue, status) => new Promise((resolve) => {
const entrarPausa = (id_pausa, matricula) => new Promise((resolve) => {
$.ajax({
url: `${server_api}/supervisor/entrarPausa`,
url: `${server_api}${version_api}agente/entrarPausa`,
type: "POST",
data: JSON.stringify({
id_pausa,
@ -106,7 +173,7 @@ const entrarPausa = (id_pausa, matricula) => new Promise((resolve) => {
})
const sairPausa = (matricula) => new Promise((resolve) => {
$.ajax({
url: `${server_api}/supervisor/sairPausa`,
url: `${server_api}${version_api}agente/sairPausa`,
type: "POST",
data: JSON.stringify({
matricula
@ -120,46 +187,10 @@ const sairPausa = (matricula) => new Promise((resolve) => {
}
});
})
const entrar = (matricula, id_fila, id_number) => new Promise((resolve) => {
$.ajax({
url: `${server_api}/auth/conectar-chat`,
type: "POST",
data: JSON.stringify({
matricula,
id_fila,
"id_number_channel": id_number
}),
success: function (res) {
resolve(res)
},
error: function (res) {
resolve(res)
}
});
})
const sair = (matricula) => {
$.ajax({
url: `${server_api}/auth/desconectar-chat`,
type: "POST",
data: JSON.stringify({
matricula
}),
success: function (res) {
if (res.status == 'success') {
alert('Desconectado do sistema!')
window.close()
} else {
alert(res.message)
}
},
error: function (res) {
alert('Nao foi possivel desconectar do sistema.')
}
});
}
const finalizarAtendimento = (matricula, uniqueid) => new Promise((resolve) => {
$.ajax({
url: `${server_api}/atendimentos/finalizar`,
url: `${server_api}${version_api}atendimentos/finalizar`,
type: "POST",
data: JSON.stringify({
matricula,
@ -186,26 +217,65 @@ const finalizarAtendimento = (matricula, uniqueid) => new Promise((resolve) => {
}
});
})
const statusAgente = (id_empresa, matricula) => new Promise((resolve) => {
const recuperarAtendimento = () => new Promise((resolve) => {
$.ajax({
url: `${server_api}${version_api}atendimentos/recover`,
type: "PUT",
data: JSON.stringify({
uniqueid: localStorage.getItem("session_uniqueid"),
matricula: localStorage.getItem("my_uniqueid")
}),
success: function (res) {
if(res.status == 'error'){
alert(res.message);
}
resolve(res)
},
error: function (res) {
alertModal(
`<h2>OPS... HOUVE UM PROBLEMA &nbsp</h2><img id="imgReconnect" width="25px" src="${path}/images/alert.png">
<p>Não foi possível Recuperar o atendimento!</p>
<p>Error: ${res}</p>`,
'OPS!!!'
)
}
});
})
const statusAgente = (matricula) => new Promise((resolve) => {
$.ajax({
url: `${server_api}/supervisor/agentes/${id_empresa}/${matricula}`,
url: `${server_api}${version_api}supervisor/agentes/${matricula}`,
type: "GET",
success: function (res) {
localStorage.removeItem('obj_status')
localStorage.setItem('obj_status', JSON.stringify(res))
$("#modalselect").hide();
resolve(res)
},
error: function (res) {
alertModal(
`<h2>RECONECTANDO, AGUARDE &nbsp</h2><img id="imgReconnect" width="25px" src="${path}/images/loading.gif">`,
`<h3 class="text-modal">RECONECTANDO, AGUARDE &nbsp</h3><img id="imgReconnect" width="25px" src="${path}/images/loading.gif">`,
'[ POR FAVOR AGUARDE ]'
)
},
statusCode: {
403: function(){
logoff(matricula).then((res) => {
localStorage.removeItem("token")
localStorage.removeItem("id_number")
localStorage.removeItem("obj_ws")
localStorage.removeItem("obj_queue"),
localStorage.removeItem("my_uniqueid")
localStorage.removeItem("obj_server")
alert('Desconectado do sistema!')
window.close()
})
}
}
});
})
const transferirAtendimento = (origem, destino, uniqueid) => new Promise((resolve) => {
$.ajax({
url: `${server_api}/atendimentos/transferir`,
url: `${server_api}${version_api}atendimentos/transferir`,
type: "POST",
data: JSON.stringify({
matricula_origem: origem,
@ -232,7 +302,7 @@ const transferirAtendimento = (origem, destino, uniqueid) => new Promise((resolv
})
const marcarMensagemVista = (uniqueid) => {
$.ajax({
url: `${server_api}/messages/markMessageRead`,
url: `${server_api}${version_api}messages/markMessageRead`,
type: "POST",
data: JSON.stringify({
uniqueid
@ -247,11 +317,8 @@ const marcarMensagemVista = (uniqueid) => {
}
const buscarAtendimento = async (uniqueid) => {
return $.ajax({
url: `${server_api}/atendimentos/buscar`,
type: "POST",
data: JSON.stringify({
uniqueid
}),
url: `${server_api}${version_api}atendimentos/buscar/${uniqueid}`,
type: "GET",
success: function (res) {
return res
},
@ -262,11 +329,8 @@ const buscarAtendimento = async (uniqueid) => {
}
const buscarUsuario = (matricula) => new Promise((resolve) =>{
$.ajax({
url: `${server_api}/usuario/buscar`,
type: "POST",
data: JSON.stringify({
matricula
}),
url: `${server_api}${version_api}usuario/` + matricula,
type: "GET",
success: function (res) {
resolve(res)
},
@ -274,4 +338,59 @@ const buscarUsuario = (matricula) => new Promise((resolve) =>{
alert('Nao foi possivel carregar as informacoes do usuario.')
}
});
})
const listarContatos = () => new Promise((resolve) =>{
$.ajax({
url: `${server_api}${version_api}contatos`,
type: "GET",
success: function (res) {
localStorage.removeItem('obj_contacts')
localStorage.setItem('obj_contacts', JSON.stringify(res))
resolve(res)
},
error: function (res) {
alert('Nao foi possivel carregar as informacoes dos contatos.')
}
});
})
const listarTemplates = () => new Promise((resolve) =>{
$.ajax({
url: `${server_api}${version_api}templates`,
type: "GET",
success: function (res) {
resolve(res)
},
error: function (res) {
alert('Nao foi possivel carregar as informacoes dos templates.')
}
});
})
const enviarHsmMessage = (dataSend) => new Promise((resolve) =>{
$.ajax({
url: `${server_api}${version_api}messages/sendHsmMessage`,
type: "POST",
data: JSON.stringify(dataSend),
success: function (res) {
resolve(res)
},
error: function (res) {
console.log(res);
const btn = $("#btn-enviar-template")[0];
loadingBtn(btn, "Enviar Mensagem", false)
alert(res.responseText)
}
});
})
const cadastrarContato = (dataSend) => new Promise((resolve) =>{
$.ajax({
url: `${server_api}${version_api}contatos`,
type: "POST",
data: JSON.stringify(dataSend),
success: function (res) {
resolve(res)
},
error: function (res) {
alert(res.responseText);
}
});
})

696
public/js/util.js

File diff suppressed because it is too large Load Diff

4
storage/logs/display_erros.log

@ -1,4 +0,0 @@
[25-May-2022 21:05:43 Europe/Berlin] PHP Fatal error: Uncaught Error: Class 'app\Providers\Crypt' not found in C:\Users\lucas.awade\Desktop\Arquivos\Projetos\WhatsApp\simples_client\index.php:9
Stack trace:
#0 {main}
thrown in C:\Users\lucas.awade\Desktop\Arquivos\Projetos\WhatsApp\simples_client\index.php on line 9

2
ws.php

@ -10,7 +10,7 @@
</body>
<script language="javascript" type="text/javascript">
var wsUri = "ws://192.168.115.244:8080/wss";
var wsUri = "ws://0.0.0.0:8080/wss";
var log;
function init() {

Loading…
Cancel
Save