get31 Posted July 25 Report Share Posted July 25 Доброго времени суток! Решил попробовать сделать добавление пользователя (ID, username, имя) в БД после нажатия на /start в боте Телеграм Делаю следующее: 1. В БД s_users добавляем telegram_id и username ALTER TABLE `s_users` ADD COLUMN `telegram_id` BIGINT DEFAULT NULL; ALTER TABLE `s_users` ADD COLUMN `username` VARCHAR(255) DEFAULT NULL; 2. В api/Users.php в функции get_users и get_user добавим u.username, u.telegram_id, Далее в конце файла добавим: // Добавление пользователя по Telegram ID public function add_telegram_user($telegram_id, $username, $first_name, $last_name) { $user = new stdClass(); $user->telegram_id = $telegram_id; $user->username = $username; $user->name = $first_name . ' ' . $last_name; // Проверка, существует ли пользователь с таким telegram_id $existing_user = $this->get_user_by_telegram_id($telegram_id); if (!$existing_user) { $query = $this->db->placehold("INSERT INTO __users SET ?%", $user); $this->db->query($query); return $this->db->insert_id(); } else { return $existing_user->id; } } // Получение пользователя по Telegram ID public function get_user_by_telegram_id($telegram_id) { $query = $this->db->placehold("SELECT * FROM __users WHERE telegram_id=?", $telegram_id); $this->db->query($query); return $this->db->result(); } 3. В api/Simpla.php подключим 'usertelegram' => 'UserTelegram', 4. Создадим файл в api/UserTelegram.php с содержимым <?php class UserTelegram extends Simpla { private $salt = '8e86a279d6e182b3c811c559e6b15484'; public function __construct() { parent::__construct(); } public function addUser($user) { $user = (array) $user; // Хэширование пароля if (isset($user['password'])) { $user['password'] = md5($this->salt . $user['password'] . md5($user['password'])); } // Проверка существования пользователя $query = $this->db->placehold("SELECT count(*) as count FROM __users WHERE email=?", $user['email']); $this->db->query($query); if ($this->db->result('count') > 0) { return false; // Пользователь уже существует } // Вставка нового пользователя $query = $this->db->placehold("INSERT INTO __users SET ?%", $user); $this->db->query($query); $insertId = $this->db->insert_id(); if ($insertId) { return $insertId; // Успешно добавлен } else { return false; // Не удалось добавить } } // Пример метода для обновления пользователя public function updateUser($id, $user) { $user = (array) $user; if (isset($user['password'])) { $user['password'] = md5($this->salt . $user['password'] . md5($user['password'])); } $query = $this->db->placehold("UPDATE __users SET ?% WHERE id=? LIMIT 1", $user, intval($id)); $this->db->query($query); return $id; } // Пример метода для получения пользователя public function getUser($id) { if (gettype($id) == 'string') { $where = $this->db->placehold(' WHERE u.email=? ', $id); } else { $where = $this->db->placehold(' WHERE u.id=? ', intval($id)); } $query = $this->db->placehold("SELECT u.id, u.email, u.password, u.name, u.telegram_id, u.username, u.group_id, u.enabled, u.last_ip, u.last_date, u.created, g.discount, g.name as group_name FROM __users u LEFT JOIN __groups g ON u.group_id=g.id $where LIMIT 1", $id); $this->db->query($query); $user = $this->db->result(); if (empty($user)) { return false; } $user->discount *= 1; return $user; } } 5. В view/UserView.php добавим везде где нужно telegram_id и username $telegram_id = $this->request->post('telegram_id'); $username = $this->request->post('username'); $this->design->assign('tg_channel', $tg_channel); $this->design->assign('telegram_id', $telegram_id); Но не работает. Подскажите, пожалуйста, что я забыл сделать и что нужно изменить? Quote Link to post Share on other sites
sergeevizh Posted July 25 Report Share Posted July 25 Для авторизации и регистрации есть официальный виджет от Telegram https://core.telegram.org/widgets/login На счет кода, нужен webhook который будет получать команды от бота и в зависимости от пришедших данных решать, что ему делать. Записать данные пользователя: имя, аватар, телефон. И в ответ отправить ссылку для авторизации с записью кук в браузер. Quote Link to post Share on other sites
get31 Posted July 25 Author Report Share Posted July 25 1 час назад, alexivchenko сказал: Для авторизации и регистрации есть официальный виджет от Telegram https://core.telegram.org/widgets/login На счет кода, нужен webhook который будет получать команды от бота и в зависимости от пришедших данных решать, что ему делать. Записать данные пользователя: имя, аватар, телефон. И в ответ отправить ссылку для авторизации с записью кук в браузер. Мне не нужна авторизация через https://core.telegram.org/widgets/login Мне нужно просто добавить в БД. вебхук добавить не проблема (https://api.telegram.org/botТОКЕН/setWebhook?url=https://site.com/bot.php), проблема стала в коде.... Quote Link to post Share on other sites
sergeevizh Posted July 25 Report Share Posted July 25 10 минут назад, get31 сказал: Мне не нужна авторизация через https://core.telegram.org/widgets/login Мне нужно просто добавить в БД. вебхук добавить не проблема (https://api.telegram.org/botТОКЕН/setWebhook?url=https://site.com/bot.php), проблема стала в коде.... Код вебхука какой? Quote Link to post Share on other sites
shooroop Posted July 25 Report Share Posted July 25 откуда в коде у вас взялся email если телега хук передает имя и id ..... Quote Link to post Share on other sites
get31 Posted July 26 Author Report Share Posted July 26 8 часов назад, alexivchenko сказал: Код вебхука какой? ага, то есть вебхук нужен. Его нужно отдельно в файл или подключить в api/UserTelegram.php? Если я не буду отправлять сообщения пользователю, типа "спасибо, ваши данные добавлены" и пр текст, то вебхук все равно нужен? Quote Link to post Share on other sites
get31 Posted July 26 Author Report Share Posted July 26 6 часов назад, shooroop сказал: откуда в коде у вас взялся email если телега хук передает имя и id ..... согласен, перебор, но не ошибка Quote Link to post Share on other sites
sergeevizh Posted July 26 Report Share Posted July 26 6 часов назад, shooroop сказал: откуда в коде у вас взялся email если телега хук передает имя и id ..... Откуда взялся, понятное дело, скопирован класс api/Users.php без изменения кода под задачу. Я вот спрашиваю код вебхука у ТС, чтобы понять, есть у него проверка ответа бота на нажатие кнопки «/start» или по барабану, чтобы пользователь не прислал будет новая запись в базу. Quote Link to post Share on other sites
sergeevizh Posted July 26 Report Share Posted July 26 4 минуты назад, get31 сказал: ага, то есть вебхук нужен. Его нужно отдельно в файл или подключить в api/UserTelegram.php? Если я не буду отправлять сообщения пользователю, типа "спасибо, ваши данные добавлены" и пр текст, то вебхук все равно нужен? Конечно, вебхук нужен обязательно. Логика должна быть такая: 1. Вебхук получает данные из бота 2. Отправляет данные в api/UsersTelegram.php 3. В api/UsersTelegram.php проверяем, что была нажата кнопка «/start», если что-то другое, то молчим. После фильтра берем из ответа Id пользователя и проверяем есть ли запись о нем. Если есть, отправляем пользователю сообщение «Ваши данные уже есть в базе», а если записи нет, то записываем в базу и отправляем сообщение «Спасибо, ваши данные добавлены». Quote Link to post Share on other sites
shooroop Posted July 26 Report Share Posted July 26 2 часа назад, get31 сказал: согласен, перебор, но не ошибка одна из ошибок у вас идет проверка на выбор пользователей по емайлу из бд. а у вас в таблице будут только id и имя соответственно если даже таблица будет с записями то вернет пустоту. логику вам описал Алекс Quote Link to post Share on other sites
get31 Posted July 26 Author Report Share Posted July 26 1 минуту назад, shooroop сказал: одна из ошибок у вас идет проверка на выбор пользователей по емайлу из бд. а у вас в таблице будут только id и имя соответственно если даже таблица будет с записями то вернет пустоту. логику вам описал Алекс Да, я потом заметил и уже заменил у себя в коде $query = $this->db->placehold("SELECT count(*) as count FROM __users WHERE telegram_id=?", $user['telegram_id']); Спасибо. Я теперь завис на вебхуке.....типа отдельный файл нужен? Получается тогда код в api/UsersTelegram.php полностью менять нужно? А по логике Алекса тогда изменения в api/Users.php вообще не нужны.....шото бошка уже не варит.... Quote Link to post Share on other sites
sergeevizh Posted July 26 Report Share Posted July 26 (edited) 17 минут назад, get31 сказал: Да, я потом заметил и уже заменил у себя в коде $query = $this->db->placehold("SELECT count(*) as count FROM __users WHERE telegram_id=?", $user['telegram_id']); Спасибо. Я теперь завис на вебхуке.....типа отдельный файл нужен? Получается тогда код в api/UsersTelegram.php полностью менять нужно? А по логике Алекса тогда изменения в api/Users.php вообще не нужны.....шото бошка уже не варит.... api/Users.php нужен только для вывода данный в профиле пользователя или в админке. api/UsersTelegram.php нужен для фильтрации данных, проверки и записи данных пользователя из Телеграмм. Edited July 26 by alexivchenko Quote Link to post Share on other sites
shooroop Posted July 26 Report Share Posted July 26 8 часов назад, get31 сказал: Да, я потом заметил и уже заменил у себя в коде $query = $this->db->placehold("SELECT count(*) as count FROM __users WHERE telegram_id=?", $user['telegram_id']); Спасибо. Я теперь завис на вебхуке.....типа отдельный файл нужен? Получается тогда код в api/UsersTelegram.php полностью менять нужно? А по логике Алекса тогда изменения в api/Users.php вообще не нужны.....шото бошка уже не варит.... да вебхук нужен там все просто как и сказал Алекс получаемый запрос мы фильтруем делая проверку и если событие произошло записываем данные в бд Quote Link to post Share on other sites
get31 Posted August 1 Author Report Share Posted August 1 Сегодня снова сел делать, создал вебхук...но все равно почему-то не добавляет пользователя в БД Вот новый код api/UsersTelegram.php: <?php require_once('Simpla.php'); require_once('Users.php'); class UsersTelegram extends Simpla { private $botToken = 'ТУТ_TOKEN_TELEGRAM'; private $webhookUrl; private $users; public function __construct() { parent::__construct(); $this->users = new Users(); $this->setWebhookUrl(); $this->setWebhook(); $this->handleRequest(); } private function setWebhookUrl() { // Определяем полный URL вебхука $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http'; $host = $_SERVER['HTTP_HOST']; $scriptName = $_SERVER['SCRIPT_NAME']; $this->webhookUrl = "$protocol://$host$scriptName"; } private function sendRequest($method, $data) { $url = "https://api.telegram.org/bot" . $this->botToken . "/" . $method; $options = [ 'http' => [ 'header' => "Content-type: application/x-www-form-urlencoded\r\n", 'method' => 'POST', 'content' => http_build_query($data), ], ]; $context = stream_context_create($options); $response = file_get_contents($url, false, $context); return json_decode($response, true); } private function setWebhook() { // Проверяем наличие текущего вебхука $webhookInfo = $this->sendRequest('getWebhookInfo', []); if ($webhookInfo['ok']) { $currentUrl = $webhookInfo['result']['url']; if ($currentUrl !== $this->webhookUrl) { // Если URL вебхука не совпадает с требуемым, устанавливаем новый $response = $this->sendRequest('setWebhook', ['url' => $this->webhookUrl]); if ($response['ok']) { echo "Вебхук успешно установлен."; } else { echo "Ошибка установки вебхука: " . $response['description']; } } else { echo "Вебхук уже установлен и корректен."; } } else { echo "Ошибка получения информации о вебхуке: " . $webhookInfo['description']; } } private function handleRequest() { $input = file_get_contents('php://input'); $update = json_decode($input, true); if (isset($update['message']['text']) && $update['message']['text'] === '/start') { $telegram_id = $update['message']['from']['id']; $username = $update['message']['from']['username']; // Определяем IP пользователя $ip = !empty($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']); // Проверяем, существует ли пользователь $existing_user = $this->users->get_user_by_telegram_id($telegram_id); if ($existing_user) { // Пользователь уже есть в базе данных $response = 'Ваши данные уже есть в базе'; } else { // Добавляем нового пользователя в базу данных $userData = [ 'id' => $telegram_id, 'email' => $telegram_id, 'password' => $telegram_id, 'name' => $username, // Используем имя пользователя в Telegram 'group_id' => '0', 'enabled' => '1', 'created' => date('Y-m-d H:i:s'), 'telegram_id' => $telegram_id, 'username' => $username ]; $user_id = $this->users->add_user($userData); if ($user_id) { $response = 'Спасибо, ваши данные добавлены'; } else { $response = 'Ошибка добавления данных в базу'; } } // Отправляем ответ пользователю $url = "https://api.telegram.org/bot" . $this->botToken . "/sendMessage"; $data = [ 'chat_id' => $telegram_id, 'text' => $response ]; $options = [ 'http' => [ 'header' => "Content-type: application/x-www-form-urlencoded\r\n", 'method' => 'POST', 'content' => http_build_query($data), ], ]; $context = stream_context_create($options); file_get_contents($url, false, $context); } } } // Создаем экземпляр класса new UsersTelegram(); ?> Хз на сколько правильно и нужно ли подключать к api/Users.php, но думал подключить чтобы проще было может добавлять пользователя, хотя по факту добавляю все равно через api/UsersTelegram.php В api/Users.php делаем проверку на telegram_id public function get_user_by_telegram_id($telegram_id) { $query = $this->db->placehold("SELECT * FROM __users WHERE telegram_id=? LIMIT 1", $telegram_id); $this->db->query($query); return $this->db->result(); } в api/Simpla..php подключаем 'userstelegram' => 'UsersTelegram', на счет него тоже хз, поскольку нигде не задействую userstelegram Quote Link to post Share on other sites
sergeevizh Posted August 2 Report Share Posted August 2 (edited) В 01.08.2024 в 15:41, get31 сказал: Сегодня снова сел делать, создал вебхук...но все равно почему-то не добавляет пользователя в БД Вот новый код api/UsersTelegram.php: <?php require_once('Simpla.php'); require_once('Users.php'); class UsersTelegram extends Simpla { private $botToken = 'ТУТ_TOKEN_TELEGRAM'; private $webhookUrl; private $users; public function __construct() { parent::__construct(); $this->users = new Users(); $this->setWebhookUrl(); $this->setWebhook(); $this->handleRequest(); } private function setWebhookUrl() { // Определяем полный URL вебхука $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http'; $host = $_SERVER['HTTP_HOST']; $scriptName = $_SERVER['SCRIPT_NAME']; $this->webhookUrl = "$protocol://$host$scriptName"; } private function sendRequest($method, $data) { $url = "https://api.telegram.org/bot" . $this->botToken . "/" . $method; $options = [ 'http' => [ 'header' => "Content-type: application/x-www-form-urlencoded\r\n", 'method' => 'POST', 'content' => http_build_query($data), ], ]; $context = stream_context_create($options); $response = file_get_contents($url, false, $context); return json_decode($response, true); } private function setWebhook() { // Проверяем наличие текущего вебхука $webhookInfo = $this->sendRequest('getWebhookInfo', []); if ($webhookInfo['ok']) { $currentUrl = $webhookInfo['result']['url']; if ($currentUrl !== $this->webhookUrl) { // Если URL вебхука не совпадает с требуемым, устанавливаем новый $response = $this->sendRequest('setWebhook', ['url' => $this->webhookUrl]); if ($response['ok']) { echo "Вебхук успешно установлен."; } else { echo "Ошибка установки вебхука: " . $response['description']; } } else { echo "Вебхук уже установлен и корректен."; } } else { echo "Ошибка получения информации о вебхуке: " . $webhookInfo['description']; } } private function handleRequest() { $input = file_get_contents('php://input'); $update = json_decode($input, true); if (isset($update['message']['text']) && $update['message']['text'] === '/start') { $telegram_id = $update['message']['from']['id']; $username = $update['message']['from']['username']; // Определяем IP пользователя $ip = !empty($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']); // Проверяем, существует ли пользователь $existing_user = $this->users->get_user_by_telegram_id($telegram_id); if ($existing_user) { // Пользователь уже есть в базе данных $response = 'Ваши данные уже есть в базе'; } else { // Добавляем нового пользователя в базу данных $userData = [ 'id' => $telegram_id, 'email' => $telegram_id, 'password' => $telegram_id, 'name' => $username, // Используем имя пользователя в Telegram 'group_id' => '0', 'enabled' => '1', 'created' => date('Y-m-d H:i:s'), 'telegram_id' => $telegram_id, 'username' => $username ]; $user_id = $this->users->add_user($userData); if ($user_id) { $response = 'Спасибо, ваши данные добавлены'; } else { $response = 'Ошибка добавления данных в базу'; } } // Отправляем ответ пользователю $url = "https://api.telegram.org/bot" . $this->botToken . "/sendMessage"; $data = [ 'chat_id' => $telegram_id, 'text' => $response ]; $options = [ 'http' => [ 'header' => "Content-type: application/x-www-form-urlencoded\r\n", 'method' => 'POST', 'content' => http_build_query($data), ], ]; $context = stream_context_create($options); file_get_contents($url, false, $context); } } } // Создаем экземпляр класса new UsersTelegram(); ?> Хз на сколько правильно и нужно ли подключать к api/Users.php, но думал подключить чтобы проще было может добавлять пользователя, хотя по факту добавляю все равно через api/UsersTelegram.php В api/Users.php делаем проверку на telegram_id public function get_user_by_telegram_id($telegram_id) { $query = $this->db->placehold("SELECT * FROM __users WHERE telegram_id=? LIMIT 1", $telegram_id); $this->db->query($query); return $this->db->result(); } в api/Simpla..php подключаем 'userstelegram' => 'UsersTelegram', на счет него тоже хз, поскольку нигде не задействую userstelegram В api/Users.php нужно добавить только новые поля где будут данные из Телеграмм, для вывода их пользователю и больше эту модель трогать не нужно. Для реализации вашей идеи вот ссылка https://imakebots.ru/article/avtorizaciya-na-sayt-cherez-telegram-bez-ispolzovaniya-oficialnogo-vidzheta Сделайте для начала как написано, потом по аналогии для Simpla. Сразу напишу, для вхождения у вас должно быть: 1. site.ru/bot.php - webhook 2. site.ru/api/UsersTelegram.php - данные из webhook больше ничего не нужно. Edited August 2 by alexivchenko Quote Link to post Share on other sites
get31 Posted August 3 Author Report Share Posted August 3 (edited) 12 часов назад, alexivchenko сказал: В api/Users.php нужно добавить только новые поля где будут данные из Телеграмм, для вывода их пользователю и больше эту модель трогать не нужно. Для реализации вашей идеи вот ссылка https://imakebots.ru/article/avtorizaciya-na-sayt-cherez-telegram-bez-ispolzovaniya-oficialnogo-vidzheta Сделайте для начала как написано, потом по аналогии для Simpla. Сразу напишу, для вхождения у вас должно быть: 1. site.ru/bot.php - webhook 2. site.ru/api/UsersTelegram.php - данные из webhook больше ничего не нужно. Спасибо. Я вот не понял для чего KEY? Он мне не нужен получается, поскольку я не авторизую пользователя, а добавляю в БД нужные данные, верно? Edited August 3 by get31 Quote Link to post Share on other sites
sergeevizh Posted August 3 Report Share Posted August 3 1 час назад, get31 сказал: Спасибо. Я вот не понял для чего KEY? Он мне не нужен получается, поскольку я не авторизую пользователя, а добавляю в БД нужные данные, верно? Все верно, ключ нужен только для проверки, что пользователь есть в базе и авторизовать его. Quote Link to post Share on other sites
get31 Posted August 3 Author Report Share Posted August 3 (edited) 2 часа назад, alexivchenko сказал: Все верно, ключ нужен только для проверки, что пользователь есть в базе и авторизовать его. нам нужно 2 файла в корень кидаем webHook.php без изменений <?php // определим кодировку UTF-8 header("HTTP/1.1 200 OK"); header('Content-type: text/html; charset=utf-8'); // подключаем класс авторизации require_once("api/UsersTelegram.php"); // создаем объект авторизации $auth = new Auth(); // запускаем $auth->init(); ?> в api/UsersTelegram.php пишу вот так: <?php require_once('Simpla.php'); class UsersTelegram extends Simpla { // Токен API BOT private $token = "___TYT___TOKEN____"; public function __construct() { parent::__construct(); // Вызов конструктора родительского класса, если он есть } /** Инициализируем работу класса * @return bool */ public function init() { // Получаем данные от API и преобразуем их в ассоциативный массив $rawData = json_decode(file_get_contents('php://input'), true); // Направляем данные из бота в метод для определения дальнейших действий $this->router($rawData); // В любом случае возвращаем true для API Bot return true; } /** Роутер * @param $data array * @return bool */ private function router($data) { // Проверяем на объект Message if (array_key_exists("message", $data)) { // Получаем чат $chat_id = $data['message']['chat']['id']; // Проверяем на наличие объекта Text if (array_key_exists("text", $data['message'])) { // Получаем значение отправленных данных $text = $data['message']['text']; // Если это просто старт бота if ($text == "/start") { // Отправляем сообщение $this->botApiQuery("sendMessage", [ 'chat_id' => $chat_id, 'text' => 'Бот авторизации' ]); // Передаем данные пользователя в метод для добавления в БД $this->addUserToDatabase($data['message']); } else { // Просто пишем чего-нибудь в чат $this->botApiQuery("sendMessage", [ 'chat_id' => $chat_id, 'text' => 'Неизвестная команда' ]); } } else { // Просто пишем чего-нибудь в чат $this->botApiQuery("sendMessage", [ 'chat_id' => $chat_id, 'text' => 'Неизвестный формат сообщения' ]); } } // Другие объекты не рассматриваем return true; } /** Добавление пользователя в БД * @param $message array */ private function addUserToDatabase($message) { // Инициализация класса Users для работы с БД $users = new Users(); // Подготовка данных пользователя $user = [ 'telegram_id' => $message['chat']['id'], 'username' => $message['chat']['username'] ]; // Проверяем, существует ли пользователь с таким telegram_id $existingUser = $users->get_user($user['telegram_id']); if ($existingUser) { // Если пользователь существует, можно обновить данные или просто проигнорировать $text = "Вы уже зарегистрированы."; } else { // Если пользователь не существует, добавляем нового $userId = $users->add_user($user); if ($userId) { $text = "Вы успешно зарегистрированы."; } else { $text = "Произошла ошибка при регистрации."; } } // Отправляем сообщение пользователю $this->botApiQuery("sendMessage", [ 'chat_id' => $message['chat']['id'], 'text' => $text ]); } /** Работаем с API BOT * @param $method * @param array $fields * @return mixed */ private function botApiQuery($method, $fields = array()) { $ch = curl_init('https://api.telegram.org/bot' . $this->token . '/' . $method); curl_setopt_array($ch, array( CURLOPT_POST => count($fields), CURLOPT_POSTFIELDS => http_build_query($fields), CURLOPT_SSL_VERIFYPEER => 0, CURLOPT_RETURNTRANSFER => 1, CURLOPT_TIMEOUT => 10 )); $r = json_decode(curl_exec($ch), true); curl_close($ch); return $r; } } ?> в боте нажимаю /start и данные не добавляются в БД(((( Edited August 3 by get31 Quote Link to post Share on other sites
sergeevizh Posted August 4 Report Share Posted August 4 21 час назад, get31 сказал: нам нужно 2 файла в корень кидаем webHook.php без изменений <?php // определим кодировку UTF-8 header("HTTP/1.1 200 OK"); header('Content-type: text/html; charset=utf-8'); // подключаем класс авторизации require_once("api/UsersTelegram.php"); // создаем объект авторизации $auth = new Auth(); // запускаем $auth->init(); ?> в api/UsersTelegram.php пишу вот так: <?php require_once('Simpla.php'); class UsersTelegram extends Simpla { // Токен API BOT private $token = "___TYT___TOKEN____"; public function __construct() { parent::__construct(); // Вызов конструктора родительского класса, если он есть } /** Инициализируем работу класса * @return bool */ public function init() { // Получаем данные от API и преобразуем их в ассоциативный массив $rawData = json_decode(file_get_contents('php://input'), true); // Направляем данные из бота в метод для определения дальнейших действий $this->router($rawData); // В любом случае возвращаем true для API Bot return true; } /** Роутер * @param $data array * @return bool */ private function router($data) { // Проверяем на объект Message if (array_key_exists("message", $data)) { // Получаем чат $chat_id = $data['message']['chat']['id']; // Проверяем на наличие объекта Text if (array_key_exists("text", $data['message'])) { // Получаем значение отправленных данных $text = $data['message']['text']; // Если это просто старт бота if ($text == "/start") { // Отправляем сообщение $this->botApiQuery("sendMessage", [ 'chat_id' => $chat_id, 'text' => 'Бот авторизации' ]); // Передаем данные пользователя в метод для добавления в БД $this->addUserToDatabase($data['message']); } else { // Просто пишем чего-нибудь в чат $this->botApiQuery("sendMessage", [ 'chat_id' => $chat_id, 'text' => 'Неизвестная команда' ]); } } else { // Просто пишем чего-нибудь в чат $this->botApiQuery("sendMessage", [ 'chat_id' => $chat_id, 'text' => 'Неизвестный формат сообщения' ]); } } // Другие объекты не рассматриваем return true; } /** Добавление пользователя в БД * @param $message array */ private function addUserToDatabase($message) { // Инициализация класса Users для работы с БД $users = new Users(); // Подготовка данных пользователя $user = [ 'telegram_id' => $message['chat']['id'], 'username' => $message['chat']['username'] ]; // Проверяем, существует ли пользователь с таким telegram_id $existingUser = $users->get_user($user['telegram_id']); if ($existingUser) { // Если пользователь существует, можно обновить данные или просто проигнорировать $text = "Вы уже зарегистрированы."; } else { // Если пользователь не существует, добавляем нового $userId = $users->add_user($user); if ($userId) { $text = "Вы успешно зарегистрированы."; } else { $text = "Произошла ошибка при регистрации."; } } // Отправляем сообщение пользователю $this->botApiQuery("sendMessage", [ 'chat_id' => $message['chat']['id'], 'text' => $text ]); } /** Работаем с API BOT * @param $method * @param array $fields * @return mixed */ private function botApiQuery($method, $fields = array()) { $ch = curl_init('https://api.telegram.org/bot' . $this->token . '/' . $method); curl_setopt_array($ch, array( CURLOPT_POST => count($fields), CURLOPT_POSTFIELDS => http_build_query($fields), CURLOPT_SSL_VERIFYPEER => 0, CURLOPT_RETURNTRANSFER => 1, CURLOPT_TIMEOUT => 10 )); $r = json_decode(curl_exec($ch), true); curl_close($ch); return $r; } } ?> в боте нажимаю /start и данные не добавляются в БД(((( Ну как-то так: 1. в корень кидаем webHook.php <?php // определим кодировку UTF-8 header("HTTP/1.1 200 OK"); header('Content-type: text/html; charset=utf-8'); // подключаем класс авторизации require_once("api/UsersTelegram.php"); // создаем объект авторизации $auth = new UsersTelegram(); // запускаем $auth->init(); ?> 2. Нужно зарегистрировать WebHook https://api.telegram.org/botВАШ_ТОКЕН/setwebhook?url=https://ВАШ_ДОМЕН/webHook.php 3. в api/UsersTelegram.php <?php require_once('Simpla.php'); class UsersTelegram extends Simpla { // Токен API BOT private $token = "___TYT___TOKEN____"; public function __construct() { parent::__construct(); // Вызов конструктора родительского класса, если он есть } /** Инициализируем работу класса * @return bool */ public function init() { // Получаем данные от API и преобразуем их в ассоциативный массив $rawData = json_decode(file_get_contents('php://input'), true); // Направляем данные из бота в метод для определения дальнейших действий $this->router($rawData); // В любом случае возвращаем true для API Bot return true; } /** Роутер * @param $data array * @return bool */ private function router($data) { // Проверяем на объект Message if (array_key_exists("message", $data)) { // Получаем чат $chat_id = $data['message']['chat']['id']; // Проверяем на наличие объекта Text if (array_key_exists("text", $data['message'])) { // Получаем значение отправленных данных $text = $data['message']['text']; // Если это просто старт бота if ($text == "/start") { // Отправляем сообщение $this->botApiQuery("sendMessage", [ 'chat_id' => $chat_id, 'text' => 'Бот авторизации' ]); // Передаем данные пользователя в метод для добавления в БД $this->addUserToDatabase($data['message']); } else { // Просто пишем чего-нибудь в чат $this->botApiQuery("sendMessage", [ 'chat_id' => $chat_id, 'text' => 'Неизвестная команда' ]); } } else { // Просто пишем чего-нибудь в чат $this->botApiQuery("sendMessage", [ 'chat_id' => $chat_id, 'text' => 'Неизвестный формат сообщения' ]); } } // Другие объекты не рассматриваем return true; } /** Добавление пользователя в БД * @param $message array */ private function addUserToDatabase($message) { // Подготовка данных пользователя $user = [ 'telegram_id' => $message['chat']['id'], 'username' => $message['chat']['username'] ]; // Проверяем, существует ли пользователь с таким telegram_id $existingUser = $this->getUser($user['telegram_id']); if ($existingUser) { // Если пользователь существует, можно обновить данные или просто проигнорировать $text = "Вы уже зарегистрированы."; } else { // Если пользователь не существует, добавляем нового $userId = $this->addUser($user); if ($userId) { $text = "Вы успешно зарегистрированы."; } else { $text = "Произошла ошибка при регистрации."; } } // Отправляем сообщение пользователю $this->botApiQuery("sendMessage", [ 'chat_id' => $message['chat']['id'], 'text' => $text ]); } private function getUser($id) { // Выбираем пользователя $query = $this->db->placehold("SELECT * FROM __users WHERE telegram_id=? LIMIT 1", $id); $this->db->query($query); $user = $this->db->result(); if (empty($user)) { return false; } return $user; } private function addUser($user) { $user = (array)$user; $query = $this->db->placehold("INSERT INTO __users SET ?%", $user); $this->db->query($query); return $this->db->insert_id(); } /** Работаем с API BOT * @param $method * @param array $fields * @return mixed */ private function botApiQuery($method, $fields = array()) { $ch = curl_init('https://api.telegram.org/bot' . $this->token . '/' . $method); curl_setopt_array($ch, array( CURLOPT_POST => count($fields), CURLOPT_POSTFIELDS => http_build_query($fields), CURLOPT_SSL_VERIFYPEER => 0, CURLOPT_RETURNTRANSFER => 1, CURLOPT_TIMEOUT => 10 )); $r = json_decode(curl_exec($ch), true); curl_close($ch); return $r; } } ?> Quote Link to post Share on other sites
get31 Posted August 4 Author Report Share Posted August 4 43 минуты назад, alexivchenko сказал: Ну как-то так: 1. в корень кидаем webHook.php <?php // определим кодировку UTF-8 header("HTTP/1.1 200 OK"); header('Content-type: text/html; charset=utf-8'); // подключаем класс авторизации require_once("api/UsersTelegram.php"); // создаем объект авторизации $auth = new UsersTelegram(); // запускаем $auth->init(); ?> 2. Нужно зарегистрировать WebHook https://api.telegram.org/botВАШ_ТОКЕН/setwebhook?url=https://ВАШ_ДОМЕН/webHook.php 3. в api/UsersTelegram.php <?php require_once('Simpla.php'); class UsersTelegram extends Simpla { // Токен API BOT private $token = "___TYT___TOKEN____"; public function __construct() { parent::__construct(); // Вызов конструктора родительского класса, если он есть } /** Инициализируем работу класса * @return bool */ public function init() { // Получаем данные от API и преобразуем их в ассоциативный массив $rawData = json_decode(file_get_contents('php://input'), true); // Направляем данные из бота в метод для определения дальнейших действий $this->router($rawData); // В любом случае возвращаем true для API Bot return true; } /** Роутер * @param $data array * @return bool */ private function router($data) { // Проверяем на объект Message if (array_key_exists("message", $data)) { // Получаем чат $chat_id = $data['message']['chat']['id']; // Проверяем на наличие объекта Text if (array_key_exists("text", $data['message'])) { // Получаем значение отправленных данных $text = $data['message']['text']; // Если это просто старт бота if ($text == "/start") { // Отправляем сообщение $this->botApiQuery("sendMessage", [ 'chat_id' => $chat_id, 'text' => 'Бот авторизации' ]); // Передаем данные пользователя в метод для добавления в БД $this->addUserToDatabase($data['message']); } else { // Просто пишем чего-нибудь в чат $this->botApiQuery("sendMessage", [ 'chat_id' => $chat_id, 'text' => 'Неизвестная команда' ]); } } else { // Просто пишем чего-нибудь в чат $this->botApiQuery("sendMessage", [ 'chat_id' => $chat_id, 'text' => 'Неизвестный формат сообщения' ]); } } // Другие объекты не рассматриваем return true; } /** Добавление пользователя в БД * @param $message array */ private function addUserToDatabase($message) { // Подготовка данных пользователя $user = [ 'telegram_id' => $message['chat']['id'], 'username' => $message['chat']['username'] ]; // Проверяем, существует ли пользователь с таким telegram_id $existingUser = $this->getUser($user['telegram_id']); if ($existingUser) { // Если пользователь существует, можно обновить данные или просто проигнорировать $text = "Вы уже зарегистрированы."; } else { // Если пользователь не существует, добавляем нового $userId = $this->addUser($user); if ($userId) { $text = "Вы успешно зарегистрированы."; } else { $text = "Произошла ошибка при регистрации."; } } // Отправляем сообщение пользователю $this->botApiQuery("sendMessage", [ 'chat_id' => $message['chat']['id'], 'text' => $text ]); } private function getUser($id) { // Выбираем пользователя $query = $this->db->placehold("SELECT * FROM __users WHERE telegram_id=? LIMIT 1", $id); $this->db->query($query); $user = $this->db->result(); if (empty($user)) { return false; } return $user; } private function addUser($user) { $user = (array)$user; $query = $this->db->placehold("INSERT INTO __users SET ?%", $user); $this->db->query($query); return $this->db->insert_id(); } /** Работаем с API BOT * @param $method * @param array $fields * @return mixed */ private function botApiQuery($method, $fields = array()) { $ch = curl_init('https://api.telegram.org/bot' . $this->token . '/' . $method); curl_setopt_array($ch, array( CURLOPT_POST => count($fields), CURLOPT_POSTFIELDS => http_build_query($fields), CURLOPT_SSL_VERIFYPEER => 0, CURLOPT_RETURNTRANSFER => 1, CURLOPT_TIMEOUT => 10 )); $r = json_decode(curl_exec($ch), true); curl_close($ch); return $r; } } ?> Супер! Спасибо огромное Quote Link to post Share on other sites
founder Posted August 14 Report Share Posted August 14 Подскажите, пожалуйста, для рассылки по базе пользователей лучше делать в этом же файле api/UsersTelegram.php (у меня вместо users - subscribes) добавить: public function sendBroadcast($message) { $telegramBotToken = $this->token; $url = "https://api.telegram.org/bot$telegramBotToken/sendMessage"; // Получаем всех подписчиков из базы данных $subscribers = $this->getSubscribers(); foreach ($subscribers as $subscriber) { $chatId = $subscriber->telegram_id; $postFields = [ 'chat_id' => $chatId, 'text' => $message ]; // Отправляем сообщение $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); } } private function getSubscribers() { $query = $this->db->placehold("SELECT * FROM __subscribe_mailing"); $this->db->query($query); return $this->db->results(); } или нужно отдельный файл? Кто знает, рассылку делать лучше отправку пакетами или как? Там есть лимиты? Quote Link to post Share on other sites
shooroop Posted August 14 Report Share Posted August 14 13 часов назад, founder сказал: Подскажите, пожалуйста, для рассылки по базе пользователей лучше делать в этом же файле api/UsersTelegram.php (у меня вместо users - subscribes) добавить: public function sendBroadcast($message) { $telegramBotToken = $this->token; $url = "https://api.telegram.org/bot$telegramBotToken/sendMessage"; // Получаем всех подписчиков из базы данных $subscribers = $this->getSubscribers(); foreach ($subscribers as $subscriber) { $chatId = $subscriber->telegram_id; $postFields = [ 'chat_id' => $chatId, 'text' => $message ]; // Отправляем сообщение $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); } } private function getSubscribers() { $query = $this->db->placehold("SELECT * FROM __subscribe_mailing"); $this->db->query($query); return $this->db->results(); } или нужно отдельный файл? Кто знает, рассылку делать лучше отправку пакетами или как? Там есть лимиты? лимиты есть и зависят от вашего хостера. Quote Link to post Share on other sites
founder Posted August 15 Report Share Posted August 15 9 часов назад, shooroop сказал: лимиты есть и зависят от вашего хостера. что влияет на это? или как называется? или как называется, чтобы спросить у поддержки? Quote Link to post Share on other sites
founder Posted August 15 Report Share Posted August 15 Что-то рассылка не работает с админки( в api/UsersTelegram.php в самый низ добавил: public function sendBroadcast($message) { $telegramBotToken = $this->token; $url = "https://api.telegram.org/bot$telegramBotToken/sendMessage"; // Получаем всех подписчиков из базы данных $subscribers = $this->getSubscribers(); foreach ($subscribers as $subscriber) { $chatId = $subscriber->telegram_id; $postFields = [ 'chat_id' => $chatId, 'text' => $message ]; // Отправляем сообщение $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); } } private function getSubscribers() { $query = $this->db->placehold("SELECT * FROM __subscribe_mailing"); $this->db->query($query); return $this->db->results(); } мой код simpla/SubscribeMailingAdmin.php: <?php require_once('api/Simpla.php'); require_once('api/UsersTelegram.php'); // Подключаем UsersTelegram class SubscribeMailingAdmin extends Simpla { private $export_files_dir = 'serdiuk/files/export_users/'; public function fetch() { $status = ''; // Проверка POST-запросов if ($this->request->method('post')) { // Отправка сообщения if ($this->request->post('message')) { $message = $this->request->post('message'); $auth = new UsersTelegram(); if ($auth->sendBroadcast($message)) { $status = 'Сообщение отправлено успешно!'; } else { $status = 'Ошибка отправки сообщения.'; } } // Удаление подписчиков if ($this->request->post('check')) { $ids = $this->request->post('check'); if (is_array($ids)) { switch ($this->request->post('action')) { case 'delete': { $this->subscribes->delete_subscribe($ids); break; } } } } } // Проверка экспорта if ($this->request->post('is_export')) { $this->design->assign('export_files_dir', $this->export_files_dir); $this->design->assign('sort', $this->request->get('sort')); $this->design->assign('keyword', $this->request->get('keyword')); $this->design->assign('export_files_dir', $this->export_files_dir); if (!is_writable($this->export_files_dir)) { $this->design->assign('message_error', 'no_permission'); } return $this->design->fetch('export_subscribes.tpl'); } // Пагинация и отображение подписчиков $filter = array(); $filter['page'] = max(1, $this->request->get('page', 'integer')); $filter['limit'] = 20; // Поиск $keyword = $this->request->get('keyword'); if (!empty($keyword)) { $filter['keyword'] = $keyword; $this->design->assign('keyword', $keyword); } $subscribes_count = $this->subscribes->count_subscribes($filter); // Показать все страницы сразу if ($this->request->get('page') == 'all') { $filter['limit'] = $subscribes_count; } if ($filter['limit'] > 0) { $pages_count = ceil($subscribes_count / $filter['limit']); } else { $pages_count = 0; } $filter['page'] = min($filter['page'], $pages_count); $this->design->assign('pages_count', $pages_count); $this->design->assign('current_page', $filter['page']); $subscribes = $this->subscribes->get_subscribes($filter); $this->design->assign('subscribes', $subscribes); $this->design->assign('subscribes_count', $subscribes_count); // Добавляем статус (успешно или ошибка отправки) в шаблон $this->design->assign('status', $status); // Количество товаров (если нужно) $products_count = $this->products->count_products($filter); if ($filter['limit'] > 0) { $pages_count = ceil($products_count / $filter['limit']); } else { $pages_count = 0; } $this->design->assign('products_count', $products_count); return $this->body = $this->design->fetch('subscribe_mailing.tpl'); } } в simpla/design/html/subscribe_mailing.tpl <form id="broadcastForm" method="post" action="{url module=SubscribeMailingAdmin}"> <textarea id="message" name="message" placeholder="Сообщение рассылки"></textarea> <button type="submit">Отправить</button> </form> <div id="status">{$status|escape}</div> {literal} <script> $(function() { // Отправка сообщения через AJAX document.getElementById('broadcastForm').addEventListener('submit', function(event) { event.preventDefault(); // Предотвращаем стандартное поведение формы var form = event.target; var formData = new FormData(form); // Создаем запрос var xhr = new XMLHttpRequest(); xhr.open('POST', form.action, true); xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { // Обработка успешного ответа document.getElementById('status').innerText = 'Сообщение отправлено успешно!'; } else { // Обработка ошибок document.getElementById('status').innerText = 'Ошибка отправки сообщения.'; } }; xhr.send(formData); }); }); </script> {/literal} Quote Link to post Share on other sites
founder Posted August 19 Report Share Posted August 19 В 15.08.2024 в 15:55, founder сказал: Что-то рассылка не работает с админки( в api/UsersTelegram.php в самый низ добавил: public function sendBroadcast($message) { $telegramBotToken = $this->token; $url = "https://api.telegram.org/bot$telegramBotToken/sendMessage"; // Получаем всех подписчиков из базы данных $subscribers = $this->getSubscribers(); foreach ($subscribers as $subscriber) { $chatId = $subscriber->telegram_id; $postFields = [ 'chat_id' => $chatId, 'text' => $message ]; // Отправляем сообщение $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); } } private function getSubscribers() { $query = $this->db->placehold("SELECT * FROM __subscribe_mailing"); $this->db->query($query); return $this->db->results(); } мой код simpla/SubscribeMailingAdmin.php: <?php require_once('api/Simpla.php'); require_once('api/UsersTelegram.php'); // Подключаем UsersTelegram class SubscribeMailingAdmin extends Simpla { private $export_files_dir = 'serdiuk/files/export_users/'; public function fetch() { $status = ''; // Проверка POST-запросов if ($this->request->method('post')) { // Отправка сообщения if ($this->request->post('message')) { $message = $this->request->post('message'); $auth = new UsersTelegram(); if ($auth->sendBroadcast($message)) { $status = 'Сообщение отправлено успешно!'; } else { $status = 'Ошибка отправки сообщения.'; } } // Удаление подписчиков if ($this->request->post('check')) { $ids = $this->request->post('check'); if (is_array($ids)) { switch ($this->request->post('action')) { case 'delete': { $this->subscribes->delete_subscribe($ids); break; } } } } } // Проверка экспорта if ($this->request->post('is_export')) { $this->design->assign('export_files_dir', $this->export_files_dir); $this->design->assign('sort', $this->request->get('sort')); $this->design->assign('keyword', $this->request->get('keyword')); $this->design->assign('export_files_dir', $this->export_files_dir); if (!is_writable($this->export_files_dir)) { $this->design->assign('message_error', 'no_permission'); } return $this->design->fetch('export_subscribes.tpl'); } // Пагинация и отображение подписчиков $filter = array(); $filter['page'] = max(1, $this->request->get('page', 'integer')); $filter['limit'] = 20; // Поиск $keyword = $this->request->get('keyword'); if (!empty($keyword)) { $filter['keyword'] = $keyword; $this->design->assign('keyword', $keyword); } $subscribes_count = $this->subscribes->count_subscribes($filter); // Показать все страницы сразу if ($this->request->get('page') == 'all') { $filter['limit'] = $subscribes_count; } if ($filter['limit'] > 0) { $pages_count = ceil($subscribes_count / $filter['limit']); } else { $pages_count = 0; } $filter['page'] = min($filter['page'], $pages_count); $this->design->assign('pages_count', $pages_count); $this->design->assign('current_page', $filter['page']); $subscribes = $this->subscribes->get_subscribes($filter); $this->design->assign('subscribes', $subscribes); $this->design->assign('subscribes_count', $subscribes_count); // Добавляем статус (успешно или ошибка отправки) в шаблон $this->design->assign('status', $status); // Количество товаров (если нужно) $products_count = $this->products->count_products($filter); if ($filter['limit'] > 0) { $pages_count = ceil($products_count / $filter['limit']); } else { $pages_count = 0; } $this->design->assign('products_count', $products_count); return $this->body = $this->design->fetch('subscribe_mailing.tpl'); } } в simpla/design/html/subscribe_mailing.tpl <form id="broadcastForm" method="post" action="{url module=SubscribeMailingAdmin}"> <textarea id="message" name="message" placeholder="Сообщение рассылки"></textarea> <button type="submit">Отправить</button> </form> <div id="status">{$status|escape}</div> {literal} <script> $(function() { // Отправка сообщения через AJAX document.getElementById('broadcastForm').addEventListener('submit', function(event) { event.preventDefault(); // Предотвращаем стандартное поведение формы var form = event.target; var formData = new FormData(form); // Создаем запрос var xhr = new XMLHttpRequest(); xhr.open('POST', form.action, true); xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { // Обработка успешного ответа document.getElementById('status').innerText = 'Сообщение отправлено успешно!'; } else { // Обработка ошибок document.getElementById('status').innerText = 'Ошибка отправки сообщения.'; } }; xhr.send(formData); }); }); </script> {/literal} Подскажите, пожалуйста, где ошибка? Почему не работает рассылка? Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.