Telegram — отправка данных в чат с сайта с помощью jQuery и Ajax + защита через Cookies

MY  

Простой JavaScript для отправки данных с сайта в Telegram с помощью Ajax. Писался под конкретную задачу — прикрутить на готовый лендинг модальное окно для подачи заявки, которая отправляется в Телеграм.

Подпишись на Telegram

Это вторая версия скрипта. Поправил один маленький косяк с подбросом страницы вверх при клике на href=”#”

Написан на jQuery и состоит из одного файла и простой формы. Описание не включает в себя модальное окно.

Рабочий пример: https://code.itikhonov.art/index.php?page=jq-ajax-telegram-send

Канал для приема данных: https://t.me/iartsorders

Скрипт имеет тройную защиту от идиотов. Вечно отправлять данные не получится. Сделано все для максимизации неудобства это делать. А также будет заблокировано с помощью простейших решений:

  • блокировка вставки номера телефона в поле input;
  • блокировка повторной отправки формы без перезагрузки страницы;
  • две попытки отправить форму и блокировка через Cookies.

Подключение Ajax и Cookies

Для работы скрипта требуется подключить библиотеку jQuery, а также плагин js-cookies. Реализовано с помощью CDN.

HTML форма

<p class="ressult"></p>

<form id="datas">
  <p>
      <label for="phone">Номер телефона *</label><br>
      <input id="phone" autocomplete="off" placeholder="+70001234567" maxlength="12" name="phone" class="phone" pattern="^\+7\d{3}\d{7}$">
    </p>
    <p>
      <label for="descr">Описание (не обязательно)</label><br>
      <textarea id="descr" placeholder="Введите текст" name="descr" class="descr"></textarea>
    </p>

    <a href="#" id="datas-btn" class="block-button">ОТПРАВИТЬ</a>

</form>
  • autocomplete — запрещаем автозаполнение формы
  • placeholder — подсказка в каком виде нужно вписать номер телефона
  • pattern — регулярное выражение, которым мы запрещаем все, кроме цифр
  • maxlength — максимально 12 цифр

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

Подключение JavaScript

<!-- jQuery Libs CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>

<!-- jQuery Cookies CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-cookie/latest/js.cookie.min.js"></script>

JavaScript и Ajax отправка

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

$('#datas-btn').click(function(e){

   // отменяем подброс страницы вверх при клике на href="#"
   e.preventDefault();

   // получаем данные из формы
   var f_phone = $('input.phone').val(),
       f_descr = $('textarea.descr').val(),
       text = 'Новая заявка:\n ' + f_descr +',\n ' + f_phone;

   //вызываем функцию отправки в Telegram
   send_tg(text);
		
});
// Предварительно заполняем данные вашего чата и бота в переменных chatid и token
function send_tg(text){

    var chatid = '@iartsorders',
        token = '273805635:AAGQOuPVadtQyEx0COPrDnq2r-YmUo90xaU',
  	z = $.ajax({
	   type: "POST",  
	   url: "https://api.telegram.org/bot"+token+"/sendMessage?chat_id="+chatid,
  	   data: "parse_mode=HTML&text="+encodeURIComponent(text), 
  }); 

Рабочий код без лишних наворотов. Скрипт при клике собирает данные из формы и пересылает в указанный Telegram канал.

Плохая идея т.к. код не защищен от бесконечных нажатий. Отправка всегда будет успешна и конкурент сможет атаковать вас спамом сутки напролет.

Закрываем возможность спам рассылок

Целевое назначение написанного изначально скрипта — модальное окно на лендинге и прием заявок. Поэтому вся дальнейшая логика исходит из конкретных задач.

1. Валидация телефона и запрет его копирования и вставки. Запрет второй отправки

Именно телефон. Текстовое поле нас не интересует. Главное получить заявку в виде номера телефона. Мы всегда сможем перезвонить и уточнить недостающую информацию.

Тут же закроем возможность отправлять сообщение второй раз (такой себе дабл-клик)

// ONCLICK BUTTON
$('#datas-btn').click(function(e){

   // отменяем подброс страницы вверх при клике на href="#"
   e.preventDefault();

	// Очищаем поле с результатом на этапе сразу после клика иначе будут бесконечные дубли текстов с результатом клика по кнопке
	$('p.ressult').empty();

	// получаем данные из полей формы
	var f_phone = $('input.phone').val(),
	    f_descr = $('textarea.descr').val();

	// Проверяем корректность номера телефона (только РФ)
	if(f_phone == '' || !validatePhone(f_phone)){

	   // Если Телефон не корректный — выводим результат
	   $('p.ressult').css('color', 'red').append('Некорректно заполнен номер телефона');

	}else{

	   // Если Телефон корректный — выводим результат
	   $('p.ressult').css('color', 'red').append('Заявка отправлена!<br>Мы свяжемся с вами в ближайшее время');

	   // Защита от «Дурака» 2. Вешаем метку в виде CSS класса и блокируем повторную отправку заявки
	   $('#datas-btn').addClass('sent');
	}

});

// STATIC FUNCTIONS
// Защита от «Дурака» 3. Блокируем возможность вставки в поле с номером телефона, дабы отбить желание спамить нам заявки
$('input.phone').bind('cut copy paste', function (e) {
    e.preventDefault();
});

// Валидация телефона через регулярные выражения
function validatePhone(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);
}

2. Проверим нашу форму совершенный клик и отсечем повторный. Запишем факт клика в Cookies

$('#datas-btn').click(function(e){

   // отменяем подброс страницы вверх при клике на href="#"
   e.preventDefault();

	// Очищаем поле с результатом 
	$('p.ressult').empty();

        // проверяем нашу метку
	if($('#datas-btn').hasClass('sent')){

          // если она есть — выводим сообщение с ошибкой
          $('p.ressult').css('color', 'red').append('Вы уже отправили заявку. Если была допущена ошибка — обновите страницу и отправьте заново.');
	
        }else{

	// получаем данные из полей формы
	var f_phone = $('input.phone').val(),
	    f_descr = $('textarea.descr').val();

	// Проверяем корректность номера телефона (только РФ)
	if(f_phone == '' || !validatePhone(f_phone)){

 	  $('p.ressult').css('color', 'red').append('Некорректно заполнен номер телефона');

	}else{
	  // Если Телефон корректный — выводим результат
	  $('p.ressult').css('color', 'red').append('Заявка отправлена!<br>Мы свяжемся с вами в ближайшее время');

	// Защита от «Дурака» 2. Вешаем метку в виде CSS класса и блокируем повторную отправку заявки
	$('#datas-btn').addClass('sent');

	// Заносим номер телефона и текст в куки
	Cookies.set('phone', f_phone);
	Cookies.set('text', f_descr);

	// Защита от «Дурака» 1. Даем две попытки на отправку заяявок. Фиксируем их в куках
	if(!Cookies.get('sent')){
  	 Cookies.set('sent', '1');
	}else if(Cookies.get('sent') == '1'){
	 Cookies.set('sent', '2');
	}		
 }
}

});

// STATIC FUNCTIONS
// Защита от «Дурака» 3. Блокируем возможность вставки в поле с номером телефона, дабы отбить желание спамить нам заявки
$('input.phone').bind('cut copy paste', function (e) {
    e.preventDefault();
});

// Валидация телефона через регулярные выражения
function validatePhone(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);
}

Мы добавили этап неудобства. Главную задачу выполнили — минимум помех на первом этапе. Клиент должен легко и непринужденно подать заявку. А дальше — трудности.

При клике на кнопку скрипт проверяет наличие CSS класса «sent». Он добавляется сразу при клике т.е. уже после проверки. При втором клике условие отсечет отправку в канал и выдаст ошибку, как на скриншоте.

Параллельно с этим факт клика записывается в Cookies, проверку которых мы внедрим на следующем этапе.

3. Получаем Cookies до отправки и отсекаем спам

// Защита от «Дурака» 1. Проверяем куки на количество отправленных заявок и обрубаем очередную отправку после 2 попыток
if(Cookies.get('sent') == '2'){

   // Удаляем форму и на ее место вставляем текст
   $('#datas').empty().append('Вы отправили слишком много заявок. Попробуйте повторить позже. <br><br>От вас получены следующие данные: <br><br> <strong>Номер телефона:</strong> ' + Cookies.get('phone') + '<br><strong>Краткое описание:</strong> '  + Cookies.get('text'));

}

$('#datas-btn').click(function(e){

   // отменяем подброс страницы вверх при клике на href="#"
   e.preventDefault();

	// Очищаем поле с результатом 
	$('p.ressult').empty();

	if($('#datas-btn').hasClass('sent')){
	 
          $('p.ressult').css('color', 'red').append('Вы уже отправили заявку. Если была допущена ошибка — обновите страницу и отправьте заново.');
	
        }else{

	// получаем данные из полей формы
	var f_phone = $('input.phone').val(),
	    f_descr = $('textarea.descr').val();

	// Проверяем корректность номера телефона (только РФ)
	if(f_phone == '' || !validatePhone(f_phone)){

 	  $('p.ressult').css('color', 'red').append('Некорректно заполнен номер телефона');

	}else{
	  // Если Телефон корректный — выводим результат
	  $('p.ressult').css('color', 'red').append('Заявка отправлена!<br>Мы свяжемся с вами в ближайшее время');

	// Защита от «Дурака» 2. Вешаем метку в виде CSS класса и блокируем повторную отправку заявки
	$('#datas-btn').addClass('sent');

	// Заносим номер телефона и текст в куки
	Cookies.set('phone', f_phone);
	Cookies.set('text', f_descr);

	// Защита от «Дурака» 1. Даем две попытки на отправку заяявок. Фиксируем их в куках
	if(!Cookies.get('sent')){
  	 Cookies.set('sent', '1');
	}else if(Cookies.get('sent') == '1'){
	 Cookies.set('sent', '2');
	}

        //если все проверки пройдены формируем текстовое собщение				
	var text = 'Новая заявка:\n ' + f_descr +',\n ' + f_phone;
			
	//и вызываем функцию отправки в телегу
	send_tg(text);		
 }
}

});

// STATIC FUNCTIONS
// Защита от «Дурака» 3. Блокируем возможность вставки в поле с номером телефона, дабы отбить желание спамить нам заявки
$('input.phone').bind('cut copy paste', function (e) {
    e.preventDefault();
});

// Валидация телефона через регулярные выражения
function validatePhone(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);
}
// AJAX отправка данных в ТГ
function send_tg(text){

   var chatid = '@iartsorders',
       token = '273805635:AAGQOuPVadtQyEx0COPrDnq2r-YmUo90xaU',
       z = $.ajax({
	 type: "POST",  
	 url: "https://api.telegram.org/bot"+token+"/sendMessage?chat_id="+chatid,
  	 data: "parse_mode=HTML&text="+encodeURIComponent(text), 
  }); 
};

Баги и фиксы на будущее

v 1.2 от 2022.11.21 — добавил строку, которая убирает откат к началу страницы из-за клика по кнопе в виде ссылки.

e.preventDefault();

На будущее можно поработать с Cookies и вынести все настройки в переменные. Также можно убрать запрет вставки номера телефона при пустых Cookies — максимально облегчить клиенту первый контакт.

Файлы для скачивания