Интересное

Создаем бесплатный callback-виджет с SMS и Telegram-оповещением

В этой статье мы пошагово создадим виджет обратного звонка с красивой минималистичной анимацией и отправкой уведомлений на почту, на свой номер телефона и в мессенджер Telegram через бота. Виджет подойдет абсолютно для любого сайта на HTML или на любой CMS.

Демонстрацию можно посмотреть по ссылке.

Зачем нужен callback-виджет?

Есть масса сервисов, которые предоставляют различные настраиваемые виджеты обратного звонка — с возможностью подключить АТС, интегрировать с CRM (amoCRM, Битрикс24), с оповещением в Telegram, по СМС и так далее. За такой богатый функционал нужно платить ежемесячно, покупать минуты или выбирать тариф по карману. Стоимость подобных виджетов стартует примерно от 200 рублей в месяц.

Используя виджет, о котором мы поговорим в этой статье, вы получите навечно бесплатное, независимое и настраиваемое под любые нужды решение — с возможностью отправки заявки на почту, в Telegram и по СМС. Также с помощью вебхуков можно подключить отправку данных в CRM (если есть такая возможность на стороне самой CRM).

Минус такого виджета – отсутствие возможности онлайн-звонка. Но, думаю, это не большой минус, а скорее плюс, так как часто менеджеры не успевают ответить на звонок, и компания получает негатив от потенциального клиента. А в случае с виджетом мы принимаем заявку, выводим сообщение о том, что перезвоним в течение определенного времени, и у клиента не возникает негатива. Поэтому минус виджета может быть и плюсом.

Итак, приступим к созданию виджета.

Разметка HTML + CSS

 <div class="widget-callback">  <div class="callback-button">                                 <span class="callback-button-title">Вам перезвонить?</span>                                 <span class="callback-button-phone"></span>                  </div>                  <div class="callback-form">                                 <form id="calbback-widget-form">                                                 <span class="callback-form-title">Оставьте свой телефон и мы свяжемся с вами</span>                                                 <input type="tel" name="wgphone" placeholder="+7 (999) 999 99 99" required >                                                 <input type="hidden" name="wgdata" value="Обратный звонок">                                                 <input type="hidden" name="wgpage" value="<?php echo "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; ?>">                                                 <input type="submit">                                 </form>                  </div>  </div>

Так как виджет «сквозной» и устанавливается на все страницы, нам необходимо понимать, с какой страницы был заказан обратный звонок, чтобы оперативно помочь клиенту. Для этого нам понадобится скрытое поле в форме, которое будет передавать эту страницу, значение поле должно быть таким:

 <?php echo "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; ?>

Если у вас одностраничный сайт или несколько страниц на HTML, измените расширение файла с .html на .php. Если устанавливаете на CMS , то все в порядке.

Второе скрытое поле будет передавать тему заявки — в данном случае это «Обратный звонок».

Теперь добавим небольшой скрипт открытия формы по клику на кнопку. Для этого нам понадобится подключить библиотеку jQuery и написать небольшой скрипт отправки. Если у вас уже подключена библиотека, то этого делать не стоит.

 <script>  $(document).ready(function () {                  //Открытие виджета по клику   jQuery('body').on('click', '.callback-button-phone', function (e) {                                 e.preventDefault();                                 jQuery('.widget-callback').toggleClass('widget-callback-form-open');                  });  });  </script>

Далее оформим все с помощью CSS. Вы можете добавить этот код в свой файл стилей или создать новый.

 body {                  margin: 0;                  padding: 0;  }  .widget-callback {                  font-family: sans-serif;                  font-size: 14px;  }  .widget-callback>div {                  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);  }  .widget-callback input {                  outline: none !important  }  .widget-callback .callback-button {                  position: absolute;  right: 60px;  bottom: 30px;  }  .widget-callback .callback-button-title {                  position: absolute;                  left: -150px;                  top: 16px;                  background: rgba(41, 41, 41, 0.75);                  color: #fff;  padding: 6px 10px;                  border-radius: 3px;  }  .widget-callback.widget-callback-form-open .callback-button-title {                  display: none;  }  .widget-callback .callback-button-title:before {                  content: '';                  position: absolute;                  width: 0;                  height: 0;                  border: solid transparent;                  border-width: 6px;                  top: 50%;                  right: -12px;                  transform: translateY(-50%);                  border-left-color: rgba(41, 41, 41, 0.75);  }  .widget-callback .callback-button-phone {                  width: 60px;                  height: 60px;                  display: block;                  background: #199c68;                  border-radius: 50%;                  position: relative;                  cursor: pointer;                  animation: 1200ms ease 0s normal none 1 running shake;                  animation-iteration-count: infinite;                  -webkit-animation: 1200ms ease 0s normal none 1 running shake;                  -webkit-animation-iteration-count: infinite;  }  .widget-callback.widget-callback-form-open .callback-button-phone {                  animation: unset;                  -webkit-animation: unset;                  background: #ddd;  }  .widget-callback .callback-button-phone:before {                  content: '';                  background: url(call.svg);                  background-size: contain;                  position: absolute;                  display: block;                  width: 24px;                  height: 24px;                  left: 50%;                  top: 50%;                  margin: -12px 0 0 -12px;                  transform: scale(1);                  -webkit-transition: all 0.2s linear;                 transition: all 0.2s linear;  }  .widget-callback .callback-button-phone:after {                  content: '';                  background: url(cancel.svg);                  background-size: contain;                  position: absolute;                  display: block;                  width: 24px;                  height: 24px;                  left: 50%;                  top: 50%;                  margin: -12px 0 0 -12px;                  transform: scale(0);                  -webkit-transition: all 0.2s linear;                 transition: all 0.2s linear;  }  .widget-callback.widget-callback-form-open .callback-button-phone:before {                  content: '';                  transform: scale(0);  }  .widget-callback.widget-callback-form-open .callback-button-phone:after {                  content: '';                  transform: scale(1);  }  .widget-callback .callback-form {                  display: none;                  background: #fff;                  border: 1px solid #f9f9f9;                  width: 240px;                  border-radius: 5px;                  padding: 30px 15px;                  right: 60px;                  bottom: 110px;                  position: absolute;                  box-shadow: 0px 5px 20px rgba(0, 0, 0, 0.08);  }  .widget-callback.widget-callback-form-open .callback-form {                  display: block;                  animation: formcbwg-in 0.1s ease;  }  @keyframes formcbwg-in {                  0% { transform: translateY(15%); }                  100% { transform: translateY(0%); }  }  @keyframes formcbwg-out {                  0% { transform: translateY(0%); }                  100% { transform: translateY(15%); }  }  .widget-callback .callback-form-title {                  text-align: center;                  display: block;                  margin: 0 0 30px;  }  .widget-callback input {                  width: 100%;                  box-sizing: border-box;                  padding: 15px;                  margin: 0 0 10px;                  border: 1px solid #ebebeb;                  border-radius: 3px;                  font-size: 16px;  }  .widget-callback input[type="submit"] {                  background: #199c68;                  color: #fff;                  text-transform: uppercase;                  font-size: 14px;                  border: none;                  cursor: pointer;  }  .widget-callback .success-send {                  text-align: center;  }  .widget-callback .success-send img {                  width: 60px;                 margin: 0 0 20px;  }  @media (max-width: 600px) {  .widget-callback .callback-button {  right: 30px;                  bottom: 30px;  }  .widget-callback .callback-form {  width: 80%;  right: 10%;  box-sizing: border-box;  }  }                                                                 @keyframes shake {                                 0% {                                     transform: rotateZ(0deg);                                         -ms-transform: rotateZ(0deg);                                         -webkit-transform: rotateZ(0deg);                                 }                                 10% {                                     transform: rotateZ(-30deg);                                         -ms-transform: rotateZ(-30deg);                                         -webkit-transform: rotateZ(-30deg);                                 }                                 20% {                                     transform: rotateZ(15deg);                                         -ms-transform: rotateZ(15deg);                                         -webkit-transform: rotateZ(15deg);                                 }                                 30% {                                     transform: rotateZ(-10deg);                                         -ms-transform: rotateZ(-10deg);                                         -webkit-transform: rotateZ(-10deg);                                 }                                 40% {                                     transform: rotateZ(7.5deg);                                         -ms-transform: rotateZ(7.5deg);                                         -webkit-transform: rotateZ(7.5deg);                                 }                                 50% {                                     transform: rotateZ(-6deg);                                         -ms-transform: rotateZ(-6deg);                                         -webkit-transform: rotateZ(-6deg);                                 }                                 60% {                                     transform: rotateZ(5deg);                                         -ms-transform: rotateZ(5deg);                                         -webkit-transform: rotateZ(5deg);                                 }                                 70% {                                     transform: rotateZ(-4.28571deg);                                         -ms-transform: rotateZ(-4.28571deg);                                         -webkit-transform: rotateZ(-4.28571deg);                                 }                                 80% {                                     transform: rotateZ(3.75deg);                                         -ms-transform: rotateZ(3.75deg);                                         -webkit-transform: rotateZ(3.75deg);                                 }                                 90% {                                     transform: rotateZ(-3.33333deg);                                         -ms-transform: rotateZ(-3.33333deg);                                         -webkit-transform: rotateZ(-3.33333deg);                                 }                                 100% {                                     transform: rotateZ(0deg);                                         -ms-transform: rotateZ(0deg);                                         -webkit-transform: rotateZ(0deg);                                 }                                 }                                  @-webkit-keyframes shake {                                 0% {                                     transform: rotateZ(0deg);                                         -ms-transform: rotateZ(0deg);                                         -webkit-transform: rotateZ(0deg);                                 }                                 10% {                                     transform: rotateZ(-30deg);                                         -ms-transform: rotateZ(-30deg);                                         -webkit-transform: rotateZ(-30deg);                                 }                                 20% {                                     transform: rotateZ(15deg);                                         -ms-transform: rotateZ(15deg);                                         -webkit-transform: rotateZ(15deg);                                 }                                 30% {                                     transform: rotateZ(-10deg);                                         -ms-transform: rotateZ(-10deg);                                         -webkit-transform: rotateZ(-10deg);                                 }                                 40% {                                     transform: rotateZ(7.5deg);                                         -ms-transform: rotateZ(7.5deg);                                         -webkit-transform: rotateZ(7.5deg);                                 }                                 50% {                                     transform: rotateZ(-6deg);                                         -ms-transform: rotateZ(-6deg);                                         -webkit-transform: rotateZ(-6deg);                                 }                                 60% {                                     transform: rotateZ(5deg);                                         -ms-transform: rotateZ(5deg);                                         -webkit-transform: rotateZ(5deg);                                 }                                 70% {                                     transform: rotateZ(-4.28571deg);                                         -ms-transform: rotateZ(-4.28571deg);                                         -webkit-transform: rotateZ(-4.28571deg);                                 }                                 80% {                                     transform: rotateZ(3.75deg);                                         -ms-transform: rotateZ(3.75deg);                                         -webkit-transform: rotateZ(3.75deg);                                 }                                 90% {                                     transform: rotateZ(-3.33333deg);                                         -ms-transform: rotateZ(-3.33333deg);                                         -webkit-transform: rotateZ(-3.33333deg);                                 }                                 100% {                                     transform: rotateZ(0deg);                                         -ms-transform: rotateZ(0deg);                                         -webkit-transform: rotateZ(0deg);                                 }                                 }

Информирование по email

Разметка готова, теперь нужно настроить отправку уведомлений на почту, для этого подключим файл mail.php со следующим содержимым:

 <?php  if ($_SERVER["REQUEST_METHOD"] == "POST") {      if (isset($_POST['wgphone'])) {$wgphone = $_POST['wgphone'];}      if (isset($_POST['wgdata'])) {$wgdata = $_POST['wgdata'];}      if (isset($_POST['wgpage'])) {$wgpage = $_POST['wgpage'];}       $to = "up-lite@ya.ru"; /*Укажите адрес, на который должно приходить письмо*/      $headers = 'MIME-Version: 1.0' . "rn";      $headers .= "Content-type: text/html; charset=utf-8 rn";       // дополнительные данные      $headers .= "From: Студия Аплайт <info@up-lite.ru>;rn"; // от кого      $subject = "$wgdata";      $message = "          <div style='background: #f8f8f8;padding: 20px; font-family:sans-serif;'>              <div style='width: 400px;margin: 0 auto;'>                  <div style='    background: #1b3c56;border-radius: 10px 10px 0 0;padding: 30px 0;text-align: center;color: #fff;font-weight: 700;font-size: 20px;'>Заявка на обратный звонок                  </div>                  <div style='padding: 30px;border-radius: 0 0 10px 10px;background: #fff;'>                      <b>Телефон:</b> <a href='tel:".$wgphone."'>".$wgphone." </a><br>                      <b>Страница:</b> ".$wgdata."                  </div>              </div>          </div>                                 ";      $send = mail ($to, $subject, $message, $headers);       if ($send == 'true')          {          echo '          <div class="success-send">              <img src="tick.svg"> <br> Мы получили Вашу заявку и скоро с Вами свяжемся!          </div>';          }          else          {          echo 'Нам не удалось отправить заявку, попробуйте еще раз';          }      } else {          http_response_code(403);          echo "Попробуйте еще раз";      }  ?>

Вам остается только заменить email на свой, и форма будет работать. Как видите, в теле письма мы сформировали HTML-разметку, поэтому письма будут приходить в красиво оформленном формате:

Это удобно для администратора — сразу настроенная ссылка на телефон дает возможность не копировать номер, а сразу при клике перейти в телефонную книгу.

AJAX-отправка данных формы

Теперь добавить AJAX-отправку данных формы. Это позволит отправлять номер телефона без перезагрузки, что очень удобно для посетителя.

Скрипт отправки формы:

 <script>  $(document).ready(function () {                  //ajax-отправка данных  jQuery("#calbback-widget-form").submit(function () {                          var formID = jQuery(this).attr('id');                          var formNm = jQuery('#' + formID);                          jQuery.ajax({                          type: "POST",                           url: 'mail.php',                           data: formNm.serialize(),                           success: function (data) {                                   jQuery(formNm).html(data);                            },                            error: function (jqXHR, text, error) {                                  jQuery(formNm).html(error);                                      }                          });                          return false;                      });  });  </script> 

Скрипты можно объединить в один и подключить файлом – как удобно на вашем проекте.

Отправка СМС

Для отправки сообщений на свой номер или на номер клиента будем использовать сервис sms.ru. Регистрируемся и обращаем внимание на следующее:

1. API-ключ — на каждой странице он расположен в самом низу, копируем его.

2. Файл подключения к API sms.ru — переходим по ссылке (найти ее можно в разделе «Интеграции» -> «PHP» в первой табличке).

Файл sms.ru.php небходимо поместить в корневую папку с mail.php, а затем настроить подключение и отправку в самом файле mail.php. Выглядит это следующим образом:

 //ОТПРАВКА СМС  require_once 'sms.ru.php';  $smsru = new SMSRU('Ваш api_id'); // Ваш уникальный программный ключ, который можно получить на главной странице  $data = new stdClass();  $data->to = 'Ваш номер или номер админа ;  $data->text = ''.$wgdata.' '.$wgphone.''; // Текст сообщения  $sms = $smsru->send_one($data); // Отправка сообщения и возврат данных в переменную

Преимущество этого сервиса в том, что можно отправлять до 5 СМС в день на свой номер бесплатно.

Проверяем отправку данных формы и видим, что теперь приходит и оповещение на номер телефона. Данные, которые приходят в сообщении, можно менять, но чем больше текста, тем дороже СМС.

Отправка данных в чат Telegram

Для отправки данных в мессенджер нам понадобится следующее:

  1. Создать бота.
  2. Создать чат, в который бот будет отправлять данные.
  3. Активировать бота.
  4. Проверить правильность настройки.

Создаем телеграм-бота.

В строке поиска ищем BotFather и даем ему команду /start, затем выбираем команду /newbot, следуем подсказкам и выбираем имя бота и как его будем вызывать. Выбранное имя может быть занято, вам сообщит об этом подсказка, поэтому придумайте уникальное имя — чтоб наверняка 🙂

После отправки имени BotFather отправит нам сообщение о том, что все готово, и пришлет специальный ключ — токен (см. скриншот), он понадобится для получения ID чата, в который будем отправлять данные заявки.

Отлично, бот готов. Создаем чат и добавляем в него бота.

  1. Слева в меню Телеграма выбираем «Создать группу».
  2. Пишем название группы, например «Заявки с сайта [название сайта]».
  3. Добавляем бота в созданную группу через поиск.

Затем нужно активировать бота командой /join @uplite_bot. Пишем ее в созданной группе, далее кликаем по имени бота @uplite_bot, и нас перебрасывает на диалог с нашим ботом, где его нужно активировать командой /start.

Теперь необходимо получить ID чата, делается это следующим запросом:

 https://api.telegram.org/botXXXXXXXXXXXXXXXXXXXXXXX/getUpdates

Где XXXXXXXXXXXXXXXXXXXXXXX — токен вашего бота, полученный ранее.

Вставляем свой токен и переходим по ссылке, затем снова заходим в чат с нашим ботом и повторно активируем его командой /start, обновляем ссылку и ищем ID чата, он будет выглядеть следующим образом:

Ищем в тексте ID с черточкой — это и есть наш ID чата.

Итак, у нас теперь есть все данные для отправки заявки в чат Телеграма, осталось только настроить в mail.php.

 //ОТПРАВКА В ТЕЛЕГРАМ  $token = "ваш_токен";  $chat_id = "id_чата";  $arr = array(    'Телефон: ' => $wgphone,    'Страница' => $wgpage,    'Тема' => $wgdata  );   foreach($arr as $key => $value) {    $txt .= "<b>".$key."</b> ".$value."%0A";  };   $sendToTelegram = fopen("https://api.telegram.org/bot{$token}/sendMessage?chat_id={$chat_id}&parse_mode=html&text={$txt}","r");

Проверяем – все должно работать 🙂 Теперь у нас есть виджет с различными вариантами отправки заявок, который удовлетворит пожелания большинства заказчиков.

Межтекстовые Отзывы
Посмотреть все комментарии
guest

Искусственный интеллект: краткая история, развитие, перспективы

Разработка #Обзор #Технологии #Нейросети #Наука #Гаджеты Сейчас технологии развиваются с немыслимой скоростью. Ранее те возможности, что, казалось бы,...

Взгляд в будущее: смогут ли метавселенные заменить реальность

Разработка #Технологии #Тренды #Facebook #Криптовалюта Краткое введение в метавселенные. Что они собой представляют, как работают и стоит ли...

Что такое Data Science

Разработка #Облачные решения #Обзор #Технологии #Аналитика #Карьера Поговорим о том, что такое Data Science, почему она так важна...

Сравнение 29 сервисов аналитики маркетплейсов: обзор, рейтинг

Обзор сервисов аналитики маркетплейсов Сравнение 29 сервисов аналитики маркетплейсов по 10 параметрам. Обзор, рейтинг лучших сервисов для аналитики...

Обзор Vue.js

Разработка #Фреймворки #Обзор #JavaScript Vue.js или просто Vue – это прогрессивный JavaScript-фреймворк, который используется для создания пользовательских интерфейсов....

5 главных способов привлечения клиентов из карт и отзывиков

Бизнес #Продажи #Предпринимательство #SEO Реклама. ООО «ТаймВэб». erid: LjN8KQs4Z Мы в MyReviews делаем инструменты для мониторинга и улучшения рейтинга...

Верстка сайта: инструкция для новичков

«Верстка сайта — это сложно? А если я совсем новичок, у меня получится?» В этой статье мы рассказываем,...

PHP: работа с БД MySQL

Разработка #Серверы #MySQL #PHP #Базы данных Базы данных используются для удобного хранения информации, а также для её структурирования....

Работа с массивами в JavaScript

Разработка #JavaScript В одной из прошлых статей я разбирал работу строк в JavaScript. Но что если нам нужно хранить несколько...

Как создать краудфандинговый сайт на базе WordPress

Выбираем плагин Переходим к главному – выбору краудфандингового плагина. Здесь есть варианты. Charitable Это бесплатный плагин для сбора...

Как сделать приложение из веб-сайта

Разработка #Плагины #Веб-дизайн #Сервисы #WordPress #Конструктор Разработчики популярных веб-ресурсов стараются сделать все возможное, чтобы клиентам было комфортно потреблять...

Верстка сайта: инструкция для начинающих

Разработка #Веб-дизайн #HTML/CSS Разработка сайта – это долгая и плодотворная работа, которая, как правило, разделена на несколько этапов....

Преимущества и недостатки WordPress

Разработка #Обзор #WordPress WordPress довольно старая система управления содержимым сайтов (сокращенно — CMS), вебмастера и администраторы с ней...

Как создать одностраничный сайт на Bootstrap (Mobirise)

Разработка #Программы #Веб-дизайн #Шаблоны #HTML/CSS #Конструктор Создание сайтов под ключ – отдельная профессия. Специалисты должны разбираться в верстке...

Что такое виджет и как им пользоваться

Разработка #Веб-дизайн #JavaScript #Оптимизация #Windows Разработчики софта и владельцы сайтов стараются упростить процесс взаимодействия со своим продуктом. Одним из...

Как создать туристический сайт

Разработка #Веб-дизайн #Контент #Конструктор Туристический сайт – это важный интернет-источник для людей, планирующих путешествия. Его основная цель – познакомить...

Как открыть закрытые вкладки в Google Chrome

Все мы хотя бы раз случайно закрывали вкладку в браузере и тут же испытывали сожаление. Но есть несколько...

Как обучиться программированию на любом языке

Разработка #C/C#/C++ #Карьера #Веб-дизайн #Разбор #HTML/CSS Поговорим о том, что нужно делать разработчику, чтобы освоить любой язык программирования...

Amazon UK: как создать и продвигать свой интернет-магазин?

В последние годы популярность интернет-шоппинга выросла в разы. Возможно, вы хотите стать частью этого мира и начать продавать...

Как пользоваться Visual Studio Code

Разработка #IDE #Редакторы кода #Программы #Обзор #Windows Visual Studio Code – это один из наиболее популярных редакторов кода,...