Как связать форму на сайте с Telegram

Заявки с сайта в Telegram

Всем - привет. Давно зрела идея разобраться с отправкой данных из формы на сайте в мессенджер Telegram, но руки не доходили, а моментально получать заявки прямо в телефон, ой как хотелось!

И вот, наконец-то посидел и разобрался. Конечно постичь все тонкости API - не удалось, но по кусочкам насобирал информацию и удалось отправить данные из контактной формы в чат Telegram. 

Это актуализированная статья, в которой решены такие проблемы, как отправка файла и пропадающий символ «+», который не приходил в сообщение и из-за этого номер телефона был некликабельным.

Важно: для отправки файла из формы в Телеграм на вашем сервере должен быть включен cURL. Обратитесь к техподдержке вашего хостинга, они подскажут что делать и как включить. У многих он включен по умолчанию. Например, на моем хостинге Beget - так.

Как связать форму на сайте с Telegram

Итак, давайте приступим. Первое что нам нужно, это создать своего бота. Делается это достаточно просто. В поиске наберите @botfather, откройте родительского бота и нажмите "Start":

Как связать форму с Telegram

Далее:

  • Пишем команду /newbot, для создания нового бота.
  • Придумываем имя бота.
  • Придумываем ник бота.
Создание бота в Телеграм

Если все прошло успешно, то увидите поздравления и токен вашего бота, в моем случае это:

341996777:AAHbnuvQib-vHU47i-6hbUrCU9D-qHYekxc

Теперь нужно найти своего бота в поиске, указав его ник и нажать "Start", чтобы активировать его. В моем случае ник @DWS_MESSAGE_bot.

Активация бота в Telegram

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

Зайдите в меню, нажмите "New Group" и задайте имя вашему чату.

Создание чата для приема заявок

Не забываем пригласить своего бота в чат.

Добавление бота в чат для приема заявок

На данный момент у нас есть бот, мы знаем его токен, есть чат, в который будут приходить заявки, и нам осталось узнать только id чата. Для этого, напишем в чате:

  • /join @ник_бота

А затем, в браузере введем:

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

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

Если все сделали правильно, то перед вами откроется подобная страница:

получение id чата в Телеграм

Нас интересует объект "chat":{"id":-209253141. — Это id моего тестового чата. На данном этапе у нас есть все, чтобы отправлять текстовые сообщение из контактной формы на сайте в Telegram. Давайте займемся реализацией PHP-обработчика нашей формы, и сделаем разметку самой формы.

Разметка формы

Не стал выдумывать что-то сверхсложное, а просто 2 поля и возможность прикрепить файл. Оставил телефон, ведь у многих возникала проблема с символом "+", а файл добавил, так как меня просили разобраться с этой темой.

<form id="form-contact" method="POST" class="contact-form" autocomplete="off" enctype="multipart/form-data">
   <p class="contact-form__title">Закажите обратный звонок и наш консультант свяжется с вами</p>
   <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" tabindex="0" 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" tabindex="0" placeholder="Введите ваш телефон">
   </div>
   <div class="contact-form__input-wrapper">
     <input type="file" name="file" id="contact-form__input_file" class="contact-form__input contact-form__input_file">
     <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="Заявка с сайта">
   <button type="submit" class="contact-form__button">Отправить</button>
</form>

Добавил стили - получилось так:

Отправка формы в Телеграм

Не забывайте, что форма отправляется без перезагрузки страницы, а значит используется ajax, и, для упрощения, jQuery. Поэтому подключаем сам jQuery, если не подключен, а после, и сам скрипт. Я сделал специальную папку telegramform, которую нужно поместить в корень сайта.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="/telegramform/js/telegramform.js"></script>

Код с AJAX запросом. Файл - telegramform.js

(function ($) {
$(".contact-form").submit(function (event) {
  event.preventDefault();
 
  // Сохраняем в переменную form id текущей формы, на которой сработало событие submit
  let form = $('#' + $(this).attr('id'))[0];
  
  // Сохраняем в переменную класс с параграфом для вывода сообщений
  let message = $(this).find(".contact-form__message");
 
  let fd = new FormData(form);
  $.ajax({
    url: "/telegramform/php/send-message-to-telegram.php",
    type: "POST",
    data: fd,
    processData: false,
    contentType: false,
    success: function success(res) {
      let respond = $.parseJSON(res);
      if (respond.err) {
        message.html(respond.err).css('color','#d42121');
        setTimeout(()=> {
          message.text('');
        }, 3000);
      } else if(respond.okSend) {
        message.html(respond.okSend).css('color','#21d4bb');
        setTimeout(()=> {
          message.text('');
        }, 3000);
      } else {
        alert ('Необработанная ошибка. Проверьте консоль и устраните.');
      }
    },
  });
});
  
}(jQuery));

А теперь сам обработчик нашей формы. Файл - send-message-to-telegram.php:

<?php
$msgs = [];
if ($_SERVER["REQUEST_METHOD"] == "POST") {

    $token = "341996777:AAHbnuvQib-vHU47i-6hbUrCU9D-qHYekxc";
    $chat_id = "-209253141";

    if (!empty($_POST['name']) && !empty($_POST['phone'])){
        $bot_url = "https://api.telegram.org/bot{$token}/";
        $urlForPhoto = $bot_url . "sendPhoto?chat_id=" . $chat_id;

        if(!empty($_FILES['file']['tmp_name'])) {
            
            // Путь загрузки файлов
            $path = $_SERVER['DOCUMENT_ROOT'] . '/telegramform/tmp/';

            // Массив допустимых значений типа файла
            $types = array('image/gif', 'image/png', 'image/jpeg');

            // Максимальный размер файла
            $size = 1024000;

            // Проверяем тип файла
             if (!in_array($_FILES['file']['type'], $types)) {
                 $msgs['err'] = 'Запрещённый тип файла.';
                echo json_encode($msgs);
                die();
             }
             
             // Проверяем размер файла
             if ($_FILES['file']['size'] > $size) {
                 $msgs['err'] = 'Слишком большой размер файла.';
                echo json_encode($msgs);
                die('Слишком большой размер файла.');
             }
             
             // Загрузка файла и вывод сообщения
             if (!@copy($_FILES['file']['tmp_name'], $path . $_FILES['file']['name'])) {
                 $msgs['err'] = 'Что-то пошло не так. Файл не отправлен!';
                 echo json_encode($msgs);
             } else {
                $filePath = $path . $_FILES['file']['name'];
                $post_fields = array('chat_id' => $chat_id, 'photo' => new CURLFile(realpath($filePath)) );
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_HTTPHEADER, array( "Content-Type:multipart/form-data" ));
                curl_setopt($ch, CURLOPT_URL, $urlForPhoto);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
                $output = curl_exec($ch);
                unlink($filePath);
             }
        }

        if (isset($_POST['name'])) {
          if (!empty($_POST['name'])){
            $name = "Имя пославшего: " . strip_tags($_POST['name']) . "%0A";
          }
        }

        if (isset($_POST['phone'])) {
          if (!empty($_POST['phone'])){
            $phone = "Телефон: " . "%2B" . strip_tags($_POST['phone']) . "%0A";
          }
        }

        if (isset($_POST['theme'])) {
          if (!empty($_POST['theme'])){
            $theme = "Тема: " .strip_tags($_POST['theme']);
          }
        }
        // Формируем текст сообщения
        $txt = $name . $phone . $theme;

        $sendTextToTelegram = file_get_contents("https://api.telegram.org/bot{$token}/sendMessage?chat_id={$chat_id}&parse_mode=html&text={$txt}");
        if ($output && $sendTextToTelegram) {
            $msgs['okSend'] = 'Спасибо за отправку вашего сообщения!';
            echo json_encode($msgs);
        } elseif ($sendTextToTelegram) {
            $msgs['okSend'] = 'Спасибо за отправку вашего сообщения!';
            echo json_encode($msgs);
          return true;
        } else {
            $msgs['err'] = 'Ошибка. Сообщение не отправлено!';
            echo json_encode($msgs);
            die('Ошибка. Сообщение не отправлено!');
        }

    } else {
        $msgs['err'] = 'Ошибка. Вы заполнили не все обязательные поля!';
        echo json_encode($msgs);;
    }
} else {
  header ("Location: /");
}
?>

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

Тут стоит обратить внимание на переменные $token и $chat_id. Не забывайте подставить туда свои данные. Кроме того, не забывайте, что все это будет работать, только если данные идут через https, хотя у меня на тестовом работает и через http.

Вот так выглядит отправка текстового сообщения:

Вот так с файлом:

Отправка файла из формы в Телеграм

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

Вот так, средствами PHP можно отправлять в Telegram сообщения и файлы. Если вы используете CMS MODX, то на блоге igamov.ru есть отличная инструкция по интеграции формы с мессенджером.

Исходник для отправки данных формы в Телеграм

Размер: 0,008

Кстати, подписывайтесь на Telegram канал. Уведомления об обновлениях на блоге, в первую очередь, приходят туда)

Похожие публикации

221 комментарий

  1. Sky

    Здравствуйте!) Спасибо огромное за статью!
    У меня есть один вопрос, как можно добавить ещё несколько полей ввода?
    Уже почти сутки голову ломаю, но ничего не получается, нужно добавить в одной из форм 3 поля, но постоянно, то ошибка PHP, то "Ошибка. Вы заполнили не все обязательные поля"..
    Подскажите пожалуйста)
    За ранее спасибо) и прошу прощение, если вопрос уже поднимался в комментариях, не увидел.

    1. Sky

      Вот как у меня "сделано"...

      HTML:

      Этажность
      t2
      t3

      Площадь
      t4
      t5

      Конструкция
      t7
      t8

      Ваш телефон:

      Я прочитал(а) и согласен с Политикой конфиденциальности

      PHP:
      $theme,
      $nameFieldset => $name,
      $name1Fieldset => $name1,
      $name2Fieldset => $name2,
      $name3Fieldset => $name3,
      $phoneFieldset => $phone
      );

      foreach($arr as $key => $value) {
      $txt .= "".$key." ".urlencode($value)."%0A";
      };
      $sendToTelegram = fopen("https://api.telegram.org/bot{$token}/sendMessage?chat_id={$chat_id}&parse_mode=html&text={$txt}","r");
      if ($sendToTelegram) {

      echo 'Спасибо за отправку вашего сообщения!';
      return true;
      } else {
      echo 'Ошибка. Сообщение не отправлено!';
      }
      } else {
      echo 'Ошибка. Вы заполнили не все обязательные поля!';
      }
      } else {
      header ("Location: /");
      }

      ?>

  2. Александр

    У меня как с openserver отправляется так и с сайт https, но только без фото!
    Если я заполняю только два поля name и phone, и делаю отправку формы, то выскакивает, "Спасибо за отправку вашего сообщения!". А если я выбираю изображение, то в телеграм приходит без фото и на форме не чего не высвечивается!

    if(!empty($_FILES['file']['tmp_name'])) {
    // Путь загрузки файлов
    $path = $_SERVER['DOCUMENT_ROOT'] . '/telegramform/img/';
    Я вот недопонимаю, что значит путь загрузки?! Что в этой папке должно быть?

  3. Александр

    Всё разобрался! Это было записано в файле

    $path = $_SERVER['DOCUMENT_ROOT'] . '/telegramform/img/';

    а реальный путь был таким /telegram/img/

    Теперь вопрос в другом?! Как сделать чтобы после отправки, поля очищались?
    Думал сделать редирект, но тогда суть скрипта без перезагрузки, теряется!

    1. Дмитрий Давыдов

      Александр посмотрите в сторону

      document.getElementById('myform').reset();
  4. Саня

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

    1. Дмитрий Давыдов

      Саня, здравствуйте. Проверьте ошибки в консоли браузера.

  5. Саня

    Не могу написать ошибку, пишет обсуждение закрыто

  6. Искандар

    Здравствуйте, Дмитрий
    Все настроил по инструкции как сказано в статье на локальном сайте все работает файл и текст отправляется на телеграмм.... только когда загружаю на хостинг не работает.... после ввода данных страница просто обновляется и все
    хостинг Beget - curl включён
    не знаю что делать ?

    1. Дмитрий Давыдов

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

  7. Искандар

    Дмитрий
    Спасибо нашел проблему )

  8. никита

    Добрый день никак не могу поблороть проблему : Uncaught SyntaxError: Unexpected token < in JSON at position 0
    at JSON.parse ()
    at Function.n.parseJSON (jquery.min.js:4)
    at Object.success (telegramform.js:19)
    at i (jquery.min.js:2)
    at Object.fireWith [as resolveWith] (jquery.min.js:2)
    at z (jquery.min.js:4)
    at XMLHttpRequest. (jquery.min.js:4)

    1. Дмитрий Давыдов

      Никита, здаравствуйте. Посмотрите что приходит в res, прежде чем делать $.parseJSON(res), там не должно быть ничего лишнего, кроме нужных данных.

  9. Сергей

    У меня такая проблема
    Status Code: 405 Method Not Allowed

  10. Руслан

    Уважаемые, не нужно создавать группу в телеграме, чтобы бот отправлял в группу, можно сделать чтобы он отправлял лично конкретному человеку, просто отправьте (или пусть ваш клиент отправит) боту сообщение с текстом /join @ИмяБота и так же в браузере по ссылке с токеном отобразится id этого чата, только уже не группового, а того контакта который отправил сообщение, и так же просто указываете этот id в обработчике и бот будет отправлять в этот чат. Не надо заморачиваться с группой, особенно когда делаете для клиента. Почему автор об этом не сказал, не знаю.

    1. Саня

      Руслан, А зачем? если клиент заполняет на сайте форму обратной связи, для чего ему заморочки с отправкой боту сообщений? Это ведь просто как оповещание, что клиент заказал звонок

  11. Денис

    добрый день, такой вопрос. Форму вашу встроил в свою, всё работает, спасибо большое за решение! Но не могу разобраться, помогите. На странице имеется две формы, в начале страницы и в конце, и отправляются данные только с заполненными полями в верхней форме. Как изолировать их друг от друга?

    Например заполнена форма верхняя, данные отправляются при нажатии на кнопку от обоих форм.
    Если данные заполнены только внизу то форма не отправляется.

    Инкапсулировать бы их как то

    1. Дмитрий Давыдов

      Денис, здравствуйте. Да, конечно можно, просто укажите у форм разный id

  12. Korney Ivanov

    Здравствуйте,
    При нажатии на кнопку submit в браузере открывается сам файл php с кодом. В чем может быть ошибка?

    1. Дмитрий Давыдов

      Korney Ivanov, вы же на сервере тестируете? Какая версия PHP?

Добавить комментарий

 

© 2014 — 2021, Smartlanding.biz. Все права защищены. Любое использование материалов допускается только с указанием активной ссылки на источник. Политика конфиденциальности