1 | <?php |
||
2 | /** |
||
3 | * Telegram Bot |
||
4 | * |
||
5 | * @author mybsdc <[email protected]> |
||
6 | * @date 2020/2/3 |
||
7 | * @time 15:23 |
||
8 | */ |
||
9 | |||
10 | namespace Luolongfei\Lib; |
||
11 | |||
12 | use GuzzleHttp\Client; |
||
13 | |||
14 | class TelegramBot |
||
15 | { |
||
16 | const TIMEOUT = 34.52; |
||
17 | |||
18 | /** |
||
19 | * @var TelegramBot |
||
20 | */ |
||
21 | protected static $instance; |
||
22 | |||
23 | /** |
||
24 | * @var string chat_id |
||
25 | */ |
||
26 | protected $chatID; |
||
27 | |||
28 | /** |
||
29 | * @var string TelegramBot token |
||
30 | */ |
||
31 | protected $token; |
||
32 | |||
33 | /** |
||
34 | * @var Client |
||
35 | */ |
||
36 | protected $client; |
||
37 | |||
38 | public function __construct() |
||
39 | { |
||
40 | $this->chatID = config('telegram.chatID'); |
||
41 | $this->token = config('telegram.token'); |
||
42 | |||
43 | $this->client = new Client([ |
||
44 | 'headers' => [ |
||
45 | 'Content-Type' => 'application/x-www-form-urlencoded' |
||
46 | ], |
||
47 | 'cookies' => false, |
||
48 | 'timeout' => self::TIMEOUT, |
||
49 | 'verify' => config('verifySSL'), |
||
50 | // 'http_errors' => false, |
||
51 | 'debug' => config('debug') |
||
52 | ]); |
||
53 | } |
||
54 | |||
55 | protected static function instance() |
||
56 | { |
||
57 | if (!self::$instance instanceof self) { |
||
0 ignored issues
–
show
introduced
by
![]() |
|||
58 | self::$instance = new self(); |
||
59 | } |
||
60 | |||
61 | return self::$instance; |
||
62 | } |
||
63 | |||
64 | /** |
||
65 | * 发送消息 |
||
66 | * |
||
67 | * @param string $content 支持markdown语法,但记得对非标记部分进行转义 |
||
68 | * @param string $chatID 可单独指定chat_id参数 |
||
69 | * @param bool $isMarkdown 默认内容为Markdown格式,传否则为Html格式 |
||
70 | * @desc 注意对markdown标记占用的字符进行转义,否则无法正确发送,根据官方说明,以下字符如果不想被 Telegram Bot 识别为markdown标记, |
||
71 | * 应转义后传入,官方说明如下: |
||
72 | * In all other places characters '_‘, ’*‘, ’[‘, ’]‘, ’(‘, ’)‘, ’~‘, ’`‘, ’>‘, ’#‘, ’+‘, ’-‘, ’=‘, ’|‘, |
||
73 | * ’{‘, ’}‘, ’.‘, ’!‘ must be escaped with the preceding character ’\'. |
||
74 | * 如果你不转义,且恰好又不是正确的markdown语法,那 Telegram Bot 就只有报错了您勒 |
||
75 | * |
||
76 | * 官方markdown语法示例: |
||
77 | * *bold \*text* |
||
78 | * _italic \*text_ |
||
79 | * __underline__ |
||
80 | * ~strikethrough~ |
||
81 | * *bold _italic bold ~italic bold strikethrough~ __underline italic bold___ bold* |
||
82 | * [inline URL](http://www.example.com/) |
||
83 | * [inline mention of a user](tg://user?id=123456789) |
||
84 | * `inline fixed-width code` |
||
85 | * ``` |
||
86 | * pre-formatted fixed-width code block |
||
87 | * ``` |
||
88 | * ```python |
||
89 | * pre-formatted fixed-width code block written in the Python programming language |
||
90 | * ``` |
||
91 | * 需要注意的是,普通markdown语法中加粗字体使用的是“**正文**”的形式,但是 Telegram Bot 中是“*加粗我呀*”的形式,更多相关信息请 |
||
92 | * 参考官网:https://core.telegram.org/bots/api#sendmessage |
||
93 | * 另外我干掉了“_”、“~”、“-”、“.”和“>”关键字,分别对应斜体、删除线、无序列表、有序列表和引用符号,这几个我可能用不上:) |
||
94 | * |
||
95 | * @return bool |
||
96 | */ |
||
97 | public static function send(string $content, $chatID = '', $isMarkdown = true) |
||
98 | { |
||
99 | if (config('telegram.enable') === false) { |
||
100 | system_log('由于没有启用 Telegram Bot 功能,故本次不通过 Telegram Bot 送信。'); |
||
101 | |||
102 | return false; |
||
103 | } |
||
104 | |||
105 | if ($isMarkdown) { |
||
106 | // 这几个我可能用不上的markdown关键字我就直接干掉了 |
||
107 | $content = preg_replace('/([.>~_-])/i', '\\\\$1', $content); |
||
108 | } |
||
109 | |||
110 | $telegramBot = self::instance(); |
||
111 | |||
112 | $response = $telegramBot->client->post( |
||
113 | sprintf('https://api.telegram.org/bot%s/sendMessage', $telegramBot->token), |
||
114 | [ |
||
115 | 'form_params' => [ |
||
116 | 'chat_id' => $chatID ? $chatID : $telegramBot->chatID, |
||
117 | 'text' => $content, |
||
118 | 'parse_mode' => $isMarkdown ? 'MarkdownV2' : 'HTML', |
||
119 | 'disable_web_page_preview' => true, |
||
120 | 'disable_notification' => false |
||
121 | ], |
||
122 | ] |
||
123 | ); |
||
124 | $rp = json_decode((string)$response->getBody(), true); |
||
125 | |||
126 | return $rp['ok'] ?? false; |
||
127 | } |
||
128 | } |