vance-page / laravel-notification-telegram
Telegram 通知通道用于 Laravel
Requires
- php: ^7.4 || ^8.0
- ext-json: *
- guzzlehttp/guzzle: ^7.0
- illuminate/contracts: ^6.9|^7.0|^8.0|^9.0
- illuminate/notifications: ^6.9|^7.0|^8.0|^9.0
- illuminate/support: ^6.9|^7.0|^8.0|^9.0
Requires (Dev)
- mockery/mockery: ^1.4
- phpunit/phpunit: ^9.0
README
此包使得使用 Laravel 通过 Telegram Bot API 发送 Telegram 通知变得简单。
内容
安装
你可以通过 composer 安装此包
composer require laravel-notification-channels/telegram
设置你的 Telegram 机器人
与 @BotFather 交谈并生成 Bot API Token。
然后,配置你的 Telegram Bot API Token
# config/services.php 'telegram-bot-api' => [ 'token' => env('TELEGRAM_BOT_TOKEN', 'YOUR BOT TOKEN HERE') ],
检索 Chat ID
为了让我们能够将通知发送到你的 Telegram 机器人用户/频道或群组,我们需要知道他们的 Chat ID。
这可以通过使用 Telegram Bot API 的 getUpdates
方法来获取你的 Bot 的 updates 来完成,如 Telegram Bot API 文档 中所述。
一个 update 是一个包含相关字段的对象,这些字段基于它所代表的更新类型,一些更新对象的示例是 message
、callback_query
和 poll
。有关字段列表的完整列表,请参阅 Telegram Bot API 文档。
为了使事情变得更简单,库中提供了一个方便的方法,可以用来获取更新,然后你可以从中解析出相关的 Chat ID。
请注意,用户必须首先与你的机器人互动,你才能获取他们的 Chat ID,然后你可以将其存储在数据库中,用于未来的交互或通知。
以下是获取更新的示例
use NotificationChannels\Telegram\TelegramUpdates; // Response is an array of updates. $updates = TelegramUpdates::create() // (Optional). Get's the latest update. NOTE: All previous updates will be forgotten using this method. // ->latest() // (Optional). Limit to 2 updates (By default, updates starting with the earliest unconfirmed update are returned). ->limit(2) // (Optional). Add more params to the request. ->options([ 'timeout' => 0, ]) ->get(); if($updates['ok']) { // Chat ID $chatId = $updates['result'][0]['message']['chat']['id']; }
注意:如果设置了 outgoing webhook,则此方法将不会工作。
有关 options
的完整参数列表,请参阅 Telegram Bot API 文档。
在 Lumen 中使用
如果你在 Lumen 项目中使用此通知通道,你必须在 bootstrap/app.php
文件中添加以下代码。
# bootstrap/app.php // Make sure to create a "config/services.php" file and add the config from the above step. $app->configure('services'); # Register the notification service providers. $app->register(Illuminate\Notifications\NotificationServiceProvider::class); $app->register(NotificationChannels\Telegram\TelegramServiceProvider::class);
代理或桥接支持
如果你无法在你的国家访问 Telegram Bot API,你可能需要设置代理,请按照以下说明操作 这里,或者通过设置上述 base_uri
配置使用 Web 桥。
你可以在 .env
文件中设置 HTTPS_PROXY
。
使用
你现在可以在通知类中的 via()
方法中使用该通道。
文本通知
use NotificationChannels\Telegram\TelegramMessage; use Illuminate\Notifications\Notification; class InvoicePaid extends Notification { public function via($notifiable) { return ["telegram"]; } public function toTelegram($notifiable) { $url = url('/invoice/' . $this->invoice->id); return TelegramMessage::create() // Optional recipient user id. ->to($notifiable->telegram_user_id) // Markdown supported. ->content("Hello there!\nYour invoice has been *PAID*") // (Optional) Blade template for the content. // ->view('notification', ['url' => $url]) // (Optional) Inline Buttons ->button('View Invoice', $url) ->button('Download Invoice', $url) // (Optional) Inline Button with callback. You can handle callback in your bot instance ->buttonWithCallback('Confirm', 'confirm_invoice ' . $this->invoice->id); } }
以下是上述通知在 Telegram 消息应用中的截图预览
发送投票
public function toTelegram($notifiable) { return TelegramPoll::create() ->to($notifiable) ->question("Aren't Laravel Notification Channels awesome?") ->choices(['Yes', 'YEs', 'YES']); }
预览
附加联系人
public function toTelegram($notifiable) { return TelegramContact::create() ->to($notifiable->telegram_user_id) // Optional ->firstName('John') ->lastName('Doe') // Optional ->phoneNumber('00000000'); }
预览
附加音频
public function toTelegram($notifiable) { return TelegramFile::create() ->to($notifiable->telegram_user_id) // Optional ->content('Audio') // Optional Caption ->audio('/path/to/audio.mp3'); }
预览
附加图片
public function toTelegram($notifiable) { return TelegramFile::create() ->to($notifiable->telegram_user_id) // Optional ->content('Awesome *bold* text and [inline URL](http://www.example.com/)') ->file('/storage/archive/6029014.jpg', 'photo'); // local photo // OR using a helper method with or without a remote file. // ->photo('https://file-examples-com.github.io/uploads/2017/10/file_example_JPG_1MB.jpg'); }
预览
附加文档
public function toTelegram($notifiable) { return TelegramFile::create() ->to($notifiable->telegram_user_id) // Optional ->content('Did you know we can set a custom filename too?') ->document('https://file-examples-com.github.io/uploads/2017/10/file-sample_150kB.pdf', 'sample.pdf'); }
预览
附加位置
public function toTelegram($notifiable) { return TelegramLocation::create() ->latitude('40.6892494') ->longitude('-74.0466891'); }
预览
附加视频
public function toTelegram($notifiable) { return TelegramFile::create() ->content('Sample *video* notification!') ->video('https://file-examples-com.github.io/uploads/2017/04/file_example_MP4_480_1_5MG.mp4'); }
预览
附加 GIF 文件
public function toTelegram($notifiable) { return TelegramFile::create() ->content('Woot! We can send animated gif notifications too!') ->animation('https://sample-videos.com/gif/2.gif'); // Or local file // ->animation('/path/to/some/animated.gif'); }
预览
路由消息
你可以通过将接收者的 Chat ID 提供给 to($chatId)
方法来发送通知,如前面的示例所示,或者在你的可通知模型中添加 routeNotificationForTelegram()
方法。
/** * Route notifications for the Telegram channel. * * @return int */ public function routeNotificationForTelegram() { return $this->telegram_user_id; }
处理响应
您可以使用通知事件来处理Telegram的响应。成功时,您的事件监听器将接收到一个包含各种字段的对象,这些字段适用于通知类型。
关于响应字段的完整列表,请参阅Telegram Bot API的消息对象文档。
按需通知
有时您可能需要向不是您应用程序“用户”的人发送通知。使用
Notification::route
方法,在发送通知之前,您可以指定临时的通知路由信息。更多详情,请查看按需通知文档。
use Illuminate\Support\Facades\Notification; Notification::route('telegram', 'TELEGRAM_CHAT_ID') ->notify(new InvoicePaid($invoice));
发送给多个接收者
使用通知外观,您可以一次性向多个接收者发送通知。
如果您向多个用户发送大量通知,Telegram Bot API将不允许每秒发送超过30条消息。为了获得最佳效果,请考虑将通知分散在8-12小时的大间隔内。
请注意,您的机器人每分钟向同一个群组发送的消息不能超过20条。
如果您超过限制,您将开始收到
429
错误。更多详情,请参考Telegram Bots 常见问题解答。
use Illuminate\Support\Facades\Notification; // Recipients can be an array of chat IDs or collection of notifiable entities. Notification::send($recipients, new InvoicePaid());
可用方法
共享方法
这些方法是可选的,并且适用于所有API方法。
to(int|string $chatId)
:接收者的聊天ID。token(string $token)
:如果您希望为特定通知覆盖默认令牌,请提供机器人令牌。button(string $text, string $url, int $columns = 2)
:添加内联“操作”按钮。您可以添加任意多个,默认情况下它们将两行一列显示。buttonWithCallback(string $text, string $callback_data, int $columns = 2)
:添加带有给定回调数据的内联按钮。您可以添加任意多个,默认情况下它们将两行一列显示。disableNotification(bool $disableNotification = true)
:静默发送消息。用户将收到无声音的通知。options(array $options)
:允许您添加额外的参数或覆盖有效载荷。getPayloadValue(string $key)
:获取给定键的有效载荷值。
Telegram 消息方法
有关支持参数的更多信息,请查看这些文档。
content(string $content, int $limit = null)
:通知消息,支持Markdown。有关支持的Markdown样式信息,请查看这些文档。view(string $view, array $data = [], array $mergeData = [])
:(可选)Blade模板名称,使用Telegram支持的HTML或Markdown语法内容,如果您希望使用视图文件而不是content()
方法。chunk(int $limit = 4096)
:(可选)发送时按部分发送的消息字符块大小(适用于长消息)。注意:分块消息将被限制为每秒一条消息,以符合Telegram的速率限制要求。
Telegram 位置方法
latitude(float|string $latitude)
:位置的纬度。longitude(float|string $longitude)
:位置的经度。
Telegram 文件方法
content(string $content)
:(可选)文件标题,支持Markdown。有关支持的Markdown样式信息,请查看这些文档。view(string $view, array $data = [], array $mergeData = [])
:(可选)Blade模板名称,使用Telegram支持的HTML或Markdown语法内容,如果您希望使用视图文件而不是content()
方法。file(string|resource|StreamInterface $file, string $type, string $filename = null)
: 本地文件路径或远程URL,文件的$type
类型(例如:photo
,audio
,document
,video
,animation
,voice
,video_note
)以及可选的带有扩展名的文件名。例如:sample.pdf
。您可以使用辅助方法而不是使用此方法,以使处理文件附件更容易。photo(string $file)
: 用于附加照片的辅助方法。audio(string $file)
: 用于附加音频文件(MP3文件)的辅助方法。document(string $file, string $filename = null)
: 用于附加文档或任何文件的辅助方法。video(string $file)
: 用于附加视频文件的辅助方法。animation(string $file)
: 用于附加动画GIF文件的辅助方法。voice(string $file)
: 用于附加语音笔记(OPUS编码的.ogg
文件)的辅助方法。videoNote(string $file)
: 用于附加视频笔记文件(最长1分钟,方形视频)的辅助方法。
Telegram 联系人方法
phoneNumber(string $phoneNumber)
: 联系电话号码。firstName(string $firstName)
: 联系者名字。lastName(string $lastName)
: (可选)联系者姓氏。vCard(string $vCard)
: (可选)联系人的vCard。
Telegram 投票方法
question(string $question)
: 投票问题。choices(array $choices)
: 投票选项。
替代方案
对于高级使用,请考虑使用 telegram-bot-sdk 代替。
变更日志
请查看 CHANGELOG 获取有关最近更改的更多信息。
测试
$ composer test
安全
如果您发现任何安全相关的问题,请通过电子邮件 syed@lukonet.com 而不是使用问题跟踪器。
贡献
请查看 CONTRIBUTING 获取详细信息。
致谢
许可证
MIT许可证(MIT)。请查看 许可证文件 获取更多信息。