
Подробнее о хостинге для размещения Телеграм бота можно узнать из статьи
Авторизуйтесь через Telegram, чтобы ответить.
Откройте бот @SiteAuthBot,
нажмите кнопку Старт/Start. Следуйте инструкциям бота.
if(!$orderRaw['status']) {
// готовим кнопку для перехода в Яндекс.Деньги
$url = $this->getUrl($total, $user_id, $orderRaw['id']);
$buttons[] = [ $this->buildInlineKeyBoardButton('Оплатить через Яндекс.Деньги', '', $url),
$this->buildInlineKeyBoardButton('При отправлении Наличными', 'getNal_' . $orderRaw['id']),
$this->buildInlineKeyBoardButton('При отправлении Сканирование QR-Кода Яндекс.Деньги', 'getQrYandex_' . $orderRaw['id']),
];
} else {
// если заказ оплачен то уведомляем
$text .= "n<b>Заказ оплачен</b>n";
}
Нашел я в index.php
private function getText($data)
{
if ($this->getType($data) == "callback_query") {
return $data['callback_query']['data'];
}
return $data['message']['text'];
}
Скопировал кусок, вставил в обработчик, результат тот же, абсолютно. таймер висит и все.
public function getNal($data)
{
// Получаем id заказа через данные от кнопки
$param = explode("_", $data['data']);
$order_id = $param[1];
if ($this->getNal($data) == "callback_query") {
return $data['callback_query']['data'];
}
// Далее логика - например записать в бд
// что этот заказ будет оплачен наличными,
// выслать инструкцию ...
}
public function getQrYandex($data)
{
// Получаем id заказа через данные от кнопки
$param = explode("_", $data['data']);
$order_id = $param[1];
if ($this->getQrYandex($data) == "callback_query") {
return $data['callback_query']['data'];
}
// Далее логика - например записать в бд
// что этот заказ будет оплачен наличными,
// выслать инструкцию ...
}
Есть какое, то решение этой проблемы? С примером текстового сообщения который можно заменить после клика на кнопку оплата наличными, типа "Спасибо" и тд.
private function startBot($chat_id, $data)
{
// ...
$buttons_first[] = [
$this->buildKeyboardButton("Кабинет"),
$this->buildKeyboardButton("Помощь"),
];
// отправляем первый набор кнопок
$this->sendMessage($chat_id, "...", $buttons_first, true);
// отправляем привет
$this->sendMessage($chat_id, $text, $buttons);
}
Все супер, все работает, шикарно, спасибо большое, но вот такой вопрос, а как продублировать кнопки во второй ряд?
private function startBot($chat_id, $data)
{
// ...
$buttons_first[] = [
$this->buildKeyboardButton("Кабинет"),
$this->buildKeyboardButton("Помощь"),
];
$buttons_twice[] = [
$this->buildKeyboardButton("Кабинет"),
$this->buildKeyboardButton("Помощь"),
];
// отправляем первый набор кнопок
$this->sendMessage($chat_id, "...", $buttons_first, $buttons_twice, true);
// отправляем привет
$this->sendMessage($chat_id, $text, $buttons);
}
Вытекающий из кнопок клавиатуры вопрос, как прикрутить к кнопкам функции?https://habr.com/ru/company/netologyru/blog/326174/
, взял от туда код кнопок
}elseif ($text == "Картинка") {
$url = "https://68.media.tumblr.com/6d830b4f2c455f9cb6cd4ebe5011d2b8/tumblr_oj49kevkUz1v4bb1no1_500.jpg";
$telegram->sendPhoto([ 'chat_id' => $chat_id, 'photo' => $url, 'caption' => "Описание." ]);
}elseif ($text == "Гифка") {
$url = "https://68.media.tumblr.com/bd08f2aa85a6eb8b7a9f4b07c0807d71/tumblr_ofrc94sG1e1sjmm5ao1_400.gif";
$telegram->sendDocument([ 'chat_id' => $chat_id, 'document' => $url, 'caption' => "Описание." ]);
public function getNal($data)
{
// Получаем id заказа через данные от кнопки
$param = explode("_", $data['data']);
$order_id = $param[1];
// 1. Вы пытаетесь вызвать рекурсию getNal в getNal == бесконечность в вашем варианте
// 2. $data это массив, и $this->getNal($data) == "callback_query" вернет false,
// поэтому это условие никогда не сработает
// 3. В $data['callback_query']['data'] нет такого ключа в $data
// в $data уже лежит объект ['callback_query']
// Если вам нужно значение из элемента data то оно у нас уже в $param в виде массива
// if ($this->getNal($data) == "callback_query") {
// return $data['callback_query']['data'];
// }
// Для теста вы можете просто вызвать Уведомление
// answerCallbackQuery это позволяет
$this->notice($data['id'], "Обработка inline-кнопки getNal", true);
}
public function getQrYandex($data)
{
$this->notice($data['id'], "Обработка inline-кнопки getQrYandex", true);
}
private function startBot($chat_id, $data)
{
// ...
$buttons_first = [
[
$this->buildKeyboardButton("Кабинет"),
$this->buildKeyboardButton("Помощь"),
],
[
$this->buildKeyboardButton("Кабинет 1"),
$this->buildKeyboardButton("Помощь 1"),
],
];
// или
// $buttons_first[0] = [
// $this->buildKeyboardButton("Кабинет"),
// $this->buildKeyboardButton("Помощь"),
// ];
// $buttons_first[1] = [
// $this->buildKeyboardButton("Кабинет 1"),
// $this->buildKeyboardButton("Помощь 1"),
// ];
// отправляем первый набор кнопок
$this->sendMessage($chat_id, "...", $buttons_first, true);
// ...
}
private function router($data) {
// ...
// если это пришел старт бота
if ($text == "/start") {
$this->startBot($chat_id, $data);
} elseif ($text == "Кабинет") {
// либо вывести информацию здесь, либо вызвать метод который отработает по сценарию
$this->sendMessage($chat_id, "Выводим кабинет");
// $this->showCabinet($chat_id, $data);
// выводим страницу только админу
} elseif ($text == "/admin" && $this->isAdmin($chat_id)) {
// ...
}
private function showCabinet($chat_id, $data) {
$this->sendMessage($chat_id, "Выводим кабинет");
}
if (array_key_exists("text", $data['message'])) {
// ...
$buttons[] = [
$this->buildInlineKeyBoardButton('Другой чат', '', 'https://t.me/imakebots'),
$this->buildInlineKeyBoardButton('Документ', 'sendDocToUser_0')
];
$this->sendMessage($chat_id, 'Выберите действие', $buttons);
// ...
private function sendDocToUser($data) {
// отсылаем уведомление
$this->notice($data['id']);
// отсылаем документ
$this->botApiQuery('sendDocument', [
'chat_id' => $this->getChatId($data),
'document' => 'http://www.pdf995.com/samples/pdf.pdf'
]);
}
http://skrinshoter.ru/s/280619/wDfue06F?a
как видно из скриншота, кнопки не понимают команды, если не сложно можно решение этой проблемы?
// Статья 4 - Оплата в Телеграмм
/********************************************/
if(!$orderRaw['status']) {
// готовим кнопку для перехода в Яндекс.Деньги
$url = $this->getUrl($total, $user_id, $orderRaw['id']);
$buttons[] = [ $this->buildInlineKeyBoardButton('Оплатить через Яндекс.Деньги', '', $url),
$this->buildInlineKeyBoardButton('Оплата Наличными', 'getNal_' . $orderRaw['id']),
$this->buildInlineKeyBoardButton('При получении Сканирование QR-Кода Яндекс.Деньги', 'getQrYandex_' . $orderRaw['id']),
];
} else {
// если заказ оплачен то уведомляем
$text .= "n<b>Заказ оплачен</b>n";
}
/********************************************/
сейчас у вас как видно из скриншота появляется всплывающее окошко, http://skrinshoter.ru/s/280619/Zt0fYnAP?a
я имел ввиду что после клика по инлайнкнопкам "Оплата Наличными" и тд., пользователь получает текстовое уведомление в чат по аналогии с вашим способом оплаты по умолчанию через яндекс деньги и текущий заказ после клика на "Оплата Наличными" был закрыт// если заказ оплачен то уведомляем
$text .= "n<b>Заказ оплачен</b>n";
Сейчас просто всплывает окошко и непонятно, прошел заказ, не прошел заказ, он просто висит на шаге выбора оплаты с кнопками туда/сюда - ни админ, ни пользователь ничего не получают, это так и должно быть? private function router($data)
Я приводил пример выше постом для кнопки клавиатуры "Кабинет", вам нужно просто добавить свои условия:} elseif ($text == "ℹ️Кнопка 1") {
} elseif ($text == "💬Чат с поддержкой") {
Фразы в условиях должны быть один в один как на кнопках.public function getNal($data)
{
// высылаем уведомление без сообщения, чтобы
// Телеграм понял что мы получили команду от кнопки
$this->notice($data['id']);
// отправляем сообщение
$chat_id = $this->getChatId($data);
$this->sendMessage($chat_id, "Заказ оплачен");
}
private function sendDocToUser($data) {
// отсылаем уведомление
$this->notice($data['id']);
// отсылаем документ
$this->botApiQuery('sendDocument', [
'chat_id' => $this->getChatId($data),
'document' => 'http://www.pdf995.com/samples/pdf.pdf'
]);
}
то все выводиться нормальноhttp://skrinshoter.ru/s/290619/EOfeyAIw?a
, но если подставить свои данныеhttps://pastebin.com/yE2jR7L9
https://pastebin.com/xLZ7c5wa
то уже отображается по другомуhttp://skrinshoter.ru/s/290619/1qRO2KuS?a
также ссылки на документ автоматически стали выводиться при создании заказа сами по себеhttp://skrinshoter.ru/s/290619/5mMHyNyl?a
как решить эти моменты? и как сделать переход в другой чат по клику на кнопку (сейчас он присылает ссылку на чат, если нажать кнопку).// Статья 4 - Оплата в Телеграмм
/********************************************/
if(!$orderRaw['status']) {
// готовим кнопку для перехода в Яндекс.Деньги
$url = $this->getUrl($total, $user_id, $orderRaw['id']);
$buttons[] = [ $this->buildInlineKeyBoardButton('Оплатить через Яндекс.Деньги', '', $url),
$this->buildInlineKeyBoardButton('Оплата Наличными', 'getNal_' . $orderRaw['id']),
$this->buildInlineKeyBoardButton('При получении Сканирование QR-Кода Яндекс.Деньги', 'getQrYandex_' . $orderRaw['id']),
];
} else {
// если заказ оплачен то уведомляем
$text .= "n<b>Заказ оплачен</b>n";
}
/********************************************/
Спасибо, тоже все работает, но момент вот такой, как реализовать информирование админа (любое, простейшее) хоть в сам телеграм, хоть на почту, хоть еще куда), о том что заказ поступил? Потому что сейчас никаких уведомлений админу не поступает и не понятно есть заказ, нет заказа, существует он вообще. В случае с оплаты через яндекс деньги, реализованной вами по умолчанию, там хотя бы уведомление придет о тому, что поступил платеж на почту, а вообще в целом такие уведомления не приходят, а в случаях если пользователь делая заказ выбрал оплату наличными это очень критично, потому что это довольно казусная ситуация когда человек сидит и чего-то ждет, а о его заказе никто ни слуху ни духу как говориться. можно вариант решения этой незатейливой проблемы? Спасибо. $this->botApiQuery('sendDocument', [
'chat_id' => $this->getChatId($data),
'document' => 'http://www.pdf995.com/samples/pdf.pdf'
]);
====== /** Оформляем заказ
* @param $data
*/
private function setReady($data)
{
// ...
// удаляем из корзины
$delBasket = $this->pdo->prepare("DELETE FROM bot_shop_basket WHERE user_id = :user_id");
$delBasket->execute(['user_id' => $user_id]);
// уведомляем админа
$this->sendMessage($this->admin, "Новый заказ поступил - №" . $parent_id);
// переадресовать в личный кабинет
$this->notice($data['id']);
$this->userLc($user_id, $data['message']['message_id']);
// ...
}
https://pastebin.com/v09tQiB4
http://skrinshoter.ru/s/280619/Q92pXBLC?a
И как сделать так чтоб каждая запись, присваивалась своему полю?http://skrinshoter.ru/s/280619/15Wbgunl?a
а как сделать так чтоб после полей "телефон" и "адрес", можно было добавить к примеру поле "комментарий к заказу" (введите комментарий и тд.) следующим шагом и/или другие поля, свои поля (к примеру, поле1, поле2 и тд.)? Можно какой нибудь шаблон который можно копипастить заменяя "поле1" на свое какое нибудь поле? Спасибо.
$text_ .= "nТелефон: " . $text;
$text_ .= "nnАдрес: ";
$text_ .= "nnnНовое поле 1:";
$text_ .= "nnnnНовое поле 2:";
$text_ .= "nnnnnНовое поле 3:";
$text_ .= "nnnnnnНовое поле 4:";
я так понимаю что в данном случае лишнии n можно убрать? они как отступ выступают или как перенос на новую строку?CREATE TABLE IF NOT EXISTS 'данные о платежных системах' (
'id' int(11) NOT NULL AUTO_INCREMENT,
'name' varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
'getNal_' varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
'getQrYandex_' varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY ('id')
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
} elseif (preg_match("~^step_1_phone$~", $actionUser)) {
// если ждем данные для добавления телефона
$this->savePhoneUser($text, $data);
} elseif (preg_match("~^step_2_adress$~", $actionUser)) {
// если ждем данные для добавления адреса
$this->saveAdressUser($text, $data);
} elseif (preg_match("~^step_3_newfield1$~", $actionUser)) {
// если ждем данные для добавления адреса
$this->savenewfield1User($text, $data);
} elseif (preg_match("~^step_4_newfield2$~", $actionUser)) {
// если ждем данные для добавления адреса
$this->savenewfield2User($text, $data);
} elseif (preg_match("~^step_5_newfield3$~", $actionUser)) {
// если ждем данные для добавления адреса
$this->savenewfield3User($text, $data);
} elseif (preg_match("~^step_6_newfield4$~", $actionUser)) {
// если ждем данные для добавления адреса
$this->savenewfield4User($text, $data);
private function insertnewfield1($user_id, $data)
{
$text = "<b>Оформление заказа</b>nn";
// сумма заказа
$text .= "Сумма заказа: " . $this->totalSumOrder($user_id) . " рублей";
$text_ .= "nТелефон: " . $phone->fetch()['phone'];
$text_ .= "nАдрес: " . $adress->fetch()['adress'];
// инструкция
$text .= "nnУкажите свой телефон в формате 79001234567:";
// отправляем данные
$this->botApiQuery("editMessageText", [
'chat_id' => $user_id,
'text' => $text,
'message_id' => $this->getMessageId($data),
'parse_mode' => 'html',
]);
// глушим уведомление
$this->notice($data['id']);
}
private function saveAdressUser($text, $data)
{
$user_id = $this->getChatId($data);
// Достаем телефон
$phone = $this->pdo->prepare("SELECT phone FROM bot_shop_profile WHERE user_id = :user_id");
$phone->execute(['user_id' => $user_id]);
if ($this->setActionUser("step_7_ready", $user_id)) {
if ($this->setParamUser('adress', $text, $user_id)) {
$text_ = "<b>Оформление заказа</b>nn";
// сумма заказа
$text_ .= "Сумма заказа: " . $this->totalSumOrder($user_id) . " рублей";
// телефон
$text_ .= "nТелефон: " . $phone->fetch()['phone'];
$text_ .= "nАдрес для доставки: " . $text;
$buttons[][] = $this->buildInlineKeyBoardButton('✔ Готово', 'setReady_0');
} else {
$text_ = "Ошибка попробуйте снова /start";
}
} else {
$text_ = "Ошибка попробуйте еще раз";
}
// готовим данные
$data_send = [
'chat_id' => $user_id,
'text' => $text_,
'parse_mode' => 'html',
];
// если есть кнопки добавляем
if (is_array($buttons)) {
$data_send['reply_markup'] = $this->buildInlineKeyBoard($buttons);
}
// отправляем запрос
$this->botApiQuery("sendMessage", $data_send);
}
Это правильный код?private function saveReceiveName($user_id, $data)
{
$user_id = $this->getChatId($data);
// Достаем телефон
$phone = $this->pdo->prepare("SELECT phone FROM bot_shop_profile WHERE user_id = :user_id");
$phone->execute(['user_id' => $user_id]);
// Достаем адрес
$adress = $this->pdo->prepare("SELECT adress FROM bot_shop_profile WHERE user_id = :user_id");
$adress->execute(['user_id' => $user_id]);
if ($this->setActionUser("step_3_receivename", $user_id)) {
if ($this->setParamUser('receivename', $text, $user_id)) {
$text_ = "Оформление заказа\n\n";
// сумма заказа
$text_ .= "Сумма заказа: " . $this->totalSumOrder($user_id) . " рублей";
// телефон
$text_ .= "\nТелефон отправителя: " . $phone->fetch()['phone'];
$text_ .= "\nАдрес отправителя: " . $adress->fetch()['adress'];
$text_ .= "\nИмя получателя: " . $text;
} else {
$text_ = "Ошибка попробуйте снова /start";
}
} else {
$text_ = "Ошибка попробуйте еще раз";
}
} else {
$text_ = "Ошибка в веденных данных, попробуйте еще раз.\n\nУкажите имя получателя в формате Имя и Фамилия:";
}
$this->botApiQuery("sendMessage", [
'chat_id' => $user_id,
'text' => $text_,
'parse_mode' => 'html',
]);
// отправляем запрос
$this->botApiQuery("sendMessage", $data_send);
}
private function saveAdressUser($text, $data) {
$user_id = $this->getChatId($data);
// Достаем телефон
$phone = $this->pdo->prepare("SELECT phone FROM bot_shop_profile WHERE user_id = :user_id");
$phone->execute(['user_id' => $user_id]);
// !!!!!!!!!!!!!!!!!!
// устанавливаем пользователю следующий шаг ДЛЯ НОВОГО ПОЛЯ 1
if ($this->setActionUser("step_3_newfield1", $user_id)) {
// если удалось сохранить адрес
if ($this->setParamUser('adress', $text, $user_id)) {
// готовим текст сообщения
$text_ = "<b>Оформление заказа</b>nn";
// сумма заказа
$text_ .= "Сумма заказа: " . $this->totalSumOrder($user_id) . " рублей";
// телефон
$text_ .= "nТелефон: " . $phone->fetch()['phone'];
$text_ .= "nАдрес для доставки: " . $text;
// !!!!!!!!!!!!!!!!!!
// кнопки здесь не нужны, нужно сделать запрос данных
// >> Затем 4 раза повторить данный код?
// нет того кода повторять не надо - все запросы нужно делать после проверки предудущих значений
// !!!!!!!!!!!!!!!!!!
$text_ .= "nnУкажите данные для нового поля 1";
// $buttons[][] = $this->buildInlineKeyBoardButton('✔ Готово', 'setReady_0');
} else {
$text_ = "Ошибка попробуйте снова /start";
}
} else {
$text_ = "Ошибка попробуйте еще раз";
}
// готовим данные
$data_send = [
'chat_id' => $user_id,
'text' => $text_,
'parse_mode' => 'html',
];
// если есть кнопки добавляем
if (is_array($buttons)) {
$data_send['reply_markup'] = $this->buildInlineKeyBoard($buttons);
}
// отправляем запрос
$this->botApiQuery("sendMessage", $data_send);
}
private function step_3_newfield1($text, $data) {
$user_id = $this->getChatId($data);
// Достаем данные
$data = $this->pdo->prepare("SELECT phone, adress FROM bot_shop_profile WHERE user_id = :user_id");
$data->execute(['user_id' => $user_id]);
$data_ = $data->fetch();
if ($this->setActionUser("step_4_newfield2", $user_id)) {
if ($this->setParamUser('receivename', $text, $user_id)) {
$text_ = "Оформление заказаnn";
// сумма заказа
$text_ .= "Сумма заказа: " . $this->totalSumOrder($user_id) . " рублей";
// телефон
$text_ .= "nТелефон отправителя: " . $data_['phone'];
// адрес
$text_ .= "nАдрес отправителя: " . $data_['adress'];
// присланное значение для поля 1
$text_ .= "nИмя получателя: " . $text;
// запрос данных для поля 2
$text_ .= "nnУкажите данные для нового поля 2";
} else {
$text_ = "Ошибка попробуйте снова /start";
}
} else {
$text_ = "Ошибка попробуйте еще раз";
}
$this->botApiQuery("sendMessage", [
'chat_id' => $user_id,
'text' => $text_,
'parse_mode' => 'html',
]);
}
https://pastebin.com/1eAW77aF
https://pastebin.com/Gz9PCwG0
// Оформляем заказ
private function setReady($data){
$user_id = $this->getChatId($data);
$basket = $this->pdo->prepare("SELECT * FROM bot_shop_basket WHERE user_id = :user_id");
$basket->execute(['user_id' => $user_id]);
$user = $this->pdo->prepare("SELECT * FROM bot_shop_profile WHERE user_id = :user_id");
$user->execute(['user_id' => $user_id]);
if ($basket->rowCount() > 0) {
$userInfo = $user->fetch();
$inOrder = $this->pdo->prepare("INSERT INTO bot_shop_order SET user_id = :user_id, date = NOW(), status = 0, name = :name, phone = :phone, adress = :adress, comm = :comm");
if ($inOrder->execute([
'user_id' => $user_id,
'name' => trim($userInfo['first_name'] . " " . $userInfo['last_name']),
'phone' => $userInfo['phone'],
'adress' => $userInfo['adress'],
'comm' => $userInfo['comm'],
])) {
$parent_id = $this->pdo->lastInsertId();
while ($item = $basket->fetch()) {
$inOrderProduct = $this->pdo->prepare("INSERT INTO bot_shop_order_product SET parent_id = :parent_id, product_id = :product_id,product_count = :product_count");
$inOrderProduct->execute(['parent_id' => $parent_id, 'product_id' => $item['product_id'], 'product_count' => $item['product_count']]);
}
$delBasket = $this->pdo->prepare("DELETE FROM bot_shop_basket WHERE user_id = :user_id");
$delBasket->execute(['user_id' => $user_id]);
$this->sendMessage($this->admin, "<b>Поступил новый заказ - №" . $parent_id . "</b>nn<i>Общая сумма: </i>₸n<i>Пользователь: </i><b>".$userInfo['first_name']." ".$userInfo['last_name']."</b>n<i>Адрес: </i><b>".$userInfo['adress']."</b>n<i>Телефон: </i><b>".$userInfo['phone']."</b>n<i>Комментарий: </i><b>".$userInfo['comm']."</b>"); // уведомляем админа
$this->notice($data['id']);
$this->userLc($user_id, $data['message']['message_id']);
} else {
$this->notice($data['id'], "Ошибка_", true);
}
} else {
$this->notice($data['id'], "Ошибка", true);
}
}
И было бы очень здорово показать весь заказ клиенту, перед тем, как он его подтвердит, а вдруг чего-то забыл... private function addProductPhoto($category, $product, $file_id){
$checkHref = $this->pdo->prepare("SELECT * FROM bot_shop_product_temp WHERE id = :id"); // запрос на проверку есть ли такая временная запись товара в базе
$checkHref->execute(['id' => $product]); // выполняем запрос
if ($checkHref->rowCount() !== 0) { // если вернулось ноль строк
$photo = $this->getPhoto($file_id); // получаем картинку
if ($photo) {
$insert = $this->pdo->prepare("INSERT INTO bot_shop_product SET parent = :parent, name = :name, description = :description, price = :price, unit = :unit, image_tlg = :image_tlg, image = :image, hide = 1"); // Добавляем в основную таблицу новый товар
$item = $checkHref->fetch(); // достаем временные данные
$array = [ // готовим данные
'parent' => $category,
'name' => $item['name'],
'description' => $item['description'],
'price' => $item['price'],
'unit' => $item['unit'],
'image_tlg' => $file_id,
'image' => $photo];
if ($insert->execute($array)) { // если удалось добавить товар
$this->cleareTempProduct(); //очищаем временную таблицу
$this->adminActionCancel(); // очищаем действия админа
$catName = $this->pdo->prepare("SELECT name FROM bot_shop_category WHERE id = :id"); // название категории
$catName->execute(['id' => $category]);
$fields = $this->prepareCategory($catName->fetch()['name'], $category); // выводим список товаров
$this->botApiQuery("sendMessage", $fields); // обновляем сообщение - выводим список товаров
} else {$this->sendMessage($this->admin, "Ошибка при добавлении товара img0");
$buttons[] = [$this->buildInlineKeyBoardButton("Отменить", "addProductCancel_" . $category . "_" . $product),];}
} else {$this->sendMessage($this->admin, "Ошибка при добавлении товара img1");
$buttons[] = [$this->buildInlineKeyBoardButton("Отменить", "addProductCancel_" . $category . "_" . $product),];}
} else {$this->sendMessage($this->admin, "Ошибка при добавлении товара img2");
$buttons[] = [$this->buildInlineKeyBoardButton("Отменить", "addProductCancel_" . $category . "_" . $product),];}
}
private function getPhoto($file_id){
$file_path = $this->getPhotoPath($file_id); // получаем file_path
return $this->copyPhoto($file_path); // возвращаем результат загрузки фото
}
private function getPhotoPath($file_id){
$array = $this->botApiQuery("getFile", ['file_id' => $file_id]); // получаем объект File
return $array['result']['file_path']; // возвращаем file_path
}
private function copyPhoto($file_path){
$file_from_tgrm = "https://api.telegram.org/file/bot" . $this->token . "/" . $file_path; // ссылка на файл в телеграме
$ext = end(explode(".", $file_path)); // достаем расширение файла
$name_our_new_file = $this->img_path . "/" . time() . "." . $ext; // назначаем свое имя - время_в_секундах.расширение_файла
return copy($file_from_tgrm, $name_our_new_file) ? $name_our_new_file : false; // возвращаем путь картинки или false
}
версия php 7.4.4, но ведь работало же... Ранее загруженные картинки выводятся нормально, а новые загружаться не хотят... в какую сторону копать?
// Было
private function copyPhoto($file_path){
$file_from_tgrm = "https://api.telegram.org/file/bot" . $this->token . "/" . $file_path;
$ext = end(explode(".", $file_path));
$name_our_new_file = $this->img_path . "/" . time() . "." . $ext;
return copy($file_from_tgrm, $name_our_new_file) ? $name_our_new_file : false;
}
// Исправлено
private function copyPhoto($file_path){
$file_from_tgrm = "https://api.telegram.org/file/bot" . $this->token . "/" . $file_path;
$expl = explode(".", $file_path);
$ext = end($expl);
$name_our_new_file = $this->img_path . "/" . time() . "." . $ext;
return copy($file_from_tgrm, $name_our_new_file) ? $name_our_new_file : false;
}
пришлось добавить переменную $expl. да и по мелочи... чел.фак. так сказать... :)$inline_keyboard = [[$inline_button1,$inline_button2,$inline_button3],[$inline_button4,$inline_button5,$inline_button6],[$inline_button7,$inline_button8,$inline_button9],[$inline_button10,$inline_button11,$inline_button12],[$inline_button13,$inline_button14,$inline_button15],[$inline_button16,$inline_button17,$inline_button18],[$inline_button19,$inline_button20,$inline_button21],[$inline_button22,$inline_button23,$inline_button24]];
$buttons[] = [
$this->buildInlineKeyBoardButton($row['name'], "showCategory_" . $row['id']),
$this->buildInlineKeyBoardButton($row['name'], "showCategory_" . $row['id']),
$this->buildInlineKeyBoardButton($row['name'], "showCategory_" . $row['id']),
];
в таком виде у меня просто дублируются 3 колонки. $this->buildInlineKeyBoardButton(($row['name'], "showUserCategory_" . $row['id']),($row['name'], "showUserCategory_" . $row['id'])),
<?php
$arr = [1,2,3,4,5,6,7,8,9,0];
$new_arr = [];
$row = 0;
foreach($arr as $key => $val) {
if($key % 3 == 0) {
$row += 1;
}
$new_arr[$row][] = $val;
}
echo "<pre>";
print_r($new_arr);
Вопрос 1
Метод - обработчик можно ставить в любое место, но если у вас это будет логически связанное место с другими подобными методами, легче потом искать.
Таймер появляется если от Телеграм ушел на вебхук запрос, то должна быть какая-то реакция-результат от обработчика - вот он и ждет. Например какой-то текст, картинка или промежуточный sendChatAction ("печатает текст" или "отправляет фото" ...).
Также на каждое нажатие inline-кнопки обязательно нужно реагировать отправляя answerCallbackQuery - то есть уведомить Телеграм, что запрос от inline-кнопки пришел, в противном случае Телеграм будет слать повторные запросы, по своему расписанию (через 2 сек, 1 мин, 5 мин, 30 мин ...) пока не получит answerCallbackQuery, это даже если вы уже по своему сценарию все сделали и продолжаете работу, то фоном эти запросы все равно будут приходить.
Вопрос 2
Вместе с сообщением можно отправить только один набор объектов в reply_markup:
1. InlineKeyboardMarkup
2. ReplyKeyboardMarkup
3. ReplyKeyboardRemove
4. ForceReply.
В типовом приложении из статьи при старте отправляется набор объектов inline-кнопок с сылками на категории товаров. Добавить в сообщение еще один набор объектов не получиться, но вы можете отправить перед этим сообщение например с текстом "..." и приложить необходимый набор объектов с клавиатурой.
И для этого надо обновить метод sendMessage