Как создать Telegram-бот для бизнеса на PHP: уведомления и заказы (2016)
Коротко: Создайте бота через @BotFather, получите token, настройте webhook через setWebhook API (URL на ваш сервер с HTTPS), принимайте обновления POST запросом, отвечайте через sendMessage. Telegram API - простой REST, не нужна библиотека.
Регистрация бота
1. Открыть Telegram → найти @BotFather
2. /newbot → ввести имя → ввести username (должен заканчиваться на 'bot')
3. Получить токен: 123456789:ABCDEF...
Настройка Webhook
<?php
// setup_webhook.php - запустить один раз для настройки
$token = 'YOUR_BOT_TOKEN';
$webhookUrl = 'https://mysite.kg/telegram/webhook.php';
$response = file_get_contents(
"https://api.telegram.org/bot{$token}/setWebhook?url=" . urlencode($webhookUrl)
);
echo $response;
// {"ok":true,"result":true,"description":"Webhook was set"}
// Проверить webhook:
$info = file_get_contents("https://api.telegram.org/bot{$token}/getWebhookInfo");
echo $info;
Класс Telegram API
<?php
// TelegramBot.php
class TelegramBot {
private string $token;
private string $apiUrl;
public function __construct(string $token) {
$this->token = $token;
$this->apiUrl = "https://api.telegram.org/bot{$token}/";
}
public function sendMessage(int|string $chatId, string $text, array $options = []): array {
return $this->call('sendMessage', array_merge([
'chat_id' => $chatId,
'text' => $text,
'parse_mode' => 'HTML', // Поддержка <b>, <i>, <code>
], $options));
}
public function sendMessageWithKeyboard(int $chatId, string $text, array $buttons): array {
return $this->sendMessage($chatId, $text, [
'reply_markup' => json_encode([
'inline_keyboard' => $buttons
// Пример buttons:
// [[['text'=>'✅ Принял', 'callback_data'=>'accept:42'],
// ['text'=>'❌ Отказать', 'callback_data'=>'decline:42']]]
])
]);
}
public function answerCallbackQuery(string $callbackQueryId, string $text = ''): array {
return $this->call('answerCallbackQuery', [
'callback_query_id' => $callbackQueryId,
'text' => $text,
]);
}
public function editMessageText(int $chatId, int $messageId, string $text): array {
return $this->call('editMessageText', [
'chat_id' => $chatId,
'message_id' => $messageId,
'text' => $text,
'parse_mode' => 'HTML',
]);
}
private function call(string $method, array $params): array {
$url = $this->apiUrl . $method;
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($params),
CURLOPT_TIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => true,
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
return $response ?? [];
}
}
Webhook обработчик
<?php
// public/telegram/webhook.php
// Telegram отправляет POST с JSON на этот URL
define('TELEGRAM_TOKEN', 'YOUR_BOT_TOKEN');
define('WEBHOOK_SECRET', 'random-secret-string'); // Проверка что запрос от Telegram
// Проверяем secret token в заголовке (добавлен в Bot API в 2022, в 2016 - по IP)
// В 2016 году проверяли IP адреса Telegram серверов
require_once '../../bootstrap.php';
$update = json_decode(file_get_contents('php://input'), true);
if (!$update) {
http_response_code(400);
exit;
}
$bot = new TelegramBot(TELEGRAM_TOKEN);
// Обработка текстовых сообщений
if (isset($update['message'])) {
handleMessage($bot, $update['message']);
}
// Обработка нажатий на inline-кнопки
if (isset($update['callback_query'])) {
handleCallbackQuery($bot, $update['callback_query']);
}
// Всегда возвращать 200 - иначе Telegram будет повторять запрос
http_response_code(200);
echo 'OK';
function handleMessage(TelegramBot $bot, array $message): void {
$chatId = $message['chat']['id'];
$text = $message['text'] ?? '';
$firstName = $message['from']['first_name'] ?? 'Курьер';
switch ($text) {
case '/start':
$bot->sendMessage($chatId,
"Привет, <b>{$firstName}</b>! 👋\n\n"
. "Этот бот будет присылать вам уведомления о новых заказах.\n\n"
. "Для привязки аккаунта отправьте свой ID курьера:\n"
. "Пример: /bind 42"
);
break;
case (preg_match('/^\/bind (\d+)$/', $text, $matches) ? $text : ''):
$courierId = (int)$matches[1];
CourierRepository::bindTelegram($courierId, $chatId);
$bot->sendMessage($chatId, "✅ Аккаунт привязан. Вы будете получать уведомления о заказах.");
break;
case '/status':
$activeOrders = OrderRepository::getCourierActiveOrders(
CourierRepository::findByChatId($chatId)['id'] ?? 0
);
$text = "📦 <b>Ваши активные заказы:</b>\n\n";
foreach ($activeOrders as $order) {
$text .= "Заказ #{$order['id']} - {$order['address']}\n";
}
$bot->sendMessage($chatId, $text ?: "Активных заказов нет.");
break;
default:
$bot->sendMessage($chatId, "Неизвестная команда. Отправьте /start для начала.");
}
}
function handleCallbackQuery(TelegramBot $bot, array $callbackQuery): void {
$chatId = $callbackQuery['from']['id'];
$queryId = $callbackQuery['id'];
$messageId = $callbackQuery['message']['message_id'];
$data = $callbackQuery['data'];
[$action, $orderId] = explode(':', $data);
$orderId = (int)$orderId;
switch ($action) {
case 'accept':
$courierId = CourierRepository::findByChatId($chatId)['id'];
OrderRepository::assignCourier($orderId, $courierId);
$bot->answerCallbackQuery($queryId, 'Заказ принят ✅');
$bot->editMessageText($chatId, $messageId,
"✅ Заказ #{$orderId} принят.\nВам нужно прибыть: " . OrderRepository::getAddress($orderId)
);
break;
case 'decline':
OrderRepository::release($orderId);
$bot->answerCallbackQuery($queryId, 'Заказ передан другому курьеру');
$bot->editMessageText($chatId, $messageId, "❌ Вы отказались от заказа #{$orderId}.");
break;
}
}
Уведомление курьеров о новых заказах
<?php
// OrderService.php - вызывается когда создаётся новый заказ
class OrderNotifier {
private TelegramBot $bot;
public function notifyAvailableCouriers(array $order): void {
// Найти свободных курьеров в радиусе
$couriers = CourierRepository::getAvailableWithTelegram($order['district']);
foreach ($couriers as $courier) {
$this->bot->sendMessageWithKeyboard(
$courier['telegram_chat_id'],
"🔔 <b>Новый заказ #{$order['id']}</b>\n\n"
. "📍 Адрес: {$order['address']}\n"
. "💰 Сумма: " . number_format($order['total']) . " сом\n"
. "⏰ Время: " . date('H:i', strtotime($order['created_at'])),
[
[
['text' => '✅ Принять', 'callback_data' => 'accept:' . $order['id']],
['text' => '❌ Отказать', 'callback_data' => 'decline:' . $order['id']],
]
]
);
}
}
}
Почему Telegram вместо SMS (2016 в КР)
| SMS | Telegram Bot | |
|---|---|---|
| Стоимость | 3-5 сом/сообщение | Бесплатно |
| Интерактивность | Нет | Кнопки, команды |
| Медиа (фото маршрута) | Нет | Да |
| Охват курьеров (2016) | 100% | ~75% (не все в Telegram) |
Для курьерской службы из 40 человек: экономия $150-200/месяц на SMS + интерактивность (курьер может ответить одной кнопкой). Оставшиеся 25% курьеров без Telegram - получали SMS через резервный канал.