koot-labs/telegram-bot-dialogs

Telegram Bot API PHP SDK 扩展,允许在机器人中实现对话框

0.13.0 2024-06-22 11:50 UTC

This package is auto-updated.

Last update: 2024-09-22 12:20:07 UTC


README

CI Backward compatibility check Type coverage Psalm level

Dialogs

Telegram Bot API PHP SDK 的对话框插件

这是一个为 Telegram Bot API PHP SDK v3.1+ 设计的扩展,允许在Telegram机器人中实现对话框。

关于这个分支

原始包不再维护,并且不支持Telegram Bot API PHP SDK v3。分支的目标是保持包与最新的 Telegram Bot API PHP SDK、PHP 8+ 和 Laravel 功能兼容,专注于稳定性、更好的开发体验和可读性。

安装

您可以通过Composer安装此包

composer require koot-labs/telegram-bot-dialogs

该包将自动注册自身。

您可以使用以下命令发布配置文件

php artisan vendor:publish --tag="telegram-config"

它将创建 config/telegram.php 文件,该文件使用以下环境变量

  • TELEGRAM_DIALOGS_CACHE_DRIVER: 默认值为 database
  • TELEGRAM_DIALOGS_CACHE_PREFIX: 默认值为 tg_dialog_

使用方法

  1. 创建一个对话框类
  2. 创建一个Telegram命令 从命令激活对话框。
  3. 设置控制器类以处理收入webhook请求上的活动对话框。

1. 创建一个对话框类

每个对话框都应该实现为类,该类扩展了基本的 Dialog 类,如您在 HelloExampleDialog 中看到的,或者下面的代码所示

use KootLabs\TelegramBotDialogs\Dialog;
use Telegram\Bot\Objects\Update;

final class HelloDialog extends Dialog
{
    /** @var list<string> List of method to execute. The order defines the sequence */
    protected array $steps = ['sayHello', 'sayOk',];

    public function sayHello(Update $update): void
    {
        $this->bot->sendMessage([
            'chat_id' => $this->getChatId(),
            'text' => 'Hello! How are you?',
        ]);
    }

    public function sayOk(Update $update): void
    {
        $this->bot->sendMessage([
            'chat_id' => $this->getChatId(),
            'text' => 'I’m also OK :)',
        ]);
        
        $this->nextStep('sayHello');
    }
}

2. 创建一个Telegram命令

要启动一个对话框,请使用 DialogManager(如果使用Laravel,则使用 Dialogs Facade)——它将负责在步骤/请求之间存储和恢复 Dialog 实例状态。要执行第一步和后续步骤,请使用更新对象作为参数调用 Dialogs::proceed() 方法。此外,还可以使用类型提示通过依赖注入使用对话框和Telegram命令。

use App\Dialogs\HelloExampleDialog;
use KootLabs\TelegramBotDialogs\Laravel\Facades\Dialogs;
use Telegram\Bot\Commands\Command;

final class HelloCommand extends Command
{
    /** @var string Command name */
    protected $name = 'hello';

    /** @var string Command description */
    protected $description = 'Just say "Hello" and ask few questions in a dialog mode.';

    public function handle(): void
    {
        Dialogs::activate(new HelloExampleDialog($this->update->getChat()->id));
    }
}

3. 设置您的控制器

在您的Laravel webhook控制器中处理请求

use Telegram\Bot\BotsManager;
use KootLabs\TelegramBotDialogs\DialogManager;

final class TelegramWebhookController
{
    public function handle(DialogManager $dialogs, BotsManager $botsManager): void
    {
        $update = $bot->commandsHandler(true);

        $dialogs->exists($update)
            ? $dialogs->proceed($update) // proceed an active dialog (activated in HelloCommand)
            : $botsManager->sendMessage([ // fallback message
                'chat_id' => $update->getChat()->id,
                'text' => 'There is no active dialog at this moment. Type /hello to start a new dialog.',
            ]);
    }
}

Dialog 类 API

  • isEnd() - 检查对话框是否结束
  • 🔐 end() - 结束对话框
  • 🔐 nextStep(string $stepName) - 跳转到特定的步骤,其中 $steppublic 方法名称
  • 🔐 memory - Laravel Collection,用于在步骤之间存储中间数据

DialogManager 类 API

DialogManager 负责以下任务

  • 在步骤/请求之间存储和恢复对话框实例
  • 运行对话框步骤(使用对话框公共API)
  • 切换/激活对话框

对于Laravel应用程序,该包提供了 Dialogs Facade,它代理对 DialogManager 类的调用。

DialogManager 公共API

  • activate(\KootLabs\TelegramBotDialogs\Dialog $dialog) - 激活一个新的对话框(不运行)。同一个用户/聊天可能有多个打开的对话框,DialogManager应该知道哪个是活动的。
  • proceed(\Telegram\Bot\Objects\Update $update) - 运行活动对话框的下一个步骤处理程序(如果存在)
  • exists(\Telegram\Bot\Objects\Update $update) - 根据chat_id和可选的user_id检查给定的更新是否存在对话框
  • setBot(\Telegram\Bot\Api $bot) - 使用非默认Bot进行Telegram Bot API调用

待办事项

v1.0待完成任务

  • 添加文档和示例
  • 支持频道机器人
  • 提高测试覆盖率
  • 提高开发者体验(更干净的API(对话框和DialogManager中的类似方法))
  • 消息类型验证
  • 使用Reach API验证消息类型和内容
  • 支持Dialog步骤的\Iterator和/或\Generator

向后兼容性承诺

Dialogs包使用Semver 2.0。这意味着版本会标记为MAJOR.MINOR.PATCH。只有新的主要版本允许破坏向后兼容性(BC)。

标记为@experimental@internal的类不包括在我们的向后兼容性承诺中。您也不能保证方法返回的值总是相同的。我们保证数据类型不会改变。

PHP 8引入了命名参数,这增加了包维护者的成本并降低了灵活性。Dialogs中方法参数的名称不包括在我们的BC承诺中。