mailn
This commit is contained in:
@@ -0,0 +1,283 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user