You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Laravel Telegram Bot问题:如何保留对话线程中所有交互按钮

解决Telegram机器人按钮消失的问题

这是Telegram Bot API的默认行为导致的——当用户点击回调按钮时,Laravel Telegram Bot的ask方法默认会编辑原始消息来展示新内容,这就直接把原来的按钮替换掉了,所以你会看到之前的按钮从线程中消失。

下面给你两种可行的解决方案,根据你的需求选择:

方案1:发送新消息而非编辑原消息(推荐)

这个方法能让所有历史消息和按钮都保留在对话线程里,是最符合用户预期的交互方式。核心是把处理后续提问的ask换成reply,因为reply会发送一条全新的消息,不会修改之前的内容。

修改你的控制器代码如下:

$question = Question::create("Hi. What do you need ?")
    ->fallback('Unable to ask question')
    ->callbackId('ask_reason')
    ->addButtons([
        Button::create('1. Test My Account')->value('test'),
        Button::create('2. Delete My Account')->value('delete'),
    ]);

return $this->ask($question, function (Answer $answer) {
    if ($answer->isInteractiveMessageReply()) {
        if ($answer->getValue() === 'test') {
            $question_1 = Question::create("Will you like to continue ?")
                ->fallback('Unable to ask question')
                ->callbackId('ask_continue')
                ->addButtons([
                    Button::create('1. Continue')->value('continue'),
                    Button::create('2. Cancel')->value('cancel'), // 补充取消按钮让交互更完整
                ]);
            
            // 使用reply发送新消息,而非编辑原消息
            return $this->reply($question_1);
        }

        // 处理"Delete My Account"的逻辑同理
        if ($answer->getValue() === 'delete') {
            $deleteQuestion = Question::create("Are you sure you want to delete your account?")
                ->fallback('Unable to ask question')
                ->callbackId('confirm_delete')
                ->addButtons([
                    Button::create('Yes, delete it')->value('confirm_delete'),
                    Button::create('No, go back')->value('cancel_delete'),
                ]);
            
            return $this->reply($deleteQuestion);
        }
    }
});

方案2:在同一条消息中保留所有按钮(不推荐)

如果你坚持要在同一条消息里更新内容并保留之前的按钮,可以在创建新的Question时,把历史按钮也一并添加进去。不过这种方式会让按钮越来越多,容易让用户混淆,仅适合特殊场景:

// 可以通过会话存储历史按钮(需先开启Laravel会话支持)
$previousButtons = [
    Button::create('1. Test My Account')->value('test'),
    Button::create('2. Delete My Account')->value('delete'),
];

$question_1 = Question::create("Will you like to continue ?")
    ->fallback('Unable to ask question')
    ->callbackId('ask_continue')
    ->addButtons(array_merge($previousButtons, [
        Button::create('1. Continue')->value('continue'),
    ]));

return $this->ask($question_1, function (Answer $answer) {
    // 后续逻辑处理...
});

补充说明

  • 为什么ask会替换按钮?因为Laravel Telegram Bot的ask方法内部调用了Telegram API的editMessageText接口,这个接口会完全替换原消息的文本和键盘组件,所以之前的按钮会被清空。
  • 如果需要跟踪用户的对话步骤,建议开启Laravel的会话功能,记录用户当前处于哪个交互阶段,这样即使发送新消息,也能正确处理后续的按钮点击。

内容的提问来源于stack exchange,提问作者Switz

火山引擎 最新活动