jaggman / telegram-bot-dialogs
Telegram Bot API PHP SDK 扩展,允许在机器人中实现对话
Requires
- php: ^7.4|^8.0
- ext-redis: *
- illuminate/contracts: ^6.0|^7.0|^8.0
- illuminate/support: ^6.0|^7.0|^8.0
- irazasyed/telegram-bot-sdk: ^3.0
- symfony/yaml: 5.*
Requires (Dev)
- phpstan/phpstan: ^0.12.32
This package is auto-updated.
Last update: 2024-09-05 18:08:02 UTC
README
为 Telegram Bot API PHP SDK 提供的扩展,允许在机器人中实现对话
此库允许为您的 Telegram 机器人制作简单的对话,这些对话基于 Telegram Bot SDK。
安装
您可以使用 Composer 轻松安装此包
composer require okaufmann/telegram-bot-dialogs
您可以使用以下命令发布配置文件
php artisan vendor:publish --provider="BotDialogs\DialogsServiceProvider" --tag="config"
每个对话都应该实现为扩展基本 Dialog 的类,如下例所示
use BotDialogs\Dialog; class HelloDialog extends Dialog { // Array with methods that contains logic of dialog steps. // The order in this array defines the sequence of execution. protected $steps = ['hello', 'fine', 'bye']; public function hello() { $this->telegram->sendMessage([ 'chat_id' => $this->getChat()->getId(), 'text' => 'Hello! How are you?' ]); } public function bye() { $this->telegram->sendMessage([ 'chat_id' => $this->getChat()->getId(), 'text' => 'Bye!' ]); $this->jump('hello'); } public function fine() { $this->telegram->sendMessage([ 'chat_id' => $this->getChat()->getId(), 'text' => 'I\'m OK :)' ]); } }
为了初始化新的对话,您必须使用 Dialogs 类的实例添加新的对话实现。并且为了执行第一个和后续步骤,您必须使用更新对象作为参数调用 Dialogs::proceed() 方法。另外,您还可以通过类型提示使用 Telegram 命令和 DI 来使用对话框。
use Telegram\Bot\Commands\Command; use BotDialogs\Dialogs; use App\Dialogs\HelloDialog; class HelloCommand extends Command { protected $name = 'hello'; protected $description = 'Just say "Hello" and ask few questions'; public function __construct(Dialogs $dialogs) { $this->dialogs = $dialogs; } public function handle($arguments) { $this->dialogs->add(new HelloDialog($this->update)); } }
并且在 webhook 控制器中的代码
use Telegram\Bot\Api; use BotDialogs\Dialogs; // ... public function __construct(Api $telegram, Dialogs $dialogs) { $this->telegram = $telegram; $this->dialogs = $dialogs; } // ... $update = $this->telegram->commandsHandler(true); if (!$this->dialogs->exists($update)) { // Do something if there are no existing dialogs } else { // Call the next step of the dialog $this->dialogs->proceed($update); }
使用 Redis 存储对话信息(也包括 Dialog::remember() 方法推送的数据)
高级定义对话步骤
您可以为您的对话步骤定义默认文本回复。为此,您必须将步骤定义为具有名称和响应字段的数组。
class HelloDialog extends Dialog { protected $steps = [ [ 'name' => 'hello', 'response' => 'Hello my friend!' ], 'fine', 'bye' ]; // ... }
在这种情况下,如果您在步骤处理程序内部不需要任何逻辑 - 您可以不定义它。只需将响应放入步骤定义中即可。这对于欢迎消息、提示/建议消息等效果很好。如果您想使用 markdown 格式化响应,只需将 markdown
字段设置为 true
。
此外,您还可以通过定义 jump
和 end
字段来控制步骤中的对话方向。 jump
作为 jump()
方法 - 对话跳转到特定的步骤。 end
字段设置为 true
,则在当前步骤后结束对话。
此外,您还可以使用步骤的 is_dich
(是否为二分问题)选项。如果此选项设置为 true,则可以使用 Dialog 实例的 yes
和 no
字段来检查用户答案。例如
class HelloDialog extends Dialog { protected $steps = [ [ 'name' => 'hello', 'response' => 'Hello my friend! Are you OK?' ], [ 'name' => 'answer', 'is_dich' => true ], 'bye' ]; public function answer() { if ($this->yes) { // Send message "I am fine, thank you!" } elseif ($this->no) { // Send message "No, I am got a sick :(" } } }
在 config/dialogs.php
中,您可以修改 yes/no 意义的别名。
在二分问题中,您通常只需要发送响应并跳转到另一个步骤。在这种情况下,您可以将步骤定义为具有响应并设置它们的名称为二分步骤的 'yes'、'no' 或 'default' 键的值。例如
class HelloDialog extends Dialog { protected $steps = [ [ 'name' => 'hello', 'response' => 'Hello my friend! Are you OK?' ], [ 'name' => 'answer', 'is_dich' => true, 'yes' => 'fine', 'no' => 'sick', 'default' => 'bye' ], [ 'name' => 'fine', 'response' => 'I am fine, thank you!', 'jump' => 'bye', ], [ 'name' => 'sick', 'response' => 'No, I am got a sick :(', ], 'bye' ]; }
在对话框中进行访问控制
您可以通过继承 AuthorizedDialog 类并将 Telegram 用户名放入 $allowedUsers 属性中来使用它。之后,只需列表中的用户就可以开始对话。
Dialog 类的可用方法
start()
- 从第一个步骤开始对话proceed()
- 将对话推进到下一个步骤end()
- 结束对话jump($step)
- 跳转到特定的步骤remember($value)
- 为下一步的使用记住一些信息(目前只支持“短期”记忆,只针对一个步骤)isEnd()
- 检查对话是否结束
Dialogs 类的可用方法
add(Dialog $dialog)
- 添加新的对话get(Telegram\Bot\Objects\Update $update)
- 返回现有对话的对象proceed(Telegram\Bot\Objects\Update $update)
- 运行现有对话的下一个步骤处理程序exists(Telegram\Bot\Objects\Update $update)
- 检查现有对话
在单独的文件中配置步骤
您可以在单独的yaml或php文件中定义对话框配置。为此,在对话框配置文件中设置scenarios
,使用对话框类名作为键,配置文件的路径作为值,例如
'scenarios' => [ HelloDialog::class => base_path('config/dialogs/hello.yml') ],
生产环境中存储在默认缓存实例中的文件配置。正因为如此,您应该在部署脚本中添加php artisan cache:clear
命令。