/** * * Получаем DOM для widget, в запросе должен участвовать token для определения состояния виджета * Подключаем css * Проверям были ли сообщения от этого пользователя то подгружаем, иначе регестрируем при первом сообщение * * Функции мессенджера * 1)Отправка сообщения * 2)Отправка файла * 3)Принятие сообщения * 4)Отображение уведомления * * */ // управление интерфейсом var wrgsv_dom = { main_id: 'widget_wahelp', main_token: 'script_widget_wahelp', main_name: 'wahelp_main_widget', url_style: '/i/css/widget_style_wahelp.css', right_messanger: '45px', right_channel: '9px', //45px если есть мессенджера element: { id: { }, class: { } }, smylle: undefined, notice_count:[], disable:{ message_send:false }, // полученеие токена из элемента get_token: function () { let scripts = document.getElementById(this.main_token), token = scripts.getAttribute('data'); return token; }, // задаем dom в элемент add_dom: async function (dom) { this.url_style = document.querySelector('#script_widget_wahelp').getAttribute('src').split('/widget_new')[0] + this.url_style; this.addStyle(); document.getElementById(this.main_id).innerHTML = dom; //если мессенджер // console.log(wrgsv.config); if (wrgsv.config['messanger'] === "1" && wrgsv.config['messanger'] !== undefined) { await this.init_messanger(); } else { await this.init_links(); } this.init_script(); }, // показываем первое сообщение first_message_show: function () { if(!document.getElementById('first_message_widtget_message')) return; if (getComputedStyle(document.getElementsByClassName('wahelp_messanger whatsapp')[0]).right === '-1000px') document.getElementById('first_message_widtget_message').style.right = '15px'; }, main_button_show: function (right = '25px') { document.getElementsByClassName(this.main_name)[0].style.right = right; }, init_links: async function () { setTimeout(() => { this.main_button_show(); }, 500); }, init_messanger: async function () { // показываем кнопку wahelp через пол секунды setTimeout(() => { this.main_button_show(); }, 500); // показываем первое сообщение если оно есть по верх кнопки setTimeout(() => { this.first_message_show(); }, 2500); }, // метод подключения стилей виджета addStyle: function () { style = document.createElement('link'); style.rel = 'stylesheet'; style.type = 'text/css'; style.href = this.url_style; document.head.appendChild(style); }, // отображаем ошибку show_error_message: async function (text = '') { // document.getElementById('wahelp_widget_error').innerHTML = text; // setTimeout(() => { // document.getElementById('wahelp_widget_error').innerHTML = ''; // }, 2000); }, init_script: async function () { this.init_event(); }, init_event: async function () { console.log('init event'); // показываем основное содержимое виджета document.getElementById('widget_logo_wahelp').addEventListener('click', () => this.show_widget_wahelp()); // скрываем основной виджет document.getElementById('close_widget_logo_wahelp').addEventListener('click', () => this.hide_widget_wahelp()); if (wrgsv.config['messanger'] === "1" && wrgsv.config['messanger'] !== undefined) { if(document.getElementById('first_message_widtget_message')){ // скрываем первое сообщение document.getElementById('widget_close_first_message').addEventListener('click', () => this.hide_first_message()); // отправка сообщения из формы с первым сообщением document.getElementById('widget_first_message_whatsap_input').addEventListener('keypress', this.input_message_first_message_enter); // вызов плашки с смайликами у перовго виджета с первым сообщением document.getElementById('first_message_widget_click_smile').addEventListener('click', () => { this.show_smyle(); this.show_widget_wahelp(); }); // отправка сообещния из плашки с первым сообщением document.getElementById('first_message_widget_click_send_message').addEventListener('click', () => { let e = { which: 13 }; this.input_message_first_message_enter(e); }); } // отправляем файл document.getElementById('widget_self_file_upload').addEventListener('change', function () { wrgsv_dom.widget_self_file_upload(this.files) }); // скрываем смайлы при фокусе на input document.getElementById('widget_wahelp_input').addEventListener('keypress', this.input_message_enter); // отправлем сообщение document.getElementById('widget_send_send_message').addEventListener('keypress', () => this.input_message_enter()); // отправка сообщения по кнопке мышкой document.getElementById('widget_send_send_message').addEventListener('click', () => this.input_message()); // скрываем смайлики document.getElementById('widget_wahelp_input').addEventListener('focus', () => this.hide_smyle()); document.getElementById('widget_wahelp_input').addEventListener('click', () => this.input_message()); // показываем смайлы document.getElementById('widget_click_smile').addEventListener('click', () => this.show_smyle()); // показываем окно и отправляем файл на загрузку document.getElementById('widget_upload_file').addEventListener('click', this.widget_self_file); // после выбора файл отправляем его document.getElementById('widget_upload_file').addEventListener('change', this.widget_self_file_upload); // отправка формы контака console.log('wahelp_form_contact__submit'); document.getElementById('wahelp_form_contact__submit').addEventListener('click', this.send_form_user_contact); } }, // показываем форму для контакта show_form_contact: async function(){ document.getElementById('wahelp_form_contact').style.right = '0px'; }, // скрываем форму контакта hide_form_contact: async function(){ document.getElementById('wahelp_form_contact').style.right = '-1000px'; }, // отправка формы контака send_form_user_contact: async function(){ let phone = document.getElementById('wahelp_form_contact__phone').value; let name = document.getElementById('wahelp_form_contact__name').value; wrgsv.user_edit(phone, name); }, widget_self_file: async function () { document.getElementById('widget_self_file_upload').click(); }, // отправляем выбранный файл widget_self_file_upload: async function (files) { document.getElementById('widget_upload_file').value = null; for (let i = 0; i < files.length; i++) { console.log(files[i]); wrgsv.send_file(files[i]); } }, // загружаем смайлы init_smile: async function () { let smiles = JSON.parse(await wrgsv_service.get_smyle()); for (categories in smiles) { for (smile in smiles[categories]) { let name = smiles[categories][smile].name; let img = document.createElement('img'); img.src = 'https://whatsapp.universe-soft.ru/adm/img/emoji/whatsapp/' + name + '.png'; img.width = "22"; img.style.maring = '2px'; img.setAttribute('code', smiles[categories][smile].data.code[0].replace('U+', '&#x')); document.getElementById('widget_dashboard_smiles').appendChild(img); img.addEventListener('click', function () { // document.getElementById('widget_wahelp_input').appendChild(this.cloneNode(true).getAttribute('code')); document.getElementById('widget_wahelp_input').innerHTML += this.cloneNode(true).getAttribute('code'); }); } } this.smile = true; }, // показываем плашку с смайликами show_smyle: async function () { if (this.smile === undefined) await this.init_smile(); let border = document.getElementsByClassName('triangle_message_smile')[0]; border.classList.remove("display-none"); setTimeout(() => { border.style.height = '300px'; }, 10); }, // скрываем плашку с смайликами hide_smyle: async function () { let border = document.getElementsByClassName('triangle_message_smile')[0]; border.style.height = '0px'; setTimeout(() => { border.classList.add("display-none"); }, 500); }, // отправка сообщения из first_message input_message_first_message_enter: async function (e) { if (e.which == 13) { document.getElementById('widget_wahelp_input').innerHTML = document.getElementById('widget_first_message_whatsap_input').innerHTML; document.getElementById('widget_first_message_whatsap_input').innerHTML = ''; document.getElementsByClassName('wahelp_messanger')[0].style.right = wrgsv.right_messanger; wrgsv_dom.hide_first_message(); wrgsv_dom.show_widget_wahelp(); // border_smile_hide(); setTimeout(() => { wrgsv_dom.input_message_enter(e); }, 100); } }, // отправка сообщения на пробел input_message_enter: async function (e) { if (e.which == 13) { wrgsv_dom.input_message(); } }, // отправка сообщения input_message: async function () { this.hide_smyle(); let element_main_input = document.getElementById('widget_wahelp_input'); text = element_main_input.textContent.trim(); element_main_input.innerHTML = ''; if (text === '' || text.length == 0) { return; } wrgsv.send_message(text); }, toggle_can_send_message: async function(status = -1){ if(status == -1){ this.disable.message_send = !this.disable.message_send; }else{ this.disable.message_send = status; } // console.log(this.disable.message_send); }, show_widget_wahelp: async function () { var elems = document.getElementsByClassName('widget_wahelp_channels'); for (var i = 0; i < elems.length; i++) { elems[i].style.right = this.right_channel; } if (document.getElementsByClassName('wahelp_messanger')[0]) { document.getElementsByClassName('wahelp_messanger')[0].style.right = this.right_messanger; if(document.getElementById('first_message_widtget_message')){ document.getElementById('first_message_widtget_message').style.right = '-1000px'; } } document.getElementById('power_by').style.opacity = '1'; setTimeout(() => { document.getElementById('widget_logo_wahelp').style.opacity = '0'; }, 10); document.getElementById('power_by').style.opacity = '1'; this.set_count_notice_message_widget('remove'); // if(!wrgsv.user.phone){ // setTimeout(()=>{ // this.show_form_contact(); // }, 2000); // } }, hide_widget_wahelp: async function () { var elems = document.getElementsByClassName('widget_wahelp_channels'); for (var i = 0; i < elems.length; i++) { elems[i].style.right = '-300px'; } document.getElementById('widget_logo_wahelp').style.opacity = '1'; document.getElementById('power_by').style.opacity = '0'; if (document.getElementsByClassName('wahelp_messanger')[0]) document.getElementsByClassName('wahelp_messanger')[0].style.right = '-1000px'; }, // скрываем уведомление hide_first_message: async function () { document.getElementById('first_message_widtget_message').style.right = '-1000px'; }, hasClass: function (element, className) { return (' ' + element.className + ' ').indexOf(' ' + className + ' ') > -1; }, // загружаем файл из api create_file_messanger: function (url) { let array_files = { 'image': ['jpg', 'jpeg', 'png', 'gif', 'bmp'], 'video': ['3g2', '3gp', '3gp2', '3gpp', '3gpp2', 'avi', 'gtp', 'h264', 'm4v', 'mkv', 'mod', 'moov', 'mov', 'mp4', 'mpeg', 'mpg', 'webm', 'wmv'], 'audio': ['mp3', 'ogg', 'ptt', 'wav', 'ogg', 'aac', 'ac3'], 'document': ['txt','doc','docs','xls','xlxs'] } let file = url.split('.').slice(-1)[0]; let name = url.split('/').slice(-1)[0]; let create_file = ''; let result_file = ''; Object.entries(array_files).forEach(entry => { const [key, value] = entry; for (let i = 0; i < value.length; i++) { if (file === value[i]) { create_file = key; break; } } }); if (!create_file) create_file = 'document'; if (create_file === 'image') { result_file = document.createElement('img'); result_file.src = url; result_file.width = "200"; } if (create_file === 'document') { result_file = document.createElement('a'); result_file.text = 'Скачать файл'; result_file.download = name; result_file.target = "_blank"; result_file.href = url; } if (create_file === 'audio') { result_file = document.createElement('audio'); result_file.src = url; } if (create_file === 'video') { result_file = document.createElement('video'); result_file.src = url; } return result_file; }, add_messages: async function (messages) { console.log(messages); // добавляем полученный ответ в HTML элемент let json_data = messages; // если сообщений новых 0 if (json_data.length == 0) return; let messanger = document.getElementsByClassName('wahelp_messanger whatsapp')[0]; // если последние сообщение однаковое с полученым // if( wrgsv.last_id_message === parseInt(json_data[0]['id'])) return; //записываем что его игнорировать следующий раз wrgsv.last_id_message = parseInt(json_data[0]['id']); // так же проверяет однаковые ли сообщения // if( wrgsv.last_message == json_data[0]['message']) return; for (let i = json_data.length - 1; i >= 0; i--) { //уведомления if (getComputedStyle(messanger).right === '-1000px' && json_data[i]['destination'] == 'from_operator') { this.notice_count.push(json_data[i]); this.set_count_notice_message_widget(); } let json_message = ''; if(json_data[i]['json']){ json_message = JSON.parse(json_data[i]['json']); } let file = ''; // console.log(json_data[i]['json']); if (json_data[i]['json'] && json_message['body']) { console.log(json_message['body']); file = this.create_file_messanger(json_message['body']); json_data[i]['message'] = json_message['caption']; } if (json_data[i]['file_url']) { console.log(json_data[i]['file_url']); file = this.create_file_messanger(json_data[i]['file_url']); // json_data[i]['message'] = json_message['caption']; } if (json_data[i]['destination'] == 'from_operator' || json_data[i]['destination'] == 'to') { this.set_message_messanger('wahelp', json_data[i]['message'], messanger, this.get_date_time_widget(json_data[i]['date']), file); } else { this.set_message_messanger('user', json_data[i]['message'], messanger, this.get_date_time_widget(json_data[i]['date']), file); } } }, set_message_messanger: function (user, text_message, messanger, date, file = '') { if (wrgsv.id_time_scroll) clearTimeout(wrgsv.id_time_scroll); let st_message = ''; if (user === 'user') { st_message = 'triangle_message_user'; } else { st_message = 'triangle_message_wahelp'; } let message = messanger.getElementsByClassName('message_user ' + st_message + ' display-none')[0].cloneNode(true), form = messanger.getElementsByClassName('message')[0]; message.getElementsByClassName('message_text')[0].innerHTML = text_message.trim(); if (file) { console.log('add image'); message.getElementsByClassName('message_text')[0].appendChild(file); } message.getElementsByClassName('date')[0].innerHTML += date; // message.style.bottom = '-1000px'; message.classList.remove("display-none"); message.classList.add("hidden_message"); form.appendChild(message); // setTimeout(() => { // message.style.bottom = '0px'; // }, 100); // wrgsv.id_time_scroll = setTimeout(() => { form.scrollTop = form.clientHeight * 10; // }, 1000); }, get_date_time_widget: function (dateString = '') { let today; if (typeof (dateString) === typeof ('ab')) { dateString = Date.parse(dateString) / 1000; } if (dateString) { today = new Date(dateString * 1000); } else { today = new Date(); } // var date_format = today.getDate()+'-'+(today.getMonth()+1)+'-'+today.getFullYear() + ' ' + today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds(); var options = { year: 'numeric', month: 'numeric', day: 'numeric', timezone: 'UTC', hour: 'numeric', minute: 'numeric', second: 'numeric' }; var date_format = today.toLocaleString("ru", options); return date_format; }, set_count_notice_message_widget: async function(event = 'set'){ let el_notice_count = document.getElementById('count_notice_message_widget'); if(event === 'set'){ el_notice_count.classList.remove('display-none'); el_notice_count.innerText = this.notice_count.length; } if(event === 'remove'){ el_notice_count.classList.add('display-none'); el_notice_count.innerText = ''; this.notice_count = []; } }, }; // упраление запросами var wrgsv_service = { url_wiget: '/webhooks/widget/', url_ws:'wss', request: undefined, reqesut_open: undefined, ws: null, socket_port: 9009, _get_url: undefined, token: undefined, get_url: function () { if (this._get_url === undefined) { if (this.token === undefined) { return this.url_wiget + '\default'; } this._get_url = this.url_wiget + '\/' + this.token; } return this._get_url; }, init: async function () { this.url_wiget = document.querySelector('#script_widget_wahelp').getAttribute('src').split('/widget_new')[0] + this.url_wiget; this.url_ws = this.url_ws + document.querySelector('#script_widget_wahelp').getAttribute('src').split('/widget_new')[0].split('https')[1]; let _req = ("onload" in new XMLHttpRequest()) ? XMLHttpRequest : XDomainRequest; this.request = new _req(); }, _send: async function (data = [], stringify = true) { if (stringify === true) { data = JSON.stringify(data); } // console.log('_send', data, stringify); this.request.send(data); return this.request.response; }, _get: async function (url, data = [], stringify = true) { this.request.open('GET', url, false); return await this._send(data, stringify); }, _post: async function (url, data = [], stringify = true) { this.request.open('POST', url, false); return await this._send(data, stringify); }, get_dom: async function ($dom) { let data = { 'event': $dom }; return await this._post(this.get_url(), data); }, get_user: async function () { let data = { 'event': 'get_user' }; return await this._post(this.get_url(), data); }, check_user: async function () { data['event'] = 'check_user'; return await this._post(this.get_url(), data); }, send_message: async function (data) { data['event'] = 'send_message'; return await this._post(this.get_url(), data); }, /** * Отправляем файл * @param {FormData} data - данные для файла * @returns promisse резульатат */ send_file: async function (data) { return await this._post(this.get_url(), data, false); }, get_messages: async function (data) { data['event'] = 'get_messages'; return await this._post(this.get_url(), data); }, is_valid_token: async function (data) { data['event'] = 'check_token'; return JSON.parse(await this._post(this.get_url(), data)); }, get_smyle: async function () { // return JSON.parse(await this._get(this.url_smyle)); let data = { 'event': 'get_emojies', }; return JSON.parse(await this._post(this.get_url(), data)); }, user_edit: async function(data){ data['event'] = 'edit_user'; return await this._post(this.get_url(), data); }, connect_to_socket: async function (chat_id) { this.ws = new WebSocket(`${this.url_ws}:${this.socket_port}?bot_id=${chat_id}`); this.ws.onopen = () => { this.ws.send(JSON.stringify({ "action": "chat_init", "chat_id": chat_id })) }; this.ws.onmessage = (e) => { let data = JSON.parse(e.data); wrgsv.on_message(data); }; this.ws.onclose = (e) => { console.log('Socket is closed. Reconnect will be attempted in 5 second.' + e.reason, e.reason); setTimeout(() => { this.connect_to_socket(socket_port); }, 5000) }; this.ws.onerror = (err) => { console.error('Socket encountered error: ', err.message, 'Closing socket') this.ws.close() }; } } // основная логика var wrgsv = { user: { id: -1, sender: '', chat_id: -1, uid: -1, }, ws: '', bot_id: undefined, smiles: false, config: undefined, localStorage_id: 'id_widget_wahelp', message_last_id: '', is_valid_phone: async function(phone){ let regex = /^(\+7|7|8)?[\s\-]?\(?[489][0-9]{2}\)?[\s\-]?[0-9]{3}[\s\-]?[0-9]{2}[\s\-]?[0-9]{2}$/; return regex.test(phone); }, // запрос на валидацию is_valid_token: async function (token) { if (token === "widget_wahelp") { return false; } let data = { 'token': token }; let response = await wrgsv_service.is_valid_token(data); if (response.result === 'success' && response !== undefined) { this.config = response.config.widget; this.bot_id = response.bot_id; return true; } return false; }, // проверка валидации чека check_valid_token: async function (token) { // валидируем токен // если аргумент валидный, то запоминаем и будет вставлять его в конец запроса let is_valid_token = await this.is_valid_token(token); if (!is_valid_token) { // иначе token берем из DOM // старая версия token = wrgsv_dom.get_token(); is_valid_token = await this.is_valid_token(token); if (!is_valid_token) { console.error('error token'); return false; } } await this.set_token(token); return true; }, // заадем токен set_token: async function (token) { wrgsv_service.token = token; }, // запуск скрипта run: async function (token) { await wrgsv_service.init(); if (!await this.check_valid_token(token)) { return; } if (this.config['messanger'] === "1" && this.get_user() === false) { await wrgsv_service.check_user(); } if (this.config['messanger'] === "1" && this.config['messanger'] !== undefined) { wrgsv_service.connect_to_socket(this.bot_id); } let _dom = this.config['messanger'] === "1" ? 'messanger' : 'links'; let dom = await wrgsv_service.get_dom(_dom); wrgsv_dom.add_dom(dom); this.get_messages(); }, // метод инициализации виджета init: function (token) { this.run(token); }, // получаем данные для пользователя и сохраняем // если начался диалог init_user: async function () { console.log('init_user', this.user); if (this.user.id !== -1) return; let json_str = await wrgsv_service.get_user(); let data = JSON.parse(json_str); this.user.id = data.result.id; this.user.sender = data.result.sender; this.user.chat_id = data.result.chat_id; this.user.name = data.result.name; this.user.phone = data.result.phone; this.user.uid = data.result.uid; this.remember_user(data.result); }, // запоминаем пользователя remember_user: async function (data) { localStorage.setItem(`user_${this.localStorage_id}`, this.user.id); localStorage.setItem(`user_sender_${this.localStorage_id}`, this.user.sender); localStorage.setItem(`user_chat_${this.localStorage_id}`, this.user.chat_id); localStorage.setItem(`user_name_${this.localStorage_id}`, this.user.name); localStorage.setItem(`user_phone_${this.localStorage_id}`, this.user.phone); localStorage.setItem(`user_uid_${this.localStorage_id}`, this.user.uid); }, // получаем токе пользователя, если он уже общался через виджет get_user: async function () { if (localStorage.getItem(`user_${this.localStorage_id}`) && localStorage.getItem(`user_sender_${this.localStorage_id}`) && localStorage.getItem(`user_chat_${this.localStorage_id}`)) { this.user.id = localStorage.getItem(`user_${this.localStorage_id}`); this.user.sender = localStorage.getItem(`user_sender_${this.localStorage_id}`); this.user.chat_id = localStorage.getItem(`user_chat_${this.localStorage_id}`); this.user.name = localStorage.getItem(`user_name_${this.localStorage_id}`); this.user.phone = localStorage.getItem(`user_phone_${this.localStorage_id}`); this.user.uid = localStorage.getItem(`user_uid_${this.localStorage_id}`); return true; } return false; }, get_messages: async function () { if (this.user.id === -1) return; let data = { 'lastid': this.message_last_id, 'user_id': this.user.id, 'uid': this.user.uid }; let messages = JSON.parse(await wrgsv_service.get_messages(data)); if (messages.data.length > 0) { this.message_last_id = messages.data[0].id; } wrgsv_dom.add_messages(messages.data); }, // событие получение сообщения из ws on_message: function (data) { console.log(data); if (data['action'] == 'new_message') { this.get_messages(); } }, // отправляем сообщение // если это первое сообщение то создаем пользователя send_message: async function (text) { await this.init_user(); console.log() if (text === '') { wrgsv_dom.show_error_message('Поле для сообщения пустое'); return; } let data = this.user; data['user_id'] = this.user.id; data['text'] = text; wrgsv_service.send_message(data); }, // отправка файла // TODO выдает 413 ошибку send_file: async function (file) { await this.init_user(); let formData = new FormData(); formData.append("files_", file); formData.append('event', 'send_file'); formData.append('user_id', this.user.id); formData.append('uid', this.user.uid); formData.append('sender', this.user.sender); wrgsv_service.send_file(formData); }, // меняем пользователя user_edit: async function(phone, name){ if(!await this.is_valid_phone(phone)){ wrgsv_dom.show_error_message('Введен неверный формат телефона'); return; } this.user.phone = phone; this.user.name = name; this.remember_user(); let data = this.user; data['user_id'] = this.user.id; wrgsv_service.user_edit(data); wrgsv_dom.hide_form_contact(); } };