Files
zuevav e5a88665cd mailn
2026-04-30 15:14:09 +03:00

284 lines
7.8 KiB
PHP

<?php
/**
* Telegram Bot API client for posting images and text
* Compatible with PHP 7.2+
*/
class TelegramBot
{
private $botToken;
private $baseUrl = 'https://api.telegram.org/bot';
private $defaultChannels = [];
public function __construct($botToken)
{
$this->botToken = $botToken;
}
/**
* Set default channels for posting
*
* @param array $channels Array of channel usernames or IDs
*/
public function setDefaultChannels($channels)
{
$this->defaultChannels = $channels;
}
/**
* Make API request to Telegram
*
* @param string $method API method
* @param array $params Parameters
* @return array Response
*/
private function request($method, $params = [])
{
$url = $this->baseUrl . $this->botToken . '/' . $method;
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $params,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 60,
CURLOPT_SSL_VERIFYPEER => true,
]);
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
throw new RuntimeException("Telegram API error: {$error}");
}
$data = json_decode($response, true);
if (!$data['ok']) {
throw new RuntimeException("Telegram API error: " . (isset($data['description']) ? $data['description'] : 'Unknown error'));
}
return isset($data['result']) ? $data['result'] : [];
}
/**
* Send a text message
*
* @param string $chatId Chat/Channel ID or username
* @param string $text Message text
* @param string $parseMode Parse mode (HTML, Markdown, MarkdownV2)
* @param bool $disablePreview Disable link preview
* @return array Message info
*/
public function sendMessage($chatId, $text, $parseMode = 'HTML', $disablePreview = false)
{
return $this->request('sendMessage', [
'chat_id' => $chatId,
'text' => $text,
'parse_mode' => $parseMode,
'disable_web_page_preview' => $disablePreview,
]);
}
/**
* Send a single photo
*
* @param string $chatId Chat/Channel ID
* @param string $photo Photo URL or file_id
* @param string $caption Photo caption
* @param string $parseMode Parse mode for caption
* @return array Message info
*/
public function sendPhoto($chatId, $photo, $caption = '', $parseMode = 'HTML')
{
$params = [
'chat_id' => $chatId,
'photo' => $photo,
];
if ($caption) {
$params['caption'] = $caption;
$params['parse_mode'] = $parseMode;
}
return $this->request('sendPhoto', $params);
}
/**
* Send multiple photos as media group (album)
*
* @param string $chatId Chat/Channel ID
* @param array $photos Array of photo URLs
* @param string $caption Caption for first photo
* @param string $parseMode Parse mode
* @return array Messages info
*/
public function sendMediaGroup($chatId, $photos, $caption = '', $parseMode = 'HTML')
{
$media = [];
foreach ($photos as $index => $photo) {
$item = [
'type' => 'photo',
'media' => $photo,
];
// Caption only on first photo
if ($index === 0 && $caption) {
$item['caption'] = $caption;
$item['parse_mode'] = $parseMode;
}
$media[] = $item;
}
return $this->request('sendMediaGroup', [
'chat_id' => $chatId,
'media' => json_encode($media),
]);
}
/**
* Post photos with text to a channel
* Smart method that chooses best approach based on content
*
* @param string $chatId Chat/Channel ID
* @param array $photos Array of photo URLs
* @param string $text Post text
* @param string $parseMode Parse mode
* @return array Result info
*/
public function post($chatId, $photos, $text = '', $parseMode = 'HTML')
{
$photoCount = count($photos);
// Text only
if ($photoCount === 0) {
return ['type' => 'text', 'message' => $this->sendMessage($chatId, $text, $parseMode)];
}
// Single photo
if ($photoCount === 1) {
return ['type' => 'photo', 'message' => $this->sendPhoto($chatId, $photos[0], $text, $parseMode)];
}
// Multiple photos (2-10) - use media group
if ($photoCount <= 10) {
return ['type' => 'album', 'messages' => $this->sendMediaGroup($chatId, $photos, $text, $parseMode)];
}
// More than 10 photos - split into multiple albums
$results = [];
$chunks = array_chunk($photos, 10);
foreach ($chunks as $index => $chunk) {
$caption = ($index === 0) ? $text : '';
$results[] = $this->sendMediaGroup($chatId, $chunk, $caption, $parseMode);
}
return ['type' => 'multiple_albums', 'messages' => $results];
}
/**
* Post to multiple channels at once
*
* @param array $chatIds Array of Chat/Channel IDs
* @param array $photos Array of photo URLs
* @param string $text Post text
* @param string $parseMode Parse mode
* @return array Results for each channel
*/
public function postToMultiple($chatIds, $photos, $text = '', $parseMode = 'HTML')
{
$results = [];
foreach ($chatIds as $chatId) {
try {
$results[$chatId] = [
'success' => true,
'result' => $this->post($chatId, $photos, $text, $parseMode),
];
} catch (Exception $e) {
$results[$chatId] = [
'success' => false,
'error' => $e->getMessage(),
];
}
}
return $results;
}
/**
* Get bot info
*
* @return array Bot info
*/
public function getMe()
{
return $this->request('getMe');
}
/**
* Get chat info
*
* @param string $chatId Chat/Channel ID
* @return array Chat info
*/
public function getChat($chatId)
{
return $this->request('getChat', ['chat_id' => $chatId]);
}
/**
* Validate that bot has access to a channel
*
* @param string $chatId Channel ID or username
* @return array Validation result
*/
public function validateChannel($chatId)
{
try {
$chat = $this->getChat($chatId);
return [
'valid' => true,
'title' => isset($chat['title']) ? $chat['title'] : (isset($chat['username']) ? $chat['username'] : $chatId),
'type' => $chat['type'],
];
} catch (Exception $e) {
return [
'valid' => false,
'error' => $e->getMessage(),
];
}
}
/**
* Format text for Telegram HTML mode
*
* @param string $text Plain text
* @return string Escaped HTML
*/
public static function escapeHtml($text)
{
return htmlspecialchars($text, ENT_QUOTES | ENT_HTML5, 'UTF-8');
}
/**
* Format text for Telegram MarkdownV2 mode
*
* @param string $text Plain text
* @return string Escaped Markdown
*/
public static function escapeMarkdown($text)
{
$chars = ['_', '*', '[', ']', '(', ')', '~', '`', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!'];
foreach ($chars as $char) {
$text = str_replace($char, '\\' . $char, $text);
}
return $text;
}
}