В общем-то, эта статья является дополнением этой — Пишем бота для Telegram на php, так-что если вы попали сюда впервые — советую, для начала, прочитать ее.
Здесь я отвечу читателям на ряд вопросов, которые мне были заданы тут, на блоге.(см комментарии в указанном выше посте) В общем и целом, все варианты тут будут приведены для языка php, однако ничто не мешает вам использовать их, например, на C#.
Как, используя бота, публиковать новости в свой канал
Поясню для читателя, что такое канал. Канал, это что-то вроде паблика вк, на нем нельзя общаться, но можно читать, что пишет автор этого самого канала. Как пример — Красные Котлеты — это мой личный канал, подписывайтесь, к стати. Ну, если мои взгляды (анархо-коммунист) разделяете, разумеется.
Для решения этой, с виду не такой уж простой, задачи надо добавить нашего бота в канал, как администратора. Чтобы сделать это, я, на своей текущей версии телеграма, перехожу в админку канала и добавляю туда своего бота из вышеуказанной статьи. Переходим в управление группой -> administrators
Тыкаем туда, после чего указываем ник нашего бота и добавляем.
Отлично!
Код
Тут, на самом деле, ничего сложно нет, однако у многих на этом этапе возникает сложность. Сейчас поясню. По идее нам надо отправлять в канал сообщения через метод $bot->sendMessage(), однако, первый аргумент этого метода требует наличия некоего ID чата. В случае с конфами, диалогами и прочей фигней эти самые ID — цифровые, как у групп в VK, а вот в случае с каналами такие ID соответствуют названию самих каналов. Поэтому, чтобы отослать в канал «Красные котлеты» сообщение «Тест», нужен такой код:
$bot->sendMessage("@burgercaputt", "Тест");
Куда прописывать? Да прямо между $bot = new \TelegramBot\Api\Client($token,null); и $bot->run(); впишите. В смысле примерно так, как на картинке.
Вроде все сделано, теперь надо заставить бота отослать сообщение в канал. Как это сделать? Да легко, переходим на страничку с вашим ботом и руками нажимаем там F5(обновить).
Ну и, собственно, вот результат работы —
Теперь ничего не стоит добавить вызов страницы бота в, например, CURL и получить отложенный постинг для канала.
Так-же был вопрос — как сделать, чтобы бот публиковал информацию в канал по команде, или публиковал в несколько каналов.
— Запросто — используйте банальные GET параметры, вот как примерно в этом наброске кода:
if($_GET["bname"] == "revcombot"){
$bot->sendMessage("@burgercaputt", "Тест");
}
if($_GET["bname"] == "someoother"){
$bot->sendMessage("@someoother", "Тест");
}
Теперь достаточно обратиться к файлу index.php с get параметрами вида index.php?bname=revcombot, чтобы получить результат.
Как вывести кнопки после сообщения и обработать их
Для начала о каких кнопках идет речь. Вот на картинке вы видите их:
Как вывести такие кнопки используя telegram-bot/api? Вообще, это весьма обширная тема, я чуть ли не два часа потратил на эти гребаные кнопки и попытки их осилить. Выводятся они следующим кодом:
// Кнопки у сообщений
$bot->command("ibutton", function ($message) use ($bot) {
$keyboard = new \TelegramBot\Api\Types\Inline\InlineKeyboardMarkup(
[
[
['callback_data' => 'data_test', 'text' => 'Answer'],
['callback_data' => 'data_test2', 'text' => 'ОтветЪ']
]
]
);
$bot->sendMessage($message->getChat()->getId(), "тест", false, null,null,$keyboard);
});
То есть по команде /ibutton вылезут к нам две кнопки Answer и ОтветЪ. С выводом разобрались, теперь нам надо их обработать. Делается все так:
// Обработка кнопок у сообщений
$bot->on(function($update) use ($bot, $callback_loc, $find_command){
$callback = $update->getCallbackQuery();
$message = $callback->getMessage();
$chatId = $message->getChat()->getId();
$data = $callback->getData();
if($data == "data_test"){
$bot->answerCallbackQuery( $callback->getId(), "This is Ansver!",true);
}
if($data == "data_test2"){
$bot->sendMessage($chatId, "Это ответ!");
$bot->answerCallbackQuery($callback->getId()); // можно отослать пустое, чтобы просто убрать "часики" на кнопке
}
}, function($update){
$callback = $update->getCallbackQuery();
if (is_null($callback) || !strlen($callback->getData()))
return false;
return true;
});
Вот и все. Собственно, вот результат работы этой функции:
Ну и результат нажатия на вторую кнопку, для большей… полноты материала.
Обработка reply-кнопок
Если вы работали с botfather’ом то видели там такую панельку из кнопок под текстовым полем, выглядят они примерно так:
У людей возникает вопрос: как вывести эти кнопки? На самом деле это весьма просто сделать.
Вот код —
// Reply-Кнопки
$bot->command("buttons", function ($message) use ($bot) {
$keyboard = new \TelegramBot\Api\Types\ReplyKeyboardMarkup([[["text" => "Власть советам!"], ["text" => "Сиськи!"]]], true, true);
$bot->sendMessage($message->getChat()->getId(), "тест", false, null,null, $keyboard);
});
Тут задается команда /buttons после которой и появляются эти reply-кнопки. Как обработать? На самом деле никакой особой обработки не требуется, в смысле кнопки надо обрабатывать как обычные текстовые сообщения. В данном случае, я сделал это через метод on() —
// Отлов любых сообщений + обработка reply-кнопок
$bot->on(function($Update) use ($bot){
$message = $Update->getMessage();
$mtext = $message->getText();
$cid = $message->getChat()->getId();
if(mb_stripos($mtext,"Сиськи") !== false){
$pic = "http://aftamat4ik.ru/wp-content/uploads/2017/05/14277366494961.jpg";
$bot->sendPhoto($message->getChat()->getId(), $pic);
}
if(mb_stripos($mtext,"власть советам") !== false){
$bot->sendMessage($message->getChat()->getId(), "Смерть богатым!");
}
}, function($message) use ($name){
return true; // когда тут true - команда проходит
});
Ну и, собственно, если на любую из этих кнопок ткнуть, получим результат.
Обработка inline-запросов
Что такое inline запрос у telegram? Это… Хм, на словах будет сложно объяснить, лучше покажу. Есть у нас бот, очень популярный у пользователей — @vkmusic_bot, он выполняет поиск музыки по вконтакте. И его можно вызывать в любом месте телеграма. Просто прописываем название бота и следом — название трека, который надо найти. Это и есть inline запрос.
Как сделать в своем боте такую-же фичу?
На самом деле эта задачка заставила меня попотеть изрядно. Я перелопатил половину буржунета и весь код долбаной библиотеки telebram-bot/api . Однако, решение все-таки нашел, к счастью.
Подготовка бота
Не только лишь все боты могут обрабатывать inline запросы, а только те, в которых автор включил эту фичу. Идем на botfather’а и выполняем там команду /setinline, после чего выбираем бота. Вылезет что-то типа того:
Думаете все, режим включился? А вот фиг там было! Нам надо передать в botfather’а форму инлайн команды, примерно так: @revcom_bot тестовый inline ответ
Вот ТЕПЕРЬ можно начинать написание кода.
Код
Собственно в библиотеке бота есть метод $bot->inlineQuery(), именно он отвечает за обработку контекстных запросов. Но как заставить его работать? Оказывается у каждого поля, отправляемого в результат запроса свой формат + для некоторых полей надо данные готовить заранее. Однако я все прокомментировал, так что разобраться с этим функционалом вы сможете в два счета. А вот мне пришлось чуть ли не в слепую угадывать что и куда ставить из-за отсутствия вменяемой документации к библиотеке.
// обработка инлайнов
$bot->inlineQuery(function ($inlineQuery) use ($bot) {
mb_internal_encoding("UTF-8");
$qid = $inlineQuery->getId();
$text = $inlineQuery->getQuery();
// Это - базовое содержимое сообщения, оно выводится, когда тыкаем на выбранный нами инлайн
$str = "Что другие?
Свора голодных нищих.
Им все равно...
В этом мире немытом
Душу человеческую
Ухорашивают рублем,
И если преступно здесь быть бандитом,
То не более преступно,
Чем быть королем...
Я слышал, как этот прохвост
Говорил тебе о Гамлете.
Что он в нем смыслит?
Гамлет восстал против лжи,
В которой варился королевский двор.
Но если б теперь он жил,
То был бы бандит и вор.";
$base = new \TelegramBot\Api\Types\Inline\InputMessageContent\Text($str,"Html");
// Это список инлайнов
// инлайн для стихотворения
$msg = new \TelegramBot\Api\Types\Inline\QueryResult\Article("1","С. Есенин","Отрывок из поэмы `Страна негодяев`");
$msg->setInputMessageContent($base); // указываем, что в ответ к этому сообщению надо показать стихотворение
// инлайн для картинки
$full = "http://aftamat4ik.ru/wp-content/uploads/2017/05/14277366494961.jpg"; // собственно урл на картинку
$thumb = "http://aftamat4ik.ru/wp-content/uploads/2017/05/14277366494961-150x150.jpg"; // и миниятюра
$photo = new \TelegramBot\Api\Types\Inline\QueryResult\Photo("2",$full,$thumb);
// инлайн для музыки
$url = "http://aftamat4ik.ru/wp-content/uploads/2017/05/mongol-shuudan_-_kozyr-nash-mandat.mp3";
$mp3 = new \TelegramBot\Api\Types\Inline\QueryResult\Audio("3",$url,"Монгол Шуудан - Козырь наш Мандат!");
// инлайн для видео
$vurl = "http://aftamat4ik.ru/wp-content/uploads/2017/05/bb.mp4";
$thumb = "http://aftamat4ik.ru/wp-content/uploads/2017/05/joker_5-150x150.jpg";
$video = new \TelegramBot\Api\Types\Inline\QueryResult\Video("4",$vurl,$thumb, "video/mp4","коммунальные службы","тут тоже может быть описание");
// отправка
try{
$result = $bot->answerInlineQuery( $qid, [$msg,$photo,$mp3,$video],100,false);
}catch(Exception $e){
file_put_contents("rdata",print_r($e,true));
}
});
Как это сработает в боте? Смотрим.
Проверить все три оставшихся варианта вы сможете прямо в telegram’е на странице моего бота, ну а тут я выведу вам результат теста только первого элемента с отрывком поэмы Сергея Есенина.
Надеюсь, я смог решить вашу проблему.
Исходники
Разумеется, важно выложить исходники бота. Если не хотите все перечитывать, просто скачайте их и тестируйте.

Желающие могут поиграться с демонстрационным ботом тут — revcom_bot
Ах да, вы таки не поверите, но я принимаю ДОНАТ! Если статья помогла вам — помогите и мне, хехе.
wm — R343924802694
Коммуникабельный бот-)
ну дык, Дуров постоянно улучшает telegram, то кнопки добавит, то короткие войс-сообщения, то еще что-то. А люди хотят в своих ботах всю эту хрень видеть, ну и… приходится искать способы реализации, как говорится.
Спасибо огромное! Реально круто! тоже вчера на эти кнопки полдня убила, но так и не дошла до логичного завершения, а сегодня с вашей помощью все ок! Сейчас пробую методы editMessageCaption и editMessageReplyMarkup, чтоб не новые сообщения отправлялись, а перезатирались старые (особенно полезно для клавиатур). Еще раз спасибо
пожалуйста) очень рад, что смог помочь
Ебааааать! Ты Штокман? Троцкач, которого еще когда соцсети были молодыми и рулили форумы, банили повсюду. Чур, меня, чур. Форум РКСМ(б) помнишь, форум ревфронта загорска? Какие срачи были, эх….
нет, я немного не тот Штокман. Тот Андрей, вроде, а я Саша.
Привет, было бы здорово если бы написал статью про интернет магазинов или доставка еды. Щас такие боты актуальная тема помоэму!
я не занимаюсь доставкой еды и интернет магазинами, но если статья поможет кому-то из кодеров написать бота для магазина или чего-то еще я буду только рад. А сам я про магазины не пишу.
Здарова, а как подключиться к БД?
я попробовал так, но не сработал..
$mysqli = new mysqli(«localhost», «*****», «***********», «*****_db»);
if ($mysqli->connect_errno) {
echo «Не удалось подключиться к MySQL: (» . $mysqli->connect_errno . «) » . $mysqli->connect_error;
}
$bot->command(‘pip’, function ($message) use ($bot) {
$res = $mysqli->query(«SELECT name FROM stopwatch Where id=1»);
$row = $res->fetch_assoc();
$bot->sendMessage($message->getChat()->getId(), $row);
});
насчет бд это вам не ко мне, а к документации php
советую сделать так, как написано тут — http://www.softtime.ru/bookphp/gl12_10.php
К слову, не используйте mysqli, если не уверены в том, что это расширение есть на сервере.
Добрый вечер aftamat4ik!
как можно обработать InlineKeyboard и ReplyKeyboard в методе on()??
я же показал пример как обрабатывать, вот тут обработка reply-keyboard — http://aftamat4ik.ru/bot-dlya-telegram-na-php-knopki-posting-inline-queryes/#reply-buttons с методом on,
а вот — http://aftamat4ik.ru/bot-dlya-telegram-na-php-knopki-posting-inline-queryes/#buttons — обработка InlineKeyboard в методе on.
Объедините их. Или просто используйте 2 метода on, как я делаю в примере(там их даже три!). Скачайте файлы исходников и посмотрите.
не получается объединить их(
Вот код:
________________________________________________________________
$bot->command(«ibutton», function ($message) use ($bot) {
$keyboard = new \TelegramBot\Api\Types\ReplyKeyboardMarkup([[[«text» => «button1»], [«text» => «button1»]]], true, true);
$bot->sendMessage($message->getChat()->getId(), «тест», false, null,null,$keyboard);
});
// Обработка кнопок у сообщений
$bot->on(function($update) use ($bot,$callback_loc, $find_command){
$message = $update->getMessage();
$mtext = $message->getText();
switch ($mtext) {
case ‘button1’:
$keyboard = new \TelegramBot\Api\Types\Inline\InlineKeyboardMarkup(
[
[
[‘callback_data’ => ‘data_test1’, ‘text’ => ‘Answer’],
[‘callback_data’ => ‘data_test2’, ‘text’ => ‘ОтветЪ’]
]
]
);
$bot->sendMessage($message->getChat()->getId(), «тест», false, null,null,$keyboard);
break;
case ‘button1’:
$keyboard = new \TelegramBot\Api\Types\Inline\InlineKeyboardMarkup(
[
[
[‘callback_data’ => ‘data_test3’, ‘text’ => ‘Answer’],
[‘callback_data’ => ‘data_test4’, ‘text’ => ‘ОтветЪ’]
]
]
);
$bot->sendMessage($message->getChat()->getId(), «тест», false, null,null,$keyboard);
break;
}
$callback = $update->getCallbackQuery();
$message = $callback->getMessage();
$chatId = $message->getChat()->getId();
$data = $callback->getData();
switch ($data) {
case ‘data_test1’:
$bot->sendMessage($message->getChat()->getId(), «тест1», false, null,null,$keyboard);
break;
case ‘data_test2’:
$bot->sendMessage($message->getChat()->getId(), «тест2», false, null,null,$keyboard);
break;
}
}, function($message) use ($name){
return true; // когда тут true — команда проходит
});
_______________________________________
если не получается — используйте по рознь оба сразу. Это удобнее т.к. код проще читать будет.
т.е. использовать два раза метода on()??
так тоже попробовал но не получилось, так как они связаны между собой(
да два раза использовать. Попробуйте из одного к другому обращаться через глобальные(global) переменные или триггеры файловые.
А можно на этом пункте подробнее остановиться?
Скажите, а можно как то отправлять в канал в бдном сообщении и текст, и изображение, да так, чтобы урл изображения не отображался. Пробовал в режиме HTML. но там тег <img не поддерживается
нет, никак нельзя, этого телеграм сам по себе не позволяет сделать. Можно отправить картинку + небольшой текст-описание под нее, не более этого.
Привет. Пытаюсь по крону запустить файл, чтоб каждые 10 мин слал сообщение в чат, приходят ошибки, хотя если вручную запускать все работает:
PHP Fatal error: Uncaught exception ‘TelegramBot\Api\HttpException’ with message ‘Bad Request’ in /telegramMonitor/vendor/telegram-bot/api/src/BotApi.php:261
Подскажите, из-за чего может быть такое?
вероятно из-за версии php, но это не точно, пишите разрабам библиотеки telegram/BotApi прямо на гитхаб вот сюда — https://github.com/TelegramBot/Api/issues
полностью вашу проблему. я же не могу ответить в чем может быть ошибка внутри библиотеки бота т.к. сам ее я не писал и даже не форкал.
Доброго времени суток. Подскажите пожалуйста. Как получить id пользователя, отправившего запрос боту?
Например:
$bot->command(‘start’, function ($message) use ($bot) {
…
});
Я не силён в ооп. Поэтому задаю этот, может глупый, вопрос.
примерно так:
вот, я так делаю — http://take.ms/GExUV (скрин)
Здравствуйте! а можете скинуть пример какова нибудь бота! с использованием этой библиотеки! т.е где используются большинства
функций и как правильно реализовывать функционал этой библиотеки! если есть уже у вас готовые боты с данной библиотекой!
тут УЖЕ выложен пример бота
А как сделать чтобы бот мог читать html теги? при отправке сообщения!
Всё сам разобрался!
$bot->sendMessage($message->getChat()->getId(), ‘Раздел продукция!’, ‘HTML’);
А можете дать примеры использования: (editMessageText) (editMessageCaption) (editMessageReplyMarkup) и объяснить всём из отличие!
Не работает пример с Inline кнопками. Я так подозреваю из за того что функции getCallbackQuery в коде бота нет вообще.
хм, ну, если нет, попробуйте дополнить
В общем проблема была в версии php, на debian 7 в репозиториях версия 5.4, вот и composer сказал более старую версию бота, а в ней нет вообще обработки InlineKeyboardMarkup(как и папок в Types).
Обновил php и скачалась свежая версия, после чего пример заработал.
гуд)
Александр, спасибо за шикарные статьи! Ваши маны в закладки однозначно! )) Вопросик есть небольшой, как сделать что-бы при нажатии на кнопку (ReplyKeyboardMarkup) наша кастомная клава не пропадала с экрана? делал как у вас в примерах. Заранее благодарен.
Разобрался короче, может кому пригодится, чтобы кнопки не пропадали, секрет в комментарии
$keyboard = new \TelegramBot\Api\Types\ReplyKeyboardMarkup(array(array(«one», «two», «three»)), true); // true for one-time keyboard
короче, чтобы узнать аргументы такихметодов можете посмотреть на гитхабе в исходники — https://github.com/TelegramBot/Api/blob/master/src/Types/ReplyKeyboardMarkup.php
вот список аргументов на скрине — http://take.ms/42fZd
делаем oneTimeKeyboard = false и клава будет всегда
ture — будет пропадать после тыка по ней.
Александр, а вы не пробовали менять кнопки ReplyKeyboard например в зависимости от полученного ответа? Такое вообще возможно?
да, надо просто отправлять сообщение(можно пустое) с новой replykeyboard
в обработчике команды start создаю $keyboard, вывожу sendMessage-м, всё нормально. Потом создаю таким-же способом $keyboard2, сообщение с разметкой меняется, а кнопки нет ((
$keyset = [
[[«text» => «Today»],[«text» => «Вчера»]],
[[«text» => «Текущий месяц»],[«text» => «Прошлый месяц»]]
];
$keyboard2 = new \TelegramBot\Api\Types\ReplyKeyboardMarkup($keyset, false, true);
$bot->sendMessage($Update->getMessage()->getChat()->getId(), $answer, ‘HTML’, false, false, null, $keyboard2);
ааа! точно, забыл. Короче надо скрывать клаву, да. ща скажу как.
вызываете эту функцию и потом отсылаете keyboard2
не нужен там второй объект клавиатуры ($keyboard2), такое впечатление, как-то с первым нужно работать мне кажется, но пока решения нет.
Да братка, как ты говоришь тоже работает, но лишнее сообщение приходится отсылать. Это я перемудрил с параметрами, лишний false передал. Можно клаву менять и не скрывая, просто новый объект сразу слать и всё.
вот так НЕ ПРАВИЛЬНО:
$bot->sendMessage($Update->getMessage()->getChat()->getId(), $answer, ‘HTML’, false, false, null, $keyboard2);
а вот так ПРАВИЛЬНО:
$bot->sendMessage($Update->getMessage()->getChat()->getId(), $answer, ‘HTML’, false, null, $keyboard2);
гм, ок, гуд
А сессии кто нибудь юзал в ботах? Вычитал такую штуку, что вроде как их не получается использовать в ботах. Как вариант, один немчик свой класс запилил и в мускуле хранит переменные. https://pius-ladenburger.de/blog/2016/03/14/a-session-with-a-telegram-bot/ Может кто лучше выход нашел?
нельзя сессии юзать, надо id юзера сохранять из
$uid = $message->getFrom()->getId();
или сохранять chatid, он тоже для каждого хомяка отдельнй.
Делается база с чатид’ами и настроками прямо там-же, в виде полей или тупа одного большого text поля в которое уже пихается json.
Потом когда надо написать всем этим хомякам инфу — извлекаем из базы все чат-иды и пробегаемся и отправляем инфу в соответствии с настройками.
ага… понял Александр, спасибо! Вот не было печали ))
Нужна помощь, уже второй день не могу понять как тут реализовать казалось бы очень простую задачу: диалоговый ввод?
Например нужно получить 3 строки от пользователя
нажимаем на кнопку ввести данные и бот нас последовательно спрашивает 3 вопроса и запоминает на них ответы, спрашиваю именно про вложенный цикл и последовательный структурированный ввод, что бы можно было либо принять данные(проверить через рег выражение) или отклонить их, что бы нельзя было уйдти в другое меню(кроме /start) просто вбив команду в чат.
Вот так:
1: Как к вам обращаться? (Ответ либо имя либо /start)
Ответ: Иван
2: Сколько вам лет? (Ответ либо число либо /start)
Ответ: 19
3: Введите вашу почту (Ответ либо почта либо /start)
Ответ: [email protected]
Ну и на выходе получить эти 3 значения.
используйте файлы или базу данных. после отправки вопроса типа «Как к вам обращаться?» добавьте в базу запись с uid или с chatid
например так $uid = $message->getFrom()->getId();
дальше человек пишет ответ, например: «иван иванович».
Вам надо проверить есть ли в базе данных соответственно поле с uid отправителя. И если такое поле есть — записать в него имя.
И так со всеми случаями.
Понял, видел как делают многомерное меню, тоже сохраняют последнее действие в БД для каждого юзера, то есть это единственный способ — для каждого ввода нужно делать запрос в БД? Как же такая конструкцию будет работать при большой загруженности.
Спасибо за ответ)
нормально будет работать, базы данных рассчитаны на огромные нагрузки. Они выдержиают по 500 000 запроов в секунду на сайтах с посещалкой ольше 10к рыл в день и ничо не отваливается. А тут маленький бот.
Понятно) Буду думать над реализацией)
А как реализовать «отложенную отправку»? Имею ввиду чтобы после отправки вопроса «Как ваше имя?» и ввода ответа сразу задавался следующий вопрос
тут где-то в комментах был ответ. для этого надо базу делать. И вставлять туда записи последовательно.
Александр, извиняюсь, случайно не встречались с такой ошибкой?
Fatal error: Uncaught exception ‘TelegramBot\Api\HttpException’ with message ‘couldn’t open file «sitename»‘ in /home/u/upswee4g/sitename.ru/public_html/test/revcom_bot/vendor/telegram-bot/api/src/BotApi.php:245 Stack trace: #0 /home/u/upswee4g/sitename.ru/public_html/test/revcom_bot/vendor/telegram-bot/api/src/BotApi.php(212): TelegramBot\Api\BotApi->executeCurl(Array) #1 /home/u/upswee4g/sitename.ru/public_html/test/revcom_bot/vendor/telegram-bot/api/src/BotApi.php(321): TelegramBot\Api\BotApi->call(‘sendMessage’, Array) #2 [internal function]: TelegramBot\Api\BotApi->sendMessage(‘@sitename’, ‘\xD0\xA2\xD0\xB5\xD1\x81\xD1\x82’) #3 /home/u/upswee4g/sitename.ru/public_html/test/revcom_bot/vendor/telegram-bot/api/src/Client.php(405): call_user_func_array(Array, Array) #4 /home/u/upswee4g/sitename.ru/public_html/test/revcom_bot/index.php(24): TelegramBot\Api\Client->__call(‘sendMessage’, Array) #5 /home/u/upswee4g/sitename.ru/public_html/test/revcom_bot/index.php(24): TelegramBot\Api\Client->sendMess in /home/u/upswee4g/sitename.ru/public_html/test/revcom_bot/vendor/telegram-bot/api/src/BotApi.php on line 245
хм, нет, это что-то новое
а в этой библиотеке тип https://core.telegram.org/bots/api#keyboardbutton не поддерживается, как я понял?
список типов поддерживаемых библиотекой можно посмотреть тут https://github.com/TelegramBot/Api/tree/master/src/Types
а для инлайнов тут — https://github.com/TelegramBot/Api/tree/master/src/Types/Inline
Спасибо за исходники! Я новичок в написании ботов. Как я понял нужно загрузить на хостинг с https. Я так и сделал. но у меня не сработало ничего. Шел по инструкции но не получается. Буду благодарен помощи. Спасибо.
хм, тестируйте, у меня тоже были проблемы с доменом. Как вариант, можете статью о боте на C# прочитать, там домен регать не надо и бот может работать прямо с вашего пк.
У меня такая же ошибка выдается
Fatal error: Uncaught Error: Call to undefined function TelegramBot\Api\json_decode() in /home/lessivet/public_html/vladislavgoffman.com/bot/vendor/telegram-bot/api/src/BotApi.php:276 Stack trace: #0 /home/lessivet/public_html/vladislavgoffman.com/bot/vendor/telegram-bot/api/src/BotApi.php(210): TelegramBot\Api\BotApi::jsonValidate(‘{«ok»:true,»res…’, true) #1 /home/lessivet/public_html/vladislavgoffman.com/bot/vendor/telegram-bot/api/src/BotApi.php(415): TelegramBot\Api\BotApi->call(‘setWebhook’, Array) #2 [internal function]: TelegramBot\Api\BotApi->setWebhook(‘https://vladisl…’) #3 /home/lessivet/public_html/vladislavgoffman.com/bot/vendor/telegram-bot/api/src/Client.php(196): call_user_func_array(Array, Array) #4 /home/lessivet/public_html/vladislavgoffman.com/bot/index.php(34): TelegramBot\Api\Client->__call(‘setWebhook’, Array) #5 {main} thrown in /home/lessivet/public_html/vladislavgoffman.com/bot/vendor/telegram-bot/api/src/BotApi.php on line 276
у вас не стоит расширение php_json и, возможно, php_mbstring
погуглите как поставить.
Привет я могу залить этот скрипт в хост и он сразу начинает работать да? после замены токна или сертификат и прочие надо получить?
нужен домен с https, и после заливки сприпта в нем надо удалить файл registered.trigger, а так-же заменить токен. После этого зайти в бота из браузера, напишет «бот». после этого, если https работает то бот начнет работать тоже.
Отличные статьи. Нашёл всё что нужно.
Вопрос.
Есть ли готовый вариант скипта кнопок «лайк» и «дизлайк»?
Очень помогло бы
нет, увы, вам придется вручную решать эту проблему
Да, спасибо, вчера уже нашёл готовый пример и всё сделал 🙂
Нашел, так поделись с единомышленниками
Привет, не могу понять, какой командой удалить кнопку под сообщением. Т.е. я показал юзеру кнопку под сообщением и при определенном событии мне нужно её убрать. Так можно сделать вообще? )
да можно, но надо сохранить id сообщения которое вы отправили, в базе, например отсылаем такое сообщение
далее на другой команде делаем так
Примерно так, думаю вы поймете и разберетесь дальше. К кнопкам это тоже привязывается.В данном случае я вместо базы использовал файл, но лучше вам конечно базу заюзать сразу типа mysql или sqlite хотя-бы
Ок, спасибо ) буду разбираться
Здрасте подскажите, а как можно построить диалог, т.е. есть кнопки они отлавливаются, после нажатия идет уточнение в сообщении как его словить ((, пробовал вот таким кодом
$bot->on(function($Update) use ($bot){
$message = $Update->getMessage();
$mtext = $message->getText();
$cid = $message->getChat()->getId();
if(mb_stripos($mtext,’Информация’) !== false){
$bot->sendMessage($cid, ‘Введите текст для поиска’);
$bot->on(function($Update) use ($bot){
$messageInfo = $Update->getMessage();
$mtextInfo = $message->getText();
$cidInfo = $message->getChat()->getId();
$bot->sendMessage($cidInfo, $mtextInfo);
}, function($messageInfo) use ($name){
return true;
});
}
if(mb_stripos($mtext,’Услуги’) !== false){
$bot->sendMessage($cid, ‘Услуги!’);
}
if(mb_stripos($mtext,’Магазин’) !== false){
$bot->sendMessage($cid, ‘Магазин!’);
}
}, function($message) use ($name){
return true;
});
решено :
хм, спасибо что ответили, может кому пригодится)
А нету ли у Вас расширенного примера как производить оплату при помощи данной библиотеки?
Что-то не получается у меня обработать answerPreCheckoutQuery
увы нет, в десктопную версию телеги оплату пока не завезли так что я разработать не могу и проверить не могу эти механизмы. Планшета и телефона у меня нет
Привет, извините, что отвлекаю, но не подскажите как организовать сбор данных о пользователе через телеграмм бот? Нужно собрать username или телефон пользователя и занести в базу данных. Я PHP начала осваивать недавно, прошу сильно не пинать.
Уже не надо, разобралась сама)
вы можете собирать данные только у тех пользователей, которые находятся в одном чате с ботом. + телефоны никак собрать не получится. используйте объект $message->getFrom()
Телефоны можно собирать через кнопку с запросом номера аккаунта, но пользователь может ее и отклонить
Здравствуйте. Спасибо за замечательный пример. Это мой первый опыт в «бото-написании» причем со скромным опытом в ООП, но получилось установить и настроить с первого раза!
Сам пробую на базе вашего примера написать мини бот для опроса (с ответами типа Да Нет). Опрос — это дерево вопросов, по которому пользователь добирается к результату по одной из веток. Вопросов может быть до 10. Используется анализ ответов в том числе с помощью оператора switch в цикле. Цикл создается внутри блока
$bot->on(function($Update) use ($bot){
….
}, function($message) use ($name){
return true; // когда тут true — команда проходит
});
Проблема в том, что при каждом новом ответе, переменные цикла сбрасываются в начальное значение т.е. проходит только 1 вопрос, который потом постоянно повторяется.
Что вы можете посоветовать.
Прошу прощения за много букв и если отвлекаю от важных дел.
Да, и WM нету. Какие еще варианты для доната?
да, это же php, поэтому все сбрасывается, хехехе
Непривычно, да? PHP это такой язык скрипты которого отрабатывают один раз, а не висят в памяти постоянно. На nodejs, c#,… c++(если на нем можно сделать бота) и прочих классических языках можно создать переменную верхнего уровня и ее значение не будет теряться т.к. программа работает постоянно и может обрабатывать келлбеки. PHP так не может. Советую вам помещать нужныепеременные в файл или базу данных, а в начале каждог оцикла считывать их оттуда. Например можно вот так сделать:
Да, реализовал с файлом. Только имя файла связал с ChatID, потому что чатятся одновременно несколько юзеров и каждому свои значения переменных. Файлы накапливаются с ростом популярности бота. Теперь пытаюсь выкрутить, как удалять файлы для юзеров, у которых чат окончен (прерван).
И еще, подскажите, как с вашей библиотекой можно реализовать очистку истории чата. В АПИ есть messages.deleteHistory(), но что-то ничего не выходит.
Здравствуйте. Прошу вашей помощи. Мне нужно сделать InlineKeyboardMarkup вида: http://site.com/cash?table=. Number занесен в таблицу mysql. Не понимаю как правильно нужно составить запрос…
Здравствуйте. Очень хорошие примеры реализации. Если Вас не затруднит есть два вопроса: как реализовать отправку карты по координатам и возможна ли реализация галереи с загрузкой фотографий постранично (стрелочками вправо-влево).
короче надо юзать кейборд-баттон с типом «request_location»
как-то так
Спасибо огромное за ответ, но я имел ввиду не определение собственного местоположения, а именно вывод карты по координатам, т.е. передал боту параметры latitude и longitude, и получил в ответ карту! Если Вас не сильно напрягаю…
запросто. Юзайте метод sendLocation (вот тут можете его посмотреть — https://github.com/TelegramBot/Api/blob/master/src/BotApi.php)
вот так:
Добрый день! Не перестаю Вас благодарить! Вы очень мне помогли. Простите мне мою наглость, хотел ещё спросить: как сохранять к себе на хостинг фотки и файлы, полученные ботом от пользователей?
вот так
олзо: это отлов из канала сообщений и сохранение фоток в этих сообщениях. Если надо от пользователя, то вместо $cpost = $Update->getChannelPost(); надо сделать $cpost = $Update->getMessage(); должно сработать
Круто! Даже не ожидал так быстро! Спасибо большущее!
Простите пожалуйста, уже месяц бьюсь но никак не могу сделать подключение БД корректно, да так что бы еще пользователям разсылать сообщения 🙁
Например в txt пишем текст, и при вызове он по всем пользователям у кого бот авторизован отсылал…
Заранее огромное спасибо за помощь и долгих лет жизни!
в конец бота ставите. Далее от пользователя пишете боту чо-то, чтобы он в файл uids ваш ид добавил. Далее вызываете в браузере страницу бота + дописываете к адресу ?sendmsg=1 будет примерно так
http://vash_bot/bot/index.php?sendmsg=1 и бот отправит вам сообщение.
А получится сделать с помощью такого бота голосование?
Ну типа 10 вопросов, каждый дает баллы, в конце результат в зависимости от баллов выдается, результатов 5…
Если можно помогите плиз
получится, но надо работать с базой данных или файлами
А нельзя как в примере который чуть выше, где с udid? Приведите пожалста пример если можно 🙁
Или может как то без записи результатов, по идее бд может и не нужна?
Тогда еще вопрос, может быть поможете прикрутить к нему онлайн оплату? 🙂 не могу сообразить никак
Всем добрый вечер )
Мог бы кто помочь с отложенным постингом сообщения юзеру?
Суть дилемы такова, что не знаю как все разрешить относительно команд бота.
Прилагаю кусок который нужно засунуть в какую-то функцию бота, что бы он проверял его время от времени.
$query_time_post = $conn->query(‘SELECT timetopost FROM post WHERE timetopost IS NOT NULL’);
$text_query = $conn->query(«SELECT textpost FROM post WHERE WHERE timetopost = ‘$query_time_post'»);
$text_post = $text_query->fetch_row();
$posting_in_channel = $query_time_post->fetch_row();
$time_in_db = gmdate(‘h:i:s’,time());
if($time_in_db == reset($posting_in_channel)){
$bot->sendMessage($message->getChat->getId(),reset($text_post));
}
короче: создаешь пользователю дату постинга в его записи в таблице, у тебя она уже есть, это timetopost
потом на cron вешаешь обработчик, который будет вызывать страницу бота с get параметром, типа ?send_await=1
и долбишь раз в 5-10 секунд этот адрес.
Ну и еще вот тут timetopost < '$query_time_post';
Уважаемый Автор!
Выше вы писали как отправлять сообщения пользователям, с помощью id в файле uids
Так вот вопрос, как к этому прикрутить Реакции? (лайк и пр.), но так что бы у всех обновлялось кол-во?
Например мини опрос и тп.
Спасибо за труды 🙂
вам надо отправлять вместе с сообщением $keyboard, то есть клавиатуру с кнопками. Можете тут пост поискать у меня на блоге о том как отправлять кнопки ботом, ща, вот — http://aftamat4ik.ru/bot-dlya-telegram-na-php-knopki-posting-inline-queryes/
добавляете к сообщению кнопки, обрабатываете их. В случае с лайками вам надо будет еще обновлять клавиатуру, там метод есть для этого в API — editMessageReplyMarkup называется, он позволяет менять кнопки под сообщением, например, добавляя лайки.
Честно говоря я далека от тонкостей 🙁 Только изучаю php и толком ничего не понимаю…
Попробовала как вы говорите, кнопка появилась но не засчитывается нажатия (цифра), не говоря уже об обновлении у всех пользователей 🙁
подскажите пожалуйста какой цикл жизни у chat_ID? нето при попытке рассылки сообщений ботом людям которые к нему не обращались больше 7 дней получаю ошибку:
Fatal error: Uncaught exception ‘TelegramBot\Api\HttpException’ with message ‘Forbidden’ in /home/bzzwuser/public_html/vendor/telegram-bot/api/src/BotApi.php:261 Stack trace: #0 /home/bzzwuser/public_html/vendor/telegram-bot/api/src/BotApi.php(241): TelegramBot\Api\BotApi::curlValidate(Resource id #9) #1 /home/bzzwuser/public_html/vendor/telegram-bot/api/src/BotApi.php(210): TelegramBot\Api\BotApi->executeCurl(Array) #2 /home/bzzwuser/public_html/vendor/telegram-bot/api/src/BotApi.php(317): TelegramBot\Api\BotApi->call(‘sendMessage’, Array) #3 [internal function]: TelegramBot\Api\BotApi->sendMessage(‘204769608’, ‘\xD0\x92\xD1\x8B \xD0\xB7\xD0\xB0\xD0\xBD\xD1\x8F\xD0\xBB…’) #4 /home/bzzwuser/public_html/vendor/telegram-bot/api/src/Client.php(196): call_user_func_array(Array, Array) #5 /home/bzzwuser/public_html/daily_reward.php(69): TelegramBot\Api\Client->__call(‘sendMessage’, Array) #6 /home/bzzwuser/public_html/daily_reward.php(69): TelegramBot\Api\Client->sendMessage(‘204769608’, ‘\xD0\x92\xD1\x8B \xD0\xB7\xD0\xB0\xD in /home/bzzwuser/public_html/vendor/telegram-bot/api/src/BotApi.php on line 261
при том я на одном человеке проверил chat_id не меняется
все разобрался. просто эти пользователи выключили бота… а как делать обработку чтобы проверить без фатал эррора таких пользователей?
try {
$bot->sendchataction(336269625,’typing’);
}
catch (Exception $e) {
echo $e->getmessage();
}
if (mb_stripos($e,»Forbidden») !== false) {
echo «в топку эту запись!»;
}
Ифом обрабатываем запись и и где получаем ошибку или удаляем из базы данных или ставим метку что человек выключил бота, вдруг потом включит обратно и его данные пригодятся ему в будущем. Периодически хроном или вручную запускаем эту проверку чтобы отфильтровать мертвых пользователей из базы.
Доброго времени суток, Aftamat4ik.
Так и не нашёл метод возвращающий имя пользователя, который подключился к боту.
Есть ли вообще такая возможность в данной библиотеке, если нет, то какой лучше использовать?
Есть $message->getFrom()->getUsername()
остальные методы смотрите тут — https://github.com/TelegramBot/Api/blob/master/src/Types/User.php
Привет! Полезная статья, спасибо!
А как сделать кнопки с emoji (http://www.unicode.org/emoji/charts/full-emoji-list.html)
И как их потом отлавливать?
берете в телеграме нужный емоджи вот так — http://take.ms/zBoQs
нажимаете Ctrl+C потом вставляете в редактор. Там оно не отобразится, но если сохраните и отравите сообщение в телеграм через sendMessage то там емоджи отобразится.
Добрый вечер. Подскажите пожалуйста. Можно ли в сообщении от бота слать отформатированный html ем текст, картинки, ссылки и прочее. Хочу красиво оформить постинг в канале, но бот не понимает разметку и шлёт текстом.
Отправлял с помощью
if($_POST[‘ver’]){
$soobshen = ‘…….’;
$bot->sendMessage($id, «$soobshen»);
};
Заранее спасибо!
да, запросто
Здравствуйте еще раз. не могу наладить замену инлайн кнопок. получаю ошибку:
[11-Apr-2018 08:56:32 UTC] PHP Fatal error: Uncaught exception ‘TelegramBot\Api\HttpException’ with message ‘Bad Request’ in /home/bzzwuser/public_html/vendor/telegram-bot/api/src/BotApi.php:261
Stack trace:
#0 /home/bzzwuser/public_html/vendor/telegram-bot/api/src/BotApi.php(241): TelegramBot\Api\BotApi::curlValidate(Resource id #11)
#1 /home/bzzwuser/public_html/vendor/telegram-bot/api/src/BotApi.php(210): TelegramBot\Api\BotApi->executeCurl(Array)
#2 /home/bzzwuser/public_html/vendor/telegram-bot/api/src/BotApi.php(1002): TelegramBot\Api\BotApi->call(‘editMessageText’, Array)
#3 [internal function]: TelegramBot\Api\BotApi->editMessageReplyMarkup(336269625, 26400, Object(TelegramBot\Api\Types\Inline\InlineKeyboardMarkup))
#4 /home/bzzwuser/public_html/vendor/telegram-bot/api/src/Client.php(196): call_user_func_array(Array, Array)
#5 /home/bzzwuser/public_html/index.php(303): TelegramBot\Api\Client->__call(‘editMessageRepl…’, Array)
#6 /home/bzzwuser/public_html/index.php(303): TelegramBot\Api\Client->editMessageReplyMarkup(336269625, 26400, Object( in /home/bzzwuser/public_html/vendor/telegram-bot/api/src/BotApi.php on line 261
код выдающий ошибку взят из статьи и просто добавлены две строчки:
$keyboard = new \TelegramBot\Api\Types\Inline\InlineKeyboardMarkup(
[[[‘callback_data’ => ‘data_test2’, ‘text’ => ‘ОтветЪ’],[‘callback_query’ => ‘data_test’, ‘text’ => ‘новая кнопка!!!!!’]]]);
$bot->editMessageReplyMarkup($chatId, $message->getMessageId(),$keyboard);
все разобрался) нужно было обновить с гитхаба апи.
Ребят помогите как сделать request_contact добавить кнопку в бот, чтобы клиент мог отправить мне свои контакт!
Был один бот работал все норм, сменил токен, теперь не тот и не тот не работает
Помогите
важна привязка вебхука. перепривяжите его.
igor
Я так и не понял как вывести имя пользователя при входе в бот.
Можно показать на вашем примере?
Тут:
$bot->command(‘start’, function ($message) use ($bot) {
$answer = «Добро пожаовать»;
апи смотрите просто, вот например тут — https://github.com/TelegramBot/Api/blob/master/src/Types/User.php
Чёт не пашет
Пример не рабочий.
Подскажите пожалуйста на этом примере,как вывести имя пользователя при входе в бот?
Спасибо.
$message->getFrom()->getFirstName() — имя, остальное смотрите тут — https://github.com/TelegramBot/Api/blob/master/src/Types/User.php
И что за $cid?
А как проверить то что пользователь присоединился к каналу ?
когда это происходит срабатывает команда /start
Здравствуйте! Спасибо огромное за статьи! Подскажите, пожалуйста, возможно ли получать результат нажатия (callback) клавиши Inline клавиатуры, прицепленной к сообщению, отправленному моим ботом в канал? Если возможно, то подскажите, пожалуйста, как? К сожалению, у меня это не получилось.