codewiser / telegram-channel
Laravel Telegram 通知频道
Requires
- php: ^8.0
- irazasyed/telegram-bot-sdk: ^3.0
- laravel/framework: ^10.0|^11.0
Requires (Dev)
- codewiser/laravel-notifications: ^1.1
- phpunit/phpunit: ^11.1
Suggests
- codewiser/laravel-notifications: Unified contract for notificaion messages of any type
README
本包提供了一种通过 Telegram 发送通知的方法。
安装和设置
包使用 irazasyed/telegram-bot-sdk
。因此,请先遵循Telegram Bot SDK 指示并设置您的第一个 Telegram Bot。您可能需要运行以下命令:
php artisan vendor:publish --tag="telegram-config"
在 config/telegram.php
配置文件中添加 name
参数并注册 DeeplinkCommand
。您可能不需要定义 webhook_url
,因为它将在运行时重新配置。
'bots' => [ 'my_bot' => [ 'name' => env('TELEGRAM_BOT_NAME'), 'token' => env('TELEGRAM_BOT_TOKEN'), 'certificate_path' => env('TELEGRAM_CERTIFICATE_PATH'), //'webhook_url' => env('TELEGRAM_WEBHOOK_URL'), 'commands' => [ \Codewiser\Telegram\Commands\DeeplinkCommand::class ], ], ]
接下来,将 \Codewiser\Telegram\Contracts\TelegramNotifiable
实现到 User
模型中。您可能需要编写迁移...
use \Illuminate\Database\Eloquent\Model; use \Codewiser\Telegram\Contracts\TelegramNotifiable; class User extends Model implements TelegramNotifiable { public function routeNotificationForTelegram($notification = null): mixed { return $this->telegram; } public function setRouteForTelegram($route): void { $this->telegram = $route; $this->save(); } }
现在,创建服务以实现 \Codewiser\Telegram\Contracts\TelegramNotifiableProvider
。这是一个实现示例,您可以根据需要实现它。
use \Codewiser\Telegram\Contracts\TelegramNotifiableProvider; class TelegramUserProvider implements TelegramNotifiableProvider { /** * Issue and remember new token for a given notifiable. */ public function generateToken(TelegramNotifiable $notifiable): string { $token = Str::random(40); cache()->set( $token, $notifiable->getKey(), now()->addMinutes(5) ); return $token; } /** * Find notifiable associated with a given token. */ public function resolveToken(string $token): ?TelegramNotifiable { $key = cache()->pull($token); if ($key) { return User::query()->find($key); } return null; } }
最后,在您的应用程序的 AppServiceProvider
中注册此服务。
public function register() { $this->app->singleton(TelegramNotifiableProvider::class, fn() => new TelegramUserProvider); }
我们已准备好开始。
获取更新
注册 webhook
如果您的 bot 在 config/telegram.php
中配置正确,这足以使用 Telegram Bot SDK
包提供的 telegram:webhook
命令。我们建议您阅读帮助文档。
php artisan help telegram:webhook
本包提供处理传入消息的 webhook 控制器。
例如,上面提到的 DeeplinkCommand
用于处理带 deep link 令牌的 /start
命令。
您可以在 config/telegram.php
中添加任何其他命令处理器。
有关Bot Commands的更多信息。
长轮询
本包带来了 telegram:poll
命令,无需注册 webhook 即可获取更新。只需调用命令即可。
用法
订阅用户
首先,我们需要为用户生成一个 deep link。
use \Illuminate\Http\Request; use \Codewiser\Telegram\TelegramService; class DeeplinkController extends Controller { public function __invoke(Request $request, TelegramService $service) { return $service->getDeeplink($request->user()); } }
用户点击 deep link,打开 Telegram 客户端并点击 Start 按钮。
Codewiser\Telegram\Commands\DeeplinkCommand
处理传入的更新,解析 deep link 令牌并更新 User
的 chat_id
。
目前,此用户拥有 Telegram 路由,可以通过 Telegram 进行通知。
通知用户
要通知用户,请向通知中添加 toTelegram
方法。别忘了将 telegram
添加到 via
方法中。
class Notification extends \Illuminate\Notifications\Notification { /** * Get the notification's delivery channels. */ public function via(object $notifiable): array { return ['mail', 'telegram']; } /** * Get the telegram representation of the notification. */ public function toTelegram(object $notifiable) { // } }
Telegram 通知消息可以是字符串,也可以是数组。
数组键符合Telegram sendMessage 方法。
字符串被解释为 HTML,并将使用 ['parse_mode' => 'HTML']
发送。
失败的通知
当通知无法发送给用户时,会传播 \Illuminate\Notifications\Events\NotificationFailed
事件。
一些失败是可以捕获的。例如,如果用户锁定了一个 bot,我们会收到一个 403
响应状态。在这种情况下,我们应该从未来的通知中取消订阅用户。400
表示聊天未找到。
如果您希望自动取消订阅此类用户,请在应用程序 AppServiceProvider 的 boot 方法中注册事件监听器。
use \Codewiser\Telegram\Listeners\UnsubscribeTelegramNotifiable; use \Illuminate\Notifications\Events\NotificationFailed; public function boot(): void { Event::listen( NotificationFailed::class, UnsubscribeTelegramNotifiable::class, ); }