Laravel 的 Telegram 通知渠道

5.0.0 2024-03-12 05:47 UTC

README

Join PHP Chat Chat on Telegram Latest Version on Packagist Software License Total Downloads

此包使得使用 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')
],

检索聊天 ID

为了发送通知到你的 Telegram Bot 用户/频道或群组,我们需要知道它们的聊天 ID。

这可以通过使用 Telegram Bot API 的 getUpdates 方法获取你的 Bot 的 updates 来完成,具体操作请参考 Telegram Bot API 文档

update 是一个包含相关字段的对象,这些字段基于它代表的更新类型,以下是一些更新对象的示例:messagecallback_querypoll。有关字段列表的完整列表,请参阅 Telegram Bot API 文档

为了使事情变得更简单,该库提供了一个方便的方法,可以用来获取更新,并从中解析出相关的聊天 ID。

请注意,用户必须首先与你的机器人交互,你才能获得他们的聊天 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'];
}

注意:此方法在设置了出站 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 bridge。

你可以在 .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!")
            ->line("Your invoice has been *PAID*")
            ->lineIf($notifiable->amount > 0, "Amount paid: {$notifiable->amount}")
            ->line("Thank you!")

            // (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 消息中的截图预览

Laravel Telegram Notification Example

使用键盘发送

public function toTelegram($notifiable)
{
    return TelegramPoll::create()
        ->to($notifiable)
        ->content('Choose an option:')
        ->keyboard('Button 1')
        ->keyboard('Button 2');
        // ->keyboard('send your number', request_contact: true)
        // ->keyboard('send your location', request_location: true);
}

预览

Laravel Telegram Notification Keyboard

发送投票

public function toTelegram($notifiable)
{
    return TelegramPoll::create()
        ->to($notifiable)
        ->question("Aren't Laravel Notification Channels awesome?")
        ->choices(['Yes', 'YEs', 'YES']);
}

预览

Laravel Telegram Poll Example

附加联系人

public function toTelegram($notifiable)
{
    return TelegramContact::create()
            ->to($notifiable->telegram_user_id) // Optional
            ->firstName('John')
            ->lastName('Doe') // Optional
            ->phoneNumber('00000000');
}

预览

Laravel Telegram Contact Example

附加音频

public function toTelegram($notifiable)
{
    return TelegramFile::create()
            ->to($notifiable->telegram_user_id) // Optional
            ->content('Audio') // Optional Caption
            ->audio('/path/to/audio.mp3');
}

预览

Laravel Telegram Audio Notification Example

附加照片

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');
}

预览

Laravel Telegram Photo Notification Example

附加文档

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');
}

预览

Laravel Telegram Document Notification Example

附加位置

public function toTelegram($notifiable)
{
    return TelegramLocation::create()
        ->latitude('40.6892494')
        ->longitude('-74.0466891');
}

预览

Laravel Telegram Location Notification Example

附加视频

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');
}

预览

Laravel Telegram Video Notification Example

附加 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');
}

预览

Laravel Telegram Gif Notification Example

消息路由

您可以通过向 to($chatId) 方法提供接收者的聊天 ID 来发送通知,就像前面的例子所示,或者在你的可通知模型中添加 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 样式的更多信息,请查看这些 文档
  • line(string $content):添加一条新行消息。
  • lineIf(bool $boolean, string $line):如果给定的条件为真,则添加一条新行消息。
  • escapedLine(string $content):在 Markdown 中添加新行消息的同时转义特殊字符。
  • view(string $view, array $data = [], array $mergeData = []):(可选)如果希望使用视图文件而不是 content() 方法,请提供带有 Telegram 支持的 HTML 或 Markdown 语法内容的 Blade 模板名称。
  • 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 = []):(可选)如果希望使用视图文件而不是 content() 方法,请提供带有 Telegram 支持的 HTML 或 Markdown 语法内容的 Blade 模板名称。
  • file(string|resource|StreamInterface $file, string $type, string $filename = null): 本地文件路径或远程URL,文件的$type类型(例如:photoaudiodocumentvideoanimationvoicevideo_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

变更日志

有关最近更改的更多信息,请参阅变更日志

测试

$ composer test

安全性

如果您发现任何安全相关的问题,请发送电子邮件至syed@lukonet.com,而不是使用问题跟踪器。

贡献

有关详细信息,请参阅贡献指南

鸣谢

许可

MIT许可(MIT)。有关更多信息,请参阅许可文件