Всем - привет. Давно зрела идея разобраться с отправкой данных из формы на сайте в мессенджер Telegram, но руки не доходили, а моментально получать заявки прямо в телефон, ой как хотелось!
И вот, наконец-то посидел и разобрался. Конечно постичь все тонкости API - не удалось, но по кусочкам насобирал информацию и удалось отправить данные из контактной формы в чат Telegram.
Это актуализированная статья, в которой решены такие проблемы, как отправка фото и пропадающий символ «+», который не приходил в сообщение и из-за этого номер телефона был некликабельным. Появилась возможность не просто отправлять 1 фото, а сразу несколько файлов, в том числе PDF, docx и любых других.
Важно: для отправки файла из формы в Телеграм на вашем сервере должен быть включен cURL. Обратитесь к техподдержке вашего хостинга, они подскажут что делать и как включить. У многих он включен по умолчанию. Например, на моем хостинге Beget - так.
Как отправить данные формы на сайте в Telegram
Итак, давайте приступим. Первое что нам нужно - это создать своего бота. Делается это достаточно просто. В поиске наберите @botfather, откройте родительского бота и нажмите "Start":
Далее:
- Пишем команду /newbot, для создания нового бота.
- Придумываем имя бота.
- Придумываем ник бота.
Если все прошло успешно, то увидите поздравления и токен вашего бота, в моем случае это:
341996777:AAHbnuvQib-vHU47i-6hbUrCU9D-qHYekxc
Теперь нужно найти своего бота в поиске, указав его ник и нажать "Start", чтобы активировать его. В моем случае ник @DWS_MESSAGE_bot.
После этого можно пойти двумя путями:
- создать групповой чат, в который будут приходить заявки и пригласить туда нашего бота;
- вступить в переписку с ботом и получать личные сообщения от него.
Давайте займемся этим и, пока, пойдем по первому пути.
Зайдите в меню, нажмите "New Group" ("Создать группу") и задайте имя вашему чату.
Не забываем пригласить своего бота в чат. Откройте меню чата, перейдите в "Add Members" ("Добавить участников") и введите имя своего бота.
На данный момент у нас есть бот, мы знаем его токен, есть чат, в который будут приходить заявки, и нам осталось узнать только id чата. Для этого, напишем в чате:
- /join @ник_бота
А затем перейдите в браузер, если используете приложение и введите:
https://api.telegram.org/botXXXXXXXXXXXXXXXXXXXXXXX/getUpdates
где, XXXXXXXXXXXXXXXXXXXXXXX - токен вашего бота, полученный ранее.
Если все сделали правильно, то перед вами откроется подобная страница:
Нас интересует объект "chat":{"id":-209253141. — Это id моего тестового чата. На данном этапе у нас есть все, чтобы отправлять текстовые сообщение из контактной формы на сайте в Telegram. Давайте займемся реализацией PHP-обработчика нашей формы, и сделаем разметку самой формы.
Кстати, если не хотите создавать группу, то можете получать личные сообщения от бота. Просто напишите своему боту /join @ник_бота, а потом, в браузере наберите https://api.telegram.org/botXXXXXXXXXXXXXXXXXXXXXXX/getUpdates. Как и в первом случае, нужно просто узнать id чата.
Разметка формы
Не стал выдумывать что-то сверхсложное, а просто 2 поля и возможность прикрепить файл. Оставил телефон, ведь у многих возникала проблема с символом "+", а файл добавил, так как меня просили разобраться с этой темой, при этом, теперь можно вставлять несколько штук.
<form id="form-contact" method="POST" class="contact-form" autocomplete="off" enctype="multipart/form-data">
<p class="contact-form__title">Закажите обратный звонок и наш консультант свяжется с вами</p>
<div class="preloader"></div>
<p class="contact-form__message"></p>
<!-- Поле с именем -->
<div class="contact-form__input-wrapper contact-form__input-wrapper_name">
<input name="name" type="text" class="contact-form__input contact-form__input_name"
placeholder="Введите ваше имя">
</div>
<!-- Поле с телефоном -->
<div class="contact-form__input-wrapper contact-form__input-wrapper_phone">
<input name="phone" type="tel" class="contact-form__input contact-form__input_phone"
placeholder="Введите ваш телефон">
</div>
<!-- Поле с выбором файла -->
<div class="contact-form__input-wrapper">
<input type="file" name="files[]" id="contact-form__input_file"
class="contact-form__input contact-form__input_file" multiple>
<label for="contact-form__input_file" class="contact-form__file-button">
<span class="contact-form__file-text">Выберите файл</span>
</label>
</div>
<!--Поле с темой в письме-->
<input name="theme" type="hidden" class="contact-form__input contact-form__input_theme"
value="Заявка с сайта Smartlanding.biz">
<!--Кнопка отправки формы-->
<button type="submit" class="contact-form__button">Отправить</button>
</form>
Добавил стили - получилось примерно так (внешний вид в исходнике немного отличается):
Не забывайте, что форма отправляется без перезагрузки страницы, а значит используется ajax, и, для упрощения, jQuery. Поэтому подключаем сам jQuery, если не подключен, а после, и сам скрипт. Я сделал специальную папку telegramform, которую нужно поместить в корень сайта. Если нужно, сделаю исходник без использования jQuery.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="/telegramform/js/telegramform.js"></script>
Код с AJAX запросом. Файл - telegramform.js
(function ($) {
$(".contact-form").submit(function (event) {
event.preventDefault();
// Сообщения формы
let successSendText = "Сообщение успешно отправлено";
let errorSendText = "Сообщение не отправлено. Попробуйте еще раз!";
let requiredFieldsText = "Заполните поля с именем и телефоном";
// Сохраняем в переменную класс с параграфом для вывода сообщений об отправке
let message = $(this).find(".contact-form__message");
let form = $("#" + $(this).attr("id"))[0];
let fd = new FormData(form);
$.ajax({
url: "/telegramform/php/send-message-to-telegram.php",
type: "POST",
data: fd,
processData: false,
contentType: false,
beforeSend: () => {
$(".preloader").addClass("preloader_active");
},
success: function success(res) {
$(".preloader").removeClass("preloader_active");
// Посмотреть на статус ответа, если ошибка
// console.log(res);
let respond = $.parseJSON(res);
if (respond === "SUCCESS") {
message.text(successSendText).css("color", "#21d4bb");
setTimeout(() => {
message.text("");
}, 4000);
} else if (respond === "NOTVALID") {
message.text(requiredFieldsText).css("color", "#d42121");
setTimeout(() => {
message.text("");
}, 3000);
} else {
message.text(errorSendText).css("color", "#d42121");
setTimeout(() => {
message.text("");
}, 4000);
}
}
});
});
})(jQuery);
А теперь сам обработчик нашей формы. Файл - send-message-to-telegram.php:
<?php
// Токен
const TOKEN = '341996777:AAHbnuvQib-vHU47i-6hbUrCU9D-qHYekxc';
// ID чата
const CHATID = '-209253141';
// Массив допустимых значений типа файла.
$types = array('image/gif', 'image/png', 'image/jpeg', 'application/pdf');
// Максимальный размер файла в килобайтах
// 1048576; // 1 МБ
$size = 1073741824; // 1 ГБ
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$fileSendStatus = '';
$textSendStatus = '';
$msgs = [];
// Проверяем не пусты ли поля с именем и телефоном
if (!empty($_POST['name']) && !empty($_POST['phone'])) {
// Если не пустые, то валидируем эти поля и сохраняем и добавляем в тело сообщения. Минимально для теста так:
$txt = "";
// Имя
if (isset($_POST['name']) && !empty($_POST['name'])) {
$txt .= "Имя пославшего: " . strip_tags(trim(urlencode($_POST['name']))) . "%0A";
}
// Номер телефона
if (isset($_POST['phone']) && !empty($_POST['phone'])) {
$txt .= "Телефон: " . strip_tags(trim(urlencode($_POST['phone']))) . "%0A";
}
// Не забываем про тему сообщения
if (isset($_POST['theme']) && !empty($_POST['theme'])) {
$txt .= "Тема: " . strip_tags(urlencode($_POST['theme']));
}
$textSendStatus = @file_get_contents('https://api.telegram.org/bot'. TOKEN .'/sendMessage?chat_id=' . CHATID . '&parse_mode=html&text=' . $txt);
if( isset(json_decode($textSendStatus)->{'ok'}) && json_decode($textSendStatus)->{'ok'} ) {
if (!empty($_FILES['files']['tmp_name'])) {
$urlFile = "https://api.telegram.org/bot" . TOKEN . "/sendMediaGroup";
// Путь загрузки файлов
$path = $_SERVER['DOCUMENT_ROOT'] . '/telegramform/tmp/';
// Загрузка файла и вывод сообщения
$mediaData = [];
$postContent = [
'chat_id' => CHATID,
];
for ($ct = 0; $ct < count($_FILES['files']['tmp_name']); $ct++) {
if ($_FILES['files']['name'][$ct] && @copy($_FILES['files']['tmp_name'][$ct], $path . $_FILES['files']['name'][$ct])) {
if ($_FILES['files']['size'][$ct] < $size && in_array($_FILES['files']['type'][$ct], $types)) {
$filePath = $path . $_FILES['files']['name'][$ct];
$postContent[$_FILES['files']['name'][$ct]] = new CURLFile(realpath($filePath));
$mediaData[] = ['type' => 'document', 'media' => 'attach://'. $_FILES['files']['name'][$ct]];
}
}
}
$postContent['media'] = json_encode($mediaData);
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, ["Content-Type:multipart/form-data"]);
curl_setopt($curl, CURLOPT_URL, $urlFile);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postContent);
$fileSendStatus = curl_exec($curl);
curl_close($curl);
$files = glob($path.'*');
foreach($files as $file){
if(is_file($file))
unlink($file);
}
}
echo json_encode('SUCCESS');
} else {
echo json_encode('ERROR');
//
// echo json_decode($textSendStatus);
}
} else {
echo json_encode('NOTVALID');
}
} else {
header("Location: /");
}
Во многом он повторяет обработчик из других форм на блоге. Например, в статье "Создание формы обратной связи" используется аналогичный подход, и вы легко сможете осуществить отправку данных как на почту, так и в мессенджер одновременно. Но помните, что это все тестовый, учебный пример и в реальной жизни можно сделать намного больше проверок.
Тут стоит обратить внимание на константы TOKEN и CHATID. Не забывайте подставить туда свои данные. Чтобы принимать какой-то определённый тип файла, поместите его в "Массив допустимых значений типа файла." Из популярных можно выделить:
.jpeg .jpg | image/jpeg |
.csv | text/csv |
.doc | application/msword |
.docx | application/vnd.openxmlformats-officedocument.wordprocessingml.document |
.svg | image/svg+xml |
.txt | text/plain |
.xls | application/vnd.ms-excel |
.xlsx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
.png | image/png |
application/pdf |
При этом файлы будут приходить общим потоком, одним сообщением. Если тип файла не проходит проверку, то он просто не отправляется. Специально не прерываю отправку, так как для большинства важно получить хотя бы контакты для связи, чтобы не потерять лида. Больше типов файлов тут.
Вот так выглядит отправка сообщения:
Не стал делать каких-то серьезных валидаций, так как это просто пример и вам наверняка нужно будет не только отправка текста или картинки в Телеграм, но и на почту, а значит все равно подстраивать под свои нужды. Если будут вопросы и замечания - пишите в комментариях.
Видеопример:
Вот так, средствами PHP можно отправлять в Telegram сообщения и файлы. Если вы используете CMS MODX, то на блоге igamov.ru есть отличная инструкция по интеграции формы с мессенджером.
Исходник для отправки данных формы в Телеграм
Размер: 0,008
Кстати, подписывайтесь на Telegram канал. Уведомления об обновлениях на блоге, в первую очередь, приходят туда).
333 комментария
- убрать прикрепить файл.
+ добавить капчу, просто цифры ввести 4 штуки.
+ добавить логотип-картинку.
всё!
Добрый день!
Как сделать чтобы при отправке отправлялся и на почту
Вот тут описывал, как отправить на почту.
Дмитрий Давыдов, а как потом сделать чтобы в телеграм отправился
как к полученным данным прикрепить Inline клавиатуру?
вообще не понял вопрос...
Файл не приходит в чат телеграм :(
Приходит
михаил, проходит, я тоже засунул в папку сам скрипт, сделал правки, но перекинув скрипт в корень всё начало приходить
Если вы скачали исходный код,то там не указан action,если его прописать,то все будет отправляться
Но пока сам не разобрался почему не приходит файл прикрепленный
михаил, значит не в том виде приходит... его просто нет
ПРоверил еще раз. Файл не приходит. текст с полей приходит...
Вот скрин - все приходит: https://prnt.sc/X3TZtOz4c3Fc Ищите ошибку.
http://u29233w2.beget.tech/
Залил на таймвеб, заполняю форму, дальше при отправке она просто думает и ничего не происходит
Даниил, обратите внимание на то, какой у вас класс у формы, у submit какой формы вы отслеживаете в main.js
Прошу прощения, вставил ссылку из предыдущих комментариев
Вот моя, разархивировал прикрепленный вами архив, вставил токен и чат айди, больше ничего не менял
Ссылки-то нет
Добрый день, при отправке заявок с сайта в телеграм, будет ли какой то фильтр от спама?
Анастасия, капчу дополнительно прикрутите и будет фильтр от ботов. От людей не поможет...только верификация через смс или типа того.
Большое спасибо! Очень помогла ваша статья!
Здравствуйте . Мой акаунт был взломан и теперь я не знаю как мне его заблокировать или востановить. На том конце постоянно фиксируют мои попытки входа и выкидывают. Спасибо
Дмитрий, здравствуйте. Никак не могу найти обработчик форм для отправки заявки в телеграм и на почту одновременно. Помогите пож-та с реализацией этой функции. Форма стандартная , без прикрепленных файлов. Ну если у вас есть и с функцией прикрепленного файла , то это было бы вообще великолепно! Спасибо.
Скачал готовый архив, вставил токен и id - при отправке просто вечная загрузка(
Богдан, а вы загрузили на хостинг? дайте ссылку и покажите код скрипта
Все скачал со статьи, менял токен и айди прямо в скачанном архиве - так что ничего важного не менял. По итогу решение не нашел, психанул и по гайду с ютуба написал свой скрипт к своей форме.
Фото не приходит в телегу почему то не подскажите где смотреть
Спасибо! работает, а подскажите если двуязычный сайт, то сложно ли в js реализовать кусок кода :
// Сообщения формы
let successSendText = "Сообщение успешно отправлено";
let errorSendText = "Сообщение не отправлено. Попробуйте еще раз!";
let requiredFieldsText = "Заполните поля с именем и телефоном";
по типу если /index.html то на одном языке, а если /ru/index.html то на другом ?
Не приходит вложенный контент в телегу. Имя и телефон все ок
Дай Бог тебе здоровья, автор! Потрясающее решение, которое мне очень сильно помогло
Здравствуйте, нужно чтобы поле с сообщением было как в обратной связи, как это реализовать, благодарю за ответ.