From b735f82d9bc7e2fea8a19961c117f3b0c74a2cb0 Mon Sep 17 00:00:00 2001 From: Aleksandr Yurchenko Date: Thu, 13 Jul 2023 00:08:44 +0300 Subject: [PATCH 1/6] install composer 'dejurin/php-google-translate-for-free', bot creation started (db, api helper, keboard fo select lang) --- composer.json | 28 +-- composer.lock | 44 +++- translation-bot/DB.php | 138 +++++++++++ translation-bot/FAQ/README.md | 18 ++ .../Utils/DifferentTypesKeyboards.php | 103 ++++++++ .../Utils/TelegramBotApiHelper.php | 219 ++++++++++++++++++ translation-bot/index.php | 26 ++- 7 files changed, 561 insertions(+), 15 deletions(-) create mode 100644 translation-bot/DB.php create mode 100644 translation-bot/FAQ/README.md create mode 100644 translation-bot/Utils/DifferentTypesKeyboards.php create mode 100644 translation-bot/Utils/TelegramBotApiHelper.php diff --git a/composer.json b/composer.json index dfa1829..1b07615 100644 --- a/composer.json +++ b/composer.json @@ -1,16 +1,18 @@ { - "require-dev": { - "symfony/var-dumper": "^6.0" - }, - "require": { - "guzzlehttp/guzzle": "^7.4", - "irazasyed/telegram-bot-sdk": "^3.4" - }, - "autoload": { - "psr-4": { - "SimpleBot\\": "simple-bot/", - "TbaPhpSdk\\": "tba-php-sdk/", - "YaTranslationBot\\": "translation-bot/" - } + "require-dev": { + "symfony/var-dumper": "^6.0" + }, + "require": { + "guzzlehttp/guzzle": "^7.4", + "irazasyed/telegram-bot-sdk": "^3.4", + "dejurin/php-google-translate-for-free": "^1.0", + "ext-pdo": "*" + }, + "autoload": { + "psr-4": { + "SimpleBot\\": "simple-bot/", + "TbaPhpSdk\\": "tba-php-sdk/", + "YaTranslationBot\\": "translation-bot/" } + } } diff --git a/composer.lock b/composer.lock index 914d812..7077223 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,50 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ce2aa1397155c754016d27dfe87831ab", + "content-hash": "d7c230385438c2df08088842215141a9", "packages": [ + { + "name": "dejurin/php-google-translate-for-free", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/dejurin/php-google-translate-for-free.git", + "reference": "db5e3d0ac66e711dc41ed59618595aa3e3a7e475" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dejurin/php-google-translate-for-free/zipball/db5e3d0ac66e711dc41ed59618595aa3e3a7e475", + "reference": "db5e3d0ac66e711dc41ed59618595aa3e3a7e475", + "shasum": "" + }, + "require": { + "php": ">=5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Dejurin\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0+" + ], + "description": "Library for free use Google Translator. With attempts connecting on failure and array support.", + "homepage": "https://github.com/dejurin/php-google-translate-for-free", + "keywords": [ + "api", + "free", + "google", + "translate", + "translator" + ], + "support": { + "issues": "https://github.com/dejurin/php-google-translate-for-free/issues", + "source": "https://github.com/dejurin/php-google-translate-for-free/releases" + }, + "time": "2018-03-02T19:36:37+00:00" + }, { "name": "doctrine/inflector", "version": "2.0.8", diff --git a/translation-bot/DB.php b/translation-bot/DB.php new file mode 100644 index 0000000..f4047d6 --- /dev/null +++ b/translation-bot/DB.php @@ -0,0 +1,138 @@ +connection instanceof PDO) { + return $this; + } + + $dsn = "{$dbConfig['type']}:host={$dbConfig['host']};port={$dbConfig['port']};dbname={$dbConfig['name']}"; + + try { + $this->connection = new PDO($dsn, $dbConfig['user'], $dbConfig['password'], $dbConfig['options']); + } catch (PDOException $exception) { + file_put_contents( + __DIR__ . '/try_catch_db_logs.txt', + date('d.m.Y H:i:s') . PHP_EOL . print_r($exception, true), + FILE_APPEND + ); + die; + } + + return $this; + } + + public function query(string $query, array $params = []): false|DB + { + try { + $this->stmt = $this->connection->prepare($query); + $this->stmt->execute($params); + } catch (PDOException $exception) { + file_put_contents( + __DIR__ . '/try_catch_db_logs.txt', + date('d.m.Y H:i:s') . PHP_EOL . print_r($exception, true), + FILE_APPEND + ); + die; + } + + return $this; + } + + public function findAll(): array + { + return $this + ->stmt + ->fetchAll(); + } + + public function find(): ?array + { + $result = $this + ->stmt + ->fetch(); + + if (!$result) { + return null; + } + + return $result; + } + + public function getChatId(int $chatId): ?array + { + return $this + ->query('SELECT * FROM chat WHERE chat_id=:chatId', ['chatId' => $chatId]) + ->find(); + } + + public function setChat( + int $chatId, + string $firstName, + string $lastName, + string $username, + string $date, + string $lang + ): void { + $this + ->query( + 'INSERT INTO chat + (chat_id, first_name, last_name, username, date, lang) + VALUES (:chatId, :firstName, :lastName, :username, :date, :lang)', + [ + 'chatId' => $chatId, + 'firstName' => $firstName, + 'lastName' => $lastName, + 'username' => $username, + 'date' => $date, + 'lang' => $lang + ] + ); + } + + public function updateChat(int $chatId, string $lang, string $date): void + { + $this + ->query( + 'UPDATE chat + SET lang=:lang, date=:date + WHERE chat_id=:chatId', + [ + 'chatId' => $chatId, + 'lang' => $lang, + 'date' => $date + ] + ); + } +} diff --git a/translation-bot/FAQ/README.md b/translation-bot/FAQ/README.md new file mode 100644 index 0000000..7f2f667 --- /dev/null +++ b/translation-bot/FAQ/README.md @@ -0,0 +1,18 @@ +Создание таблицы `chat` в БД `telegram_bot_translation`: + +```sql +CREATE TABLE `telegram_bot_translation`.`chat` +( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `chat_id` BIGINT UNSIGNED NOT NULL, + `first_name` VARCHAR(510) NOT NULL, + `last_name` VARCHAR(510) NOT NULL, + `username` VARCHAR(510) NOT NULL, + `date` DATETIME NOT NULL, + `lang` VARCHAR(50) NOT NULL, + + PRIMARY KEY (`id`), + UNIQUE (`chat_id`) +) + ENGINE = InnoDB; +``` diff --git a/translation-bot/Utils/DifferentTypesKeyboards.php b/translation-bot/Utils/DifferentTypesKeyboards.php new file mode 100644 index 0000000..d3bcef2 --- /dev/null +++ b/translation-bot/Utils/DifferentTypesKeyboards.php @@ -0,0 +1,103 @@ +>> SIMPLE KEYBOARDS + protected static function simpleKeyboards(): array + { + return [ + ['Кнопка 1'], + ['Кнопка 2'], + ['Кнопка 3'], + ]; + } + + protected static function simpleKeyboardsWithComplexBtn(): array + { + return [ + [ + [ + 'text' => 'Отправить контакт', + 'request_contact' => true, + ], + [ + 'text' => 'Отправить локацию', + 'request_location' => true, + ] + ], + ['Открыть продвинутую клавиатуру'], + ['Убрать клавиатуру'], + ]; + } + + protected static function complexKeyboards(): array + { + return [ + ['Кнопка 1', 'Кнопка 2', 'Кнопка 3'], + ['Кнопка 4', 'Кнопка 5'], + ['Вернуться на стартовую клавиатуру'], + ['Убрать клавиатуру'], + ]; + } + // SIMPLE KEYBOARDS <<< + + // >>> INLINE KEYBOARDS + protected static function inlineKeyboardsForStartCommand(string $lang): array + { + if ('ru' === $lang) { + $buttons = [ + [ + 'text' => 'Английский [🇺🇸]', + 'callback_data' => 'en', + ], + [ + 'text' => 'Русский [🇷🇺]', + 'callback_data' => 'ru', + ], + ]; + } else { + $buttons = [ + [ + 'text' => 'English 🇺🇸', + 'callback_data' => 'en', + ], + [ + 'text' => 'Russian 🇷🇺', + 'callback_data' => 'ru', + ], + ]; + } + + return [$buttons]; + } + // INLINE KEYBOARDS <<< + + protected static function preparedSelectedKeyboards( + array $keyBoards, + array $additionalParams = [], + bool $inlineKeyboards = false + ): Keyboard { + $typeKeyboard = $inlineKeyboards ? 'inline_keyboard' : 'keyboard'; + + $params = [ + $typeKeyboard => $keyBoards, + ]; + + if (count($additionalParams) > 0) { + $params = array_merge($params, $additionalParams); + } + + return Keyboard::make($params); + } + + protected static function removeSelectedKeyboard(): Keyboard + { + return Keyboard::make([ + 'remove_keyboard' => true, + ]); + } +} diff --git a/translation-bot/Utils/TelegramBotApiHelper.php b/translation-bot/Utils/TelegramBotApiHelper.php new file mode 100644 index 0000000..e0e067a --- /dev/null +++ b/translation-bot/Utils/TelegramBotApiHelper.php @@ -0,0 +1,219 @@ +answerCallbackQuery возвращаемый тип MessageObject|bool, + * а не Telegram\Bot\Objects\Message ( ->answerCallbackQuery - возвращает bool) + */ + public static function definedTypeMessage( + TelegramBotApi $telegram, + Update $update, + bool $isEditMessage = false + ): MessageObject|bool { + if (isset($update['message'])) { + $typeMessage = ($isEditMessage === false) ? $update['message'] : $update['edited_message']; + $chatId = (int)$typeMessage['chat']['id']; + $incomingText = isset($typeMessage['text']) ? strtolower(trim($typeMessage['text'])) : ''; + } else { + $typeMessage = ''; + $incomingText = ''; + $chatId = -1; + } + + if ('/start' === $incomingText) { + $data = db()->getChatId($chatId); + $lang = 'ru'; + $firstName = self::getFirstName($typeMessage); + $lastName = self::getLastName($typeMessage); + $username = self::getUsername($typeMessage); + $date = self::getDate($typeMessage); + + if (null === $data) { + db()->setChat( + $chatId, + $firstName, + $lastName, + $username, + $date, + $lang + ); + } else { + $lang = $data['lang']; + } + + + $response = self::sendMessage( + telegram: $telegram, + chatId: $chatId, + message: 'Оставьте отмеченный язык для перевода с него или выберите другой', + additionalParams: [ + 'parse_mode' => 'Markdown', + 'reply_markup' => self::preparedSelectedKeyboards( + keyBoards: self::inlineKeyboardsForStartCommand($lang), + inlineKeyboards: true + ) + ] + ); + } + +// elseif ('Убрать клавиатуру' === $incomingText) { +// $response = self::sendMessage( +// telegram: $telegram, +// chatId: $chatId, +// message: 'Клавиатура убрана', +// additionalParams: [ +// 'reply_markup' => self::removeSelectedKeyboard() +// ] +// ); +// } +// +// elseif ('Открыть продвинутую клавиатуру' === $incomingText) { +// $response = self::sendMessage( +// telegram: $telegram, +// chatId: $chatId, +// message: 'Переключаюсь на продвинутую клавиатуру...', +// additionalParams: [ +// 'parse_mode' => 'Markdown', +// 'reply_markup' => self::preparedSelectedKeyboards( +// self::complexKeyboards(), +// [ +// 'resize_keyboard' => true, +// 'one_time_keyboard' => true, +// 'input_field_placeholder' => 'Выберите нужную команду' +// ] +// ) +// ] +// ); +// } +// +// elseif ('Вернуться на стартовую клавиатуру' === $incomingText) { +// $response = self::sendMessage( +// telegram: $telegram, +// chatId: $chatId, +// message: 'Возвращаюсь назад...', +// additionalParams: [ +// 'parse_mode' => 'Markdown', +// 'reply_markup' => self::preparedSelectedKeyboards( +// self::simpleKeyboardsWithComplexBtn(), +// [ +// 'resize_keyboard' => true, +// 'one_time_keyboard' => true, +// ] +// ) +// ] +// ); +// } + + return $response; + } + + public static function writeToLogs(array $update, string $pathToFile): void + { + if (count($update) > 0) { + ob_start(); + if (array_key_exists('message', $update)) { + echo '===[' . date('d-m-Y H:i:s', $update['message']['date']) . ']===' . PHP_EOL; + } elseif (array_key_exists('edited_message', $update)) { + echo '===[' . date('d-m-Y H:i:s', $update['edited_message']['edit_date']) . ']===' . PHP_EOL; + } elseif (array_key_exists('callback_query', $update)) { + echo '===[' . date('d-m-Y H:i:s', $update['callback_query']['message']['date']) . ']===' . PHP_EOL; + } else { + echo '===[' . date('d-m-Y H:i:s', $update['date']) . ']===' . PHP_EOL; + } + + print_r($update); + echo '------------------' . PHP_EOL; + $log = ob_get_clean(); + + if ('' !== $log) { + file_put_contents($pathToFile, $log, FILE_APPEND); + } + } + } + + /** + * @throws TelegramSDKException + */ + private static function sendMessage( + TelegramBotApi $telegram, + int $chatId, + string $message, + array $additionalParams = [], + int $delayMicroSecond = 0 + ): MessageObject { + $params = [ + 'chat_id' => $chatId, + 'text' => $message, + ]; + + if (count($additionalParams) > 0) { + $params = array_merge($params, $additionalParams); + } + + if (0 !== $delayMicroSecond) { + usleep($delayMicroSecond); + return $telegram->sendMessage($params); + } + + return $telegram->sendMessage($params); + } + + private static function getChatInfo(array $typeMessage): ?array + { + return $typeMessage['chat'] ?? null; + } + + private static function getFirstName(array $typeMessage): string + { + $chat = self::getChatInfo($typeMessage); + + if (null === $chat) { + return ''; + } + + return array_key_exists('first_name', $chat) ? $chat['first_name'] : ''; + } + + private static function getLastName(array $typeMessage): string + { + $chat = self::getChatInfo($typeMessage); + + if (null === $chat) { + return ''; + } + + return array_key_exists('last_name', $chat) ? $chat['last_name'] : ''; + } + + private static function getUsername(array $typeMessage): string + { + $chat = array_key_exists('chat', $typeMessage) ? $typeMessage['chat'] : ''; + + if ('' === $chat) { + return ''; + } + + return array_key_exists('username', $chat) ? $chat['username'] : ''; + } + + private static function getDate(array $typeMessage): string + { + $date = new DateTime(); + $date->setTimestamp($typeMessage['date']); + + return $date->format('Y-m-d H:i:s'); + } +} diff --git a/translation-bot/index.php b/translation-bot/index.php index cd7c7fd..2204f37 100644 --- a/translation-bot/index.php +++ b/translation-bot/index.php @@ -6,4 +6,28 @@ die('Please, created config file.'); } -die('Silence is golden.'); +use Telegram\Bot\Api as TelegramBotApi; +use YaTranslationBot\Utils\TelegramBotApiHelper as Helper; + +try { + $telegram = new TelegramBotApi(YA_TRANSLATION_BOT); + + // >>> getUpdates + $update = $telegram->getWebhookUpdate(); + Helper::writeToLogs($update->getRawResponse(), __DIR__ . '/update_logs.txt'); + // getUpdates <<< + + // >>> sendMessage + if ($update->count() > 0) { + if (array_key_exists('edited_message', $update->getRawResponse())) { + $response = Helper::definedTypeMessage($telegram, $update, true); + } else { + $response = Helper::definedTypeMessage($telegram, $update); + } + } + // sendMessage <<< +} catch (Throwable $e) { + file_put_contents(__DIR__ . '/try_catch_logs.txt', date('d.m.Y H:i:s') . PHP_EOL . print_r($e, true), FILE_APPEND); +} + +die('Silence is golden'); From 76e7c2cdf3e15292f9f932986c899912317462c3 Mon Sep 17 00:00:00 2001 From: Aleksandr Yurchenko Date: Thu, 13 Jul 2023 13:00:23 +0300 Subject: [PATCH 2/6] translation bot: realised lang switching --- .../Utils/DifferentTypesKeyboards.php | 10 +- .../Utils/TelegramBotApiHelper.php | 134 ++++++++++-------- translation-bot/index.php | 10 +- 3 files changed, 83 insertions(+), 71 deletions(-) diff --git a/translation-bot/Utils/DifferentTypesKeyboards.php b/translation-bot/Utils/DifferentTypesKeyboards.php index d3bcef2..96fbd56 100644 --- a/translation-bot/Utils/DifferentTypesKeyboards.php +++ b/translation-bot/Utils/DifferentTypesKeyboards.php @@ -46,27 +46,27 @@ protected static function complexKeyboards(): array // SIMPLE KEYBOARDS <<< // >>> INLINE KEYBOARDS - protected static function inlineKeyboardsForStartCommand(string $lang): array + protected static function getInlineKeyboardForTranslationBot(string $lang): array { if ('ru' === $lang) { $buttons = [ [ - 'text' => 'Английский [🇺🇸]', + 'text' => 'Английский', 'callback_data' => 'en', ], [ - 'text' => 'Русский [🇷🇺]', + 'text' => '☑️ Русский', 'callback_data' => 'ru', ], ]; } else { $buttons = [ [ - 'text' => 'English 🇺🇸', + 'text' => '☑️ English', 'callback_data' => 'en', ], [ - 'text' => 'Russian 🇷🇺', + 'text' => 'Russian', 'callback_data' => 'ru', ], ]; diff --git a/translation-bot/Utils/TelegramBotApiHelper.php b/translation-bot/Utils/TelegramBotApiHelper.php index e0e067a..0a297e0 100644 --- a/translation-bot/Utils/TelegramBotApiHelper.php +++ b/translation-bot/Utils/TelegramBotApiHelper.php @@ -5,6 +5,7 @@ use DateTime; use Telegram\Bot\Api as TelegramBotApi; use Telegram\Bot\Exceptions\TelegramSDKException; +use Telegram\Bot\Objects\Message; use Telegram\Bot\Objects\Message as MessageObject; use Telegram\Bot\Objects\Update; @@ -21,16 +22,29 @@ class TelegramBotApiHelper public static function definedTypeMessage( TelegramBotApi $telegram, Update $update, - bool $isEditMessage = false + string $nameArrMessage = 'message' ): MessageObject|bool { - if (isset($update['message'])) { - $typeMessage = ($isEditMessage === false) ? $update['message'] : $update['edited_message']; - $chatId = (int)$typeMessage['chat']['id']; - $incomingText = isset($typeMessage['text']) ? strtolower(trim($typeMessage['text'])) : ''; - } else { - $typeMessage = ''; - $incomingText = ''; - $chatId = -1; + switch ($nameArrMessage) { + case 'message': + $typeMessage = $update['message']; + $chatId = (int)$typeMessage['chat']['id']; + $incomingText = isset($typeMessage['text']) ? strtolower(trim($typeMessage['text'])) : ''; + break; + case 'edited_message': + $typeMessage = $update['edited_message']; + $chatId = (int)$typeMessage['chat']['id']; + $incomingText = isset($typeMessage['text']) ? strtolower(trim($typeMessage['text'])) : ''; + break; + case 'callback_query': + $typeMessage = $update['callback_query']; + $chatId = (int)$typeMessage['message']['chat']['id']; + $incomingText = ''; + break; + default: + $typeMessage = []; + $chatId = -1; + $incomingText = ''; + break; } if ('/start' === $incomingText) { @@ -39,7 +53,7 @@ public static function definedTypeMessage( $firstName = self::getFirstName($typeMessage); $lastName = self::getLastName($typeMessage); $username = self::getUsername($typeMessage); - $date = self::getDate($typeMessage); + $date = self::getTimestampToDateTime($typeMessage); if (null === $data) { db()->setChat( @@ -54,7 +68,6 @@ public static function definedTypeMessage( $lang = $data['lang']; } - $response = self::sendMessage( telegram: $telegram, chatId: $chatId, @@ -62,60 +75,59 @@ public static function definedTypeMessage( additionalParams: [ 'parse_mode' => 'Markdown', 'reply_markup' => self::preparedSelectedKeyboards( - keyBoards: self::inlineKeyboardsForStartCommand($lang), + keyBoards: self::getInlineKeyboardForTranslationBot($lang), inlineKeyboards: true ) ] ); - } + } elseif ('callback_query' === $nameArrMessage) { + $btnInlineKeyBoard = $typeMessage['message']['reply_markup']['inline_keyboard'][0]; + $now = new DateTime(); + $nowStr = $now->format('Y-m-d H:i:s'); + + foreach ($btnInlineKeyBoard as $btn) { + $isoCode = match ($btn['text']) { + 'Русский', 'Russian' => 'ru', + 'English', 'Английский' => 'en', + default => '', + }; + + if ($isoCode === $typeMessage['data']) { + db()->updateChat( + $chatId, + $typeMessage['data'], + $nowStr, + ); + + $telegram->answerCallbackQuery(['callback_query_id' => $typeMessage['id']]); + + $response = self::sendMessage( + telegram: $telegram, + chatId: $chatId, + message: 'Можете вводить слово для перевода с выбранного языка', + additionalParams: [ + 'parse_mode' => 'Markdown', + 'reply_markup' => self::preparedSelectedKeyboards( + keyBoards: self::getInlineKeyboardForTranslationBot($typeMessage['data']), + inlineKeyboards: true + ) + ] + ); + + break; + } + } -// elseif ('Убрать клавиатуру' === $incomingText) { -// $response = self::sendMessage( -// telegram: $telegram, -// chatId: $chatId, -// message: 'Клавиатура убрана', -// additionalParams: [ -// 'reply_markup' => self::removeSelectedKeyboard() -// ] -// ); -// } -// -// elseif ('Открыть продвинутую клавиатуру' === $incomingText) { -// $response = self::sendMessage( -// telegram: $telegram, -// chatId: $chatId, -// message: 'Переключаюсь на продвинутую клавиатуру...', -// additionalParams: [ -// 'parse_mode' => 'Markdown', -// 'reply_markup' => self::preparedSelectedKeyboards( -// self::complexKeyboards(), -// [ -// 'resize_keyboard' => true, -// 'one_time_keyboard' => true, -// 'input_field_placeholder' => 'Выберите нужную команду' -// ] -// ) -// ] -// ); -// } -// -// elseif ('Вернуться на стартовую клавиатуру' === $incomingText) { -// $response = self::sendMessage( -// telegram: $telegram, -// chatId: $chatId, -// message: 'Возвращаюсь назад...', -// additionalParams: [ -// 'parse_mode' => 'Markdown', -// 'reply_markup' => self::preparedSelectedKeyboards( -// self::simpleKeyboardsWithComplexBtn(), -// [ -// 'resize_keyboard' => true, -// 'one_time_keyboard' => true, -// ] -// ) -// ] -// ); -// } + $telegram->answerCallbackQuery([ + 'callback_query_id' => $typeMessage['id'], + 'text' => 'Это уже активный язык', + 'show_alert' => false, // Вызывает модальное окно, требуется клик/тап, что бы убрать + ]); + + $response = true; + } else { + $response = false; + } return $response; } @@ -209,7 +221,7 @@ private static function getUsername(array $typeMessage): string return array_key_exists('username', $chat) ? $chat['username'] : ''; } - private static function getDate(array $typeMessage): string + private static function getTimestampToDateTime(array $typeMessage): string { $date = new DateTime(); $date->setTimestamp($typeMessage['date']); diff --git a/translation-bot/index.php b/translation-bot/index.php index 2204f37..3930d88 100644 --- a/translation-bot/index.php +++ b/translation-bot/index.php @@ -19,11 +19,11 @@ // >>> sendMessage if ($update->count() > 0) { - if (array_key_exists('edited_message', $update->getRawResponse())) { - $response = Helper::definedTypeMessage($telegram, $update, true); - } else { - $response = Helper::definedTypeMessage($telegram, $update); - } + $response = match (true) { + array_key_exists('edited_message', $update->getRawResponse()) => Helper::definedTypeMessage($telegram, $update, 'edited_message'), + array_key_exists('callback_query', $update->getRawResponse()) => Helper::definedTypeMessage($telegram, $update, 'callback_query'), + default => Helper::definedTypeMessage($telegram, $update), + }; } // sendMessage <<< } catch (Throwable $e) { From 1ae68411cd816f5666fd1bb1fcb8654f74cc7b27 Mon Sep 17 00:00:00 2001 From: Aleksandr Yurchenko Date: Thu, 13 Jul 2023 13:31:40 +0300 Subject: [PATCH 3/6] translation bot: realised translation ru->en, en->ru --- .../Utils/TelegramBotApiHelper.php | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/translation-bot/Utils/TelegramBotApiHelper.php b/translation-bot/Utils/TelegramBotApiHelper.php index 0a297e0..8c2d422 100644 --- a/translation-bot/Utils/TelegramBotApiHelper.php +++ b/translation-bot/Utils/TelegramBotApiHelper.php @@ -3,6 +3,7 @@ namespace YaTranslationBot\Utils; use DateTime; +use Dejurin\GoogleTranslateForFree; use Telegram\Bot\Api as TelegramBotApi; use Telegram\Bot\Exceptions\TelegramSDKException; use Telegram\Bot\Objects\Message; @@ -104,7 +105,7 @@ public static function definedTypeMessage( $response = self::sendMessage( telegram: $telegram, chatId: $chatId, - message: 'Можете вводить слово для перевода с выбранного языка', + message: 'Можете вводить слово или фразу для перевода с выбранного языка', additionalParams: [ 'parse_mode' => 'Markdown', 'reply_markup' => self::preparedSelectedKeyboards( @@ -125,6 +126,40 @@ public static function definedTypeMessage( ]); $response = true; + } elseif ('' !== $incomingText) { + $data = db()->getChatId($chatId); + + $source = ($data['lang'] === 'en') ? 'en' : 'ru'; + $target = ($data['lang'] === 'ru') ? 'en' : 'ru'; + $attempts = 5; + $text = 'Fuck the police'; + + $result = GoogleTranslateForFree::translate($source, $target, trim($incomingText), $attempts); + + self::writeToLogs( + [ + 'chatId' => $data['chat_id'], + 'full_name' => $data['first_name'] . ' ' . $data['last_name'], + 'username' => $data['username'], + 'textToTranslate' => $text, + 'translatedText' => $result, + ], + __DIR__ . '/../translations.txt' + ); + + if ($result) { + $response = self::sendMessage( + telegram: $telegram, + chatId: $chatId, + message: $result, + ); + } else { + $response = self::sendMessage( + telegram: $telegram, + chatId: $chatId, + message: 'Сервис временно недоступен, попробуйте повторить позже', + ); + } } else { $response = false; } From 0f48c5d686f01aa5933ec8f8930e657a95ee3a0a Mon Sep 17 00:00:00 2001 From: Aleksandr Yurchenko Date: Thu, 13 Jul 2023 13:50:25 +0300 Subject: [PATCH 4/6] translation bot v1: exception handling --- translation-bot/Utils/TelegramBotApiHelper.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/translation-bot/Utils/TelegramBotApiHelper.php b/translation-bot/Utils/TelegramBotApiHelper.php index 8c2d422..1b61b59 100644 --- a/translation-bot/Utils/TelegramBotApiHelper.php +++ b/translation-bot/Utils/TelegramBotApiHelper.php @@ -132,7 +132,6 @@ public static function definedTypeMessage( $source = ($data['lang'] === 'en') ? 'en' : 'ru'; $target = ($data['lang'] === 'ru') ? 'en' : 'ru'; $attempts = 5; - $text = 'Fuck the police'; $result = GoogleTranslateForFree::translate($source, $target, trim($incomingText), $attempts); @@ -141,7 +140,7 @@ public static function definedTypeMessage( 'chatId' => $data['chat_id'], 'full_name' => $data['first_name'] . ' ' . $data['last_name'], 'username' => $data['username'], - 'textToTranslate' => $text, + 'textToTranslate' => $incomingText, 'translatedText' => $result, ], __DIR__ . '/../translations.txt' @@ -161,7 +160,11 @@ public static function definedTypeMessage( ); } } else { - $response = false; + $response = self::sendMessage( + telegram: $telegram, + chatId: $chatId, + message: 'Бот умеет работать только с текстом', + ); } return $response; From ae048d54fa9bafafb9279b86eab6fda5b8928141 Mon Sep 17 00:00:00 2001 From: Aleksandr Yurchenko Date: Thu, 13 Jul 2023 14:01:43 +0300 Subject: [PATCH 5/6] rename 'translation-bot' -> 'translation-bot-v1' --- composer.json | 2 +- {translation-bot => translation-bot-v1}/DB.php | 0 {translation-bot => translation-bot-v1}/FAQ/README.md | 0 .../Utils/DifferentTypesKeyboards.php | 0 .../Utils/TelegramBotApiHelper.php | 0 {translation-bot => translation-bot-v1}/index.php | 2 +- 6 files changed, 2 insertions(+), 2 deletions(-) rename {translation-bot => translation-bot-v1}/DB.php (100%) rename {translation-bot => translation-bot-v1}/FAQ/README.md (100%) rename {translation-bot => translation-bot-v1}/Utils/DifferentTypesKeyboards.php (100%) rename {translation-bot => translation-bot-v1}/Utils/TelegramBotApiHelper.php (100%) rename {translation-bot => translation-bot-v1}/index.php (97%) diff --git a/composer.json b/composer.json index 1b07615..c0d19fd 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "psr-4": { "SimpleBot\\": "simple-bot/", "TbaPhpSdk\\": "tba-php-sdk/", - "YaTranslationBot\\": "translation-bot/" + "YaTranslationBot\\": "translation-bot-v1/" } } } diff --git a/translation-bot/DB.php b/translation-bot-v1/DB.php similarity index 100% rename from translation-bot/DB.php rename to translation-bot-v1/DB.php diff --git a/translation-bot/FAQ/README.md b/translation-bot-v1/FAQ/README.md similarity index 100% rename from translation-bot/FAQ/README.md rename to translation-bot-v1/FAQ/README.md diff --git a/translation-bot/Utils/DifferentTypesKeyboards.php b/translation-bot-v1/Utils/DifferentTypesKeyboards.php similarity index 100% rename from translation-bot/Utils/DifferentTypesKeyboards.php rename to translation-bot-v1/Utils/DifferentTypesKeyboards.php diff --git a/translation-bot/Utils/TelegramBotApiHelper.php b/translation-bot-v1/Utils/TelegramBotApiHelper.php similarity index 100% rename from translation-bot/Utils/TelegramBotApiHelper.php rename to translation-bot-v1/Utils/TelegramBotApiHelper.php diff --git a/translation-bot/index.php b/translation-bot-v1/index.php similarity index 97% rename from translation-bot/index.php rename to translation-bot-v1/index.php index 3930d88..cdf0132 100644 --- a/translation-bot/index.php +++ b/translation-bot-v1/index.php @@ -30,4 +30,4 @@ file_put_contents(__DIR__ . '/try_catch_logs.txt', date('d.m.Y H:i:s') . PHP_EOL . print_r($e, true), FILE_APPEND); } -die('Silence is golden'); +//die('Silence is golden'); From 775ee545d01efc13457e07bb65af69260699204c Mon Sep 17 00:00:00 2001 From: Aleksandr Yurchenko Date: Thu, 13 Jul 2023 14:18:32 +0300 Subject: [PATCH 6/6] update README.md and config.php.example --- README.md | 18 ++++++++++++++++-- config.php.example | 44 +++++++++++++++++++++++++++----------------- 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 84c0f08..77eb757 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ * Пример: если бот доступен по url `https://example.com/bot`, привязать его можно выполнив запрос: `https://api.telegram.org/bot{BOT_TOKEN}/setWebhook?url=https://example.com/bot` (наличие ssl - **обязательно**). * Проверить статус бота можно, выполнив запрос: `https://api.telegram.org/bot{BOT_TOKEN}/getWebhook` -## Функционал ботов +## Реализованные боты ### simple-bot @@ -53,7 +53,21 @@ > [Пример работающего TbaPhpSdkBot бота](https://t.me/TbaPhpSdkBot "Пример работающего TbaPhpSdkBot бота") +### translation-bot-v1 + +Бот переводчик, перевод фраз осуществляется с помощью `dejurin/php-google-translate-for-free`. Доступные переводы: + +* С Английского на Русский +* С Русского на английский + +Есть возможность переводить как слова, так и словосочетания и предложения. Реализована обработка ошибок, если в бот отправить +фото, видео, стикер или какой-то документ, пользователю вернется сообщение, что бот работает только с текстом. + +> [Пример работающего ya_translation_bot бота](https://t.me/ya_translation_bot "Пример работающего ya_translation_bot бота") + +--- + ### Для отладки в ботах реализован функционал записи в логи * Возникающие исключения отлавливаются в `try/catch` и пишутся в файл `try_catch_logs.txt`, который находится в папке с ботом. -* Для записи ответов с телеграмм бота и запросов с вашей стороны реализован методы `addToLogs()` / `writeToLogs()`. \ No newline at end of file +* Для записи ответов с телеграмм бота и запросов с вашей стороны реализован методы `addToLogs()` / `writeToLogs()`. diff --git a/config.php.example b/config.php.example index 5106191..9620423 100644 --- a/config.php.example +++ b/config.php.example @@ -1,6 +1,7 @@ >> Token for local telegram bots -/** - * Токен используется для ботов из директории: local -*/ -const FIRST_BOT_TOKEN = '...'; -// Token for local telegram bots <<< - - -// >>> Token for remote telegram bots /** * Логин: ... * - * Привязка URL к вебхуку: - * echo BASE_URL . EXAMPLE_TOKEN . '/setWebhook?url={{ URL YOUR SITE, https - required }}'; + * Привязка URL к вебхука: * https://api.telegram.org/bot{{EXAMPLE_TOKEN }}/setWebhook?url={{ URL YOUR SITE, https - required }} * * Проверка статуса вебхука: - * https://api.telegram.org/bot{{EXAMPLE_TOKEN }}/getWebhookInfo?url={{ URL YOUR SITE, https - required }} + * https://api.telegram.org/bot{{EXAMPLE_TOKEN }}/getWebhookInfo + * + * Удалить вебхук: + * https://api.telegram.org/bot{{EXAMPLE_TOKEN }}/setWebhook */ -const SIMPLE_BOT_TOKEN = '...'; // Токен используется для ботов из директории: remote/echo-bot -const TBA_PHP_SDK_TOKEN = '...'; // Токен используется для ботов из директории: remote/tba-php-sdk -// Token for remote telegram bots <<< \ No newline at end of file +const EXAMPLE_TOKEN = '...'; // Токен (создается в BotFather) + +// Для подключения к БД (используется в некоторых ботах, например бот переводчик) +const PARAMS_DB = [ + 'type' => 'mysql', + 'host' => 'localhost', + 'name' => '{DB_NAME}', + 'port' => '{DB_PORT}', + 'user' => '{DB_USER}', + 'password' => '{DB_PASSWORD}', + 'options' => [ + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + //PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION // формирование исключений для PHP < v.8 + ], +]; + +function db(): DB +{ + return DB::getInstance()->getConnection(PARAMS_DB); +}