Telegram-боты стали мощным инструментом для автоматизации коммуникаций, уведомлений и взаимодействия с пользователями. В этой статье я покажу, как создать простого Telegram-бота на PHP с нуля.

Что нам понадобится
1. Аккаунт в Telegram
2. Хостинг или локальный сервер с поддержкой PHP и HTTPS (для вебхуков)
3. Базовые знания PHP

Шаг 1: Создание бота в Telegram
1. Откройте Telegram и найдите @BotFather
2. Отправьте команду /newbot
3. Укажите имя бота (например, MyTestBot)
4. Укажите username бота (должен заканчиваться на bot, например, my_test_example_bot)
5. Сохраните полученный токен — он понадобится для работы с API

Пример токена: 1234567890:ABCdefGHIjklMNOpqrsTUVwxyz

Шаг 2: Настройка окружения

Создадим базовую структуру проекта:
Код:
telegram-bot/
├── config.php
├── bot.php
├── webhook.php
├── index.php
└── .htaccess

Шаг 3: Основной код бота
config.php
PHP:
<?php
// Конфигурация бота
define('BOT_TOKEN', 'ВАШ_ТОКЕН_ЗДЕСЬ');
define('API_URL', 'https://api.telegram.org/bot' . BOT_TOKEN . '/');

// Настройки вебхука
define('WEBHOOK_URL', 'https://ваш-домен.ru/webhook.php');
?>

bot.php - Класс для работы с Telegram API
PHP:
<?php
require_once 'config.php';

class TelegramBot {
    
    /**
     * Отправка запроса к Telegram API
     */
    public function apiRequest($method, $parameters = []) {
        foreach ($parameters as $key => &$val) {
            if (is_array($val)) {
                $val = json_encode($val);
            }
        }
        
        $url = API_URL . $method . '?' . http_build_query($parameters);
        $handle = curl_init($url);
        
        curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
        curl_setopt($handle, CURLOPT_TIMEOUT, 60);
        curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
        
        $response = curl_exec($handle);
        
        if ($response === false) {
            $errno = curl_errno($handle);
            $error = curl_error($handle);
            curl_close($handle);
            throw new Exception("CURL ошибка: [$errno] $error");
        }
        
        $http_code = curl_getinfo($handle, CURLINFO_HTTP_CODE);
        curl_close($handle);
        
        if ($http_code >= 500) {
            sleep(10);
            return false;
        } elseif ($http_code != 200) {
            $response = json_decode($response, true);
            error_log("Ошибка: " . print_r($response, true));
            throw new Exception("Ошибка HTTP: $http_code");
        } else {
            $response = json_decode($response, true);
            if ($response['ok'] == false) {
                throw new Exception("Ошибка Telegram API: {$response['description']}");
            }
            return $response['result'];
        }
    }
    
    /**
     * Отправка сообщения
     */
    public function sendMessage($chat_id, $text, $parse_mode = 'HTML', $reply_markup = null) {
        $params = [
            'chat_id' => $chat_id,
            'text' => $text,
            'parse_mode' => $parse_mode,
        ];
        
        if ($reply_markup) {
            $params['reply_markup'] = $reply_markup;
        }
        
        return $this->apiRequest('sendMessage', $params);
    }
    
    /**
     * Установка вебхука
     */
    public function setWebhook($url) {
        return $this->apiRequest('setWebhook', ['url' => $url]);
    }
    
    /**
     * Удаление вебхука
     */
    public function deleteWebhook() {
        return $this->apiRequest('deleteWebhook');
    }
    
    /**
     * Получение информации о боте
     */
    public function getMe() {
        return $this->apiRequest('getMe');
    }
    
    /**
     * Создание клавиатуры
     */
    public function buildKeyboard($buttons, $resize_keyboard = true, $one_time_keyboard = false) {
        return json_encode([
            'keyboard' => $buttons,
            'resize_keyboard' => $resize_keyboard,
            'one_time_keyboard' => $one_time_keyboard
        ]);
    }
    
    /**
     * Создание inline-клавиатуры
     */
    public function buildInlineKeyboard($buttons) {
        return json_encode(['inline_keyboard' => $buttons]);
    }
}
?>

webhook.php - Обработчик вебхука
PHP:
<?php
require_once 'bot.php';

// Получаем входящее обновление
$content = file_get_contents("php://input");
$update = json_decode($content, true);

if (!$update) {
    exit;
}

$bot = new TelegramBot();

try {
    // Обработка сообщения
    if (isset($update["message"])) {
        $message = $update["message"];
        $chat_id = $message["chat"]["id"];
        $text = $message["text"] ?? '';
        $first_name = $message["chat"]["first_name"] ?? 'Пользователь';
        
        // Обработка команд
        switch ($text) {
            case '/start':
                $response = "Привет, {$first_name}! 👋\nЯ простой демонстрационный бот.\n\n";
                $response .= "Доступные команды:\n";
                $response .= "/start - Начать диалог\n";
                $response .= "/help - Помощь\n";
                $response .= "/time - Текущее время\n";
                $response .= "/keyboard - Показать клавиатуру\n";
                $response .= "/hidekeyboard - Скрыть клавиатуру\n";
                $response .= "/inline - Inline-кнопки";
                
                // Отправляем сообщение
                $bot->sendMessage($chat_id, $response);
                break;
                
            case '/help':
                $help_text = "🤖 <b>Помощь по боту</b>\n\n";
                $help_text .= "Это демонстрационный бот, созданный для примера.\n";
                $help_text .= "Он показывает основные возможности Telegram Bot API.\n\n";
                $help_text .= "<i>Используйте команды из меню или введите /start</i>";
                
                $bot->sendMessage($chat_id, $help_text);
                break;
                
            case '/time':
                $time = date('d.m.Y H:i:s');
                $bot->sendMessage($chat_id, "🕐 Текущее время: $time");
                break;
                
            case '/keyboard':
                // Создаем кастомную клавиатуру
                $keyboard = [
                    ['/start', '/help'],
                    ['/time', '/inline'],
                    ['Скрыть клавиатуру']
                ];
                
                $reply_markup = $bot->buildKeyboard($keyboard);
                $bot->sendMessage($chat_id, "Выберите действие:", 'HTML', $reply_markup);
                break;
                
            case '/hidekeyboard':
            case 'Скрыть клавиатуру':
                // Убираем клавиатуру
                $reply_markup = json_encode(['remove_keyboard' => true]);
                $bot->sendMessage($chat_id, "Клавиатура скрыта", 'HTML', $reply_markup);
                break;
                
            case '/inline':
                // Создаем inline-клавиатуру
                $inline_keyboard = [
                    [
                        ['text' => 'GitHub', 'url' => 'https://github.com'],
                        ['text' => 'Telegram', 'url' => 'https://t.me']
                    ],
                    [
                        ['text' => 'Кнопка с callback', 'callback_data' => 'button_clicked']
                    ]
                ];
                
                $reply_markup = $bot->buildInlineKeyboard($inline_keyboard);
                $bot->sendMessage($chat_id, "Пример inline-клавиатуры:", 'HTML', $reply_markup);
                break;
                
            default:
                if (!empty($text)) {
                    $bot->sendMessage($chat_id, "Вы сказали: \"$text\"\nИспользуйте /help для списка команд");
                }
                break;
        }
    }
    
    // Обработка callback-запросов от inline-кнопок
    if (isset($update["callback_query"])) {
        $callback = $update["callback_query"];
        $callback_id = $callback["id"];
        $chat_id = $callback["message"]["chat"]["id"];
        $data = $callback["data"];
        
        if ($data === 'button_clicked') {
            // Отвечаем на callback
            $bot->apiRequest('answerCallbackQuery', [
                'callback_query_id' => $callback_id,
                'text' => 'Вы нажали на кнопку!',
                'show_alert' => false
            ]);
            
            // Редактируем сообщение
            $bot->apiRequest('editMessageText', [
                'chat_id' => $chat_id,
                'message_id' => $callback["message"]["message_id"],
                'text' => 'Вы нажали на inline-кнопку! ✅',
                'parse_mode' => 'HTML'
            ]);
        }
    }
    
} catch (Exception $e) {
    error_log("Ошибка: " . $e->getMessage());
}
?>

index.php - Панель управления
PHP:
<?php
require_once 'bot.php';

$bot = new TelegramBot();

echo "<h1>Панель управления Telegram-ботом</h1>";

try {
    // Получаем информацию о боте
    $bot_info = $bot->getMe();
    echo "<h2>Информация о боте</h2>";
    echo "<p><strong>ID:</strong> {$bot_info['id']}</p>";
    echo "<p><strong>Имя:</strong> {$bot_info['first_name']}</p>";
    echo "<p><strong>Username:</strong> @{$bot_info['username']}</p>";
    
    // Форма для управления вебхуком
    echo "<h2>Управление вебхуком</h2>";
    echo "<form method='post'>";
    echo "<p><input type='text' name='webhook_url' value='" . WEBHOOK_URL . "' style='width: 400px;'></p>";
    echo "<p><button type='submit' name='set_webhook'>Установить вебхук</button> ";
    echo "<button type='submit' name='delete_webhook'>Удалить вебхук</button></p>";
    echo "</form>";
    
    if (isset($_POST['set_webhook'])) {
        $result = $bot->setWebhook($_POST['webhook_url']);
        echo "<p style='color: green;'>Вебхук успешно установлен!</p>";
    }
    
    if (isset($_POST['delete_webhook'])) {
        $result = $bot->deleteWebhook();
        echo "<p style='color: green;'>Вебхук успешно удален!</p>";
    }
    
} catch (Exception $e) {
    echo "<p style='color: red;'>Ошибка: " . $e->getMessage() . "</p>";
}
?>

.htaccess - Настройки для Apache
Код:
RewriteEngine On

# Перенаправление на index.php для панели управления
RewriteRule ^admin/?$ index.php [L]

# Разрешаем доступ к webhook.php
RewriteRule ^webhook\.php$ - [L]

# Блокируем доступ к другим файлам
RewriteRule ^.*$ - [F,L]

Шаг 4: Развертывание и настройка
1. Загрузите файлы на хостинг с поддержкой HTTPS
2. Настройте config.php:
· Вставьте ваш токен бота
· Укажите правильный URL для вебхука
3. Откройте панель управления: https://ваш-домен.ru/admin
4. Установите вебхук, нажав соответствующую кнопку
5. Протестируйте бота в Telegram

Шаг 5: Дальнейшее развитие
Ваш базовый бот готов! Вот несколько идей для расширения функциональности:

1. Добавление базы данных
PHP:
// Пример подключения к MySQL
class Database {
    private $connection;
    
    public function __construct() {
        $this->connection = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
        $this->connection->set_charset("utf8mb4");
    }
    
    public function saveUser($user_id, $username, $first_name) {
        $stmt = $this->connection->prepare("INSERT INTO users (user_id, username, first_name) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE last_seen = NOW()");
        $stmt->bind_param("iss", $user_id, $username, $first_name);
        return $stmt->execute();
    }
}

2. Многопользовательская игра
PHP:
// Простая игра "Угадай число"
class GuessGame {
    private $games = [];
    
    public function startGame($chat_id) {
        $this->games[$chat_id] = rand(1, 100);
        return "Я загадал число от 1 до 100. Попробуй угадать!";
    }
    
    public function checkGuess($chat_id, $number) {
        if (!isset($this->games[$chat_id])) {
            return "Сначала начните игру командой /game";
        }
        
        $secret = $this->games[$chat_id];
        
        if ($number == $secret) {
            unset($this->games[$chat_id]);
            return "🎉 Поздравляю! Вы угадали число $secret!";
        } elseif ($number < $secret) {
            return "Мое число больше!";
        } else {
            return "Мое число меньше!";
        }
    }
}

3. Интеграция с внешними API
PHP:
// Получение погоды
class WeatherService {
    public function getWeather($city) {
        $api_key = 'ВАШ_API_КЛЮЧ';
        $url = "http://api.openweathermap.org/data/2.5/weather?q={$city}&appid={$api_key}&units=metric&lang=ru";
        
        $response = file_get_contents($url);
        $data = json_decode($response, true);
        
        if ($data['cod'] == 200) {
            $temp = round($data['main']['temp']);
            $description = $data['weather'][0]['description'];
            return "Погода в {$city}: {$temp}°C, {$description}";
        }
        
        return "Не удалось получить погоду для города: {$city}";
    }
}

Советы по улучшению
1. Логирование - сохраняйте все ошибки и запросы
2. Кэширование - используйте Redis или Memcached для частых запросов
3. Безопасность - проверяйте входящие данные, ограничивайте доступ
4. Асинхронность - для долгих операций используйте очереди
5. Масштабирование - разделяйте логику на модули

Заключение
Вы создали работающего Telegram-бота на PHP! Этот пример демонстрирует основные концепции:
· Работу с Telegram Bot API
· Обработку команд и сообщений
· Использование клавиатур
· Настройку вебхуков

Бот можно расширять, добавляя новые команды, интеграции с базами данных и внешними сервисами.

P.S. Не судите строго, это моя одна из первых статей. В дальнейшем постараюсь выкладывать ещё статьи на подобные темы касающиеся как web так и системного программирования.
  • Like
Реакции: admin