You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Telegram API中点击内联键盘按钮后如何处理用户后续输入?

问题描述

我现在用以下代码实现Telegram机器人的内联键盘:

$arr1 = array('text' => "weather forecast", 'callback_data' => "weatherscript");
$arr2 = array('text' => "some other script", 'callback_data' => "script2");
$keyboard = array(array($arr1, $arr2));
sendInlineKeyboard($bot_id,$json_out->message->chat->id,"Wähle aus",$keyboard);

我想要实现的流程是:

  • 询问用户要执行的脚本(比如天气脚本);
  • 用户点击按钮后,机器人请求用户输入具体城市名称;
  • 用户输入完成后,机器人返回对应城市的天气信息。

现在的困惑是:点击按钮后怎么处理用户后续的输入内容?

解决方案

核心思路是给用户维护一个交互状态,因为Telegram机器人是无状态的HTTP请求模型,每次用户操作(点击按钮/发消息)都是独立请求,必须靠外部存储(数据库、Redis甚至文件)记录用户当前处于哪个交互步骤。

步骤1:处理按钮回调,设置用户状态

当用户点击内联按钮时,Telegram会推送callback_query类型的更新。你需要捕获这个回调,根据callback_data判断用户选择的脚本,给用户设置对应状态,并发送输入提示。

示例代码(以MySQL数据库存储状态为例):

// 处理按钮回调请求
if (isset($update['callback_query'])) {
    $chat_id = $update['callback_query']['message']['chat']['id'];
    $callback_data = $update['callback_query']['data'];
    
    // 根据回调内容设置用户状态
    if ($callback_data === 'weatherscript') {
        // 标记用户当前需要输入城市名
        saveUserState($chat_id, 'waiting_for_city');
        sendMessage($bot_id, $chat_id, "请输入你要查询天气的城市名称:");
    } elseif ($callback_data === 'script2') {
        saveUserState($chat_id, 'waiting_for_script2_input');
        sendMessage($bot_id, $chat_id, "请输入所需参数:");
    }
    
    // 必须回复回调,否则按钮会一直显示加载状态
    answerCallbackQuery($bot_id, $update['callback_query']['id']);
}

// 保存用户状态的函数
function saveUserState($chat_id, $state) {
    $pdo = new PDO('mysql:host=localhost;dbname=your_db', 'db_user', 'db_pass');
    // 用REPLACE实现存在则更新,不存在则插入
    $stmt = $pdo->prepare("REPLACE INTO user_states (chat_id, current_state) VALUES (?, ?)");
    $stmt->execute([$chat_id, $state]);
}

步骤2:根据用户状态处理后续输入

当用户发送文本消息时,先读取该用户的当前状态,再根据状态处理输入内容:

// 处理用户文本消息
if (isset($update['message']['text'])) {
    $chat_id = $update['message']['chat']['id'];
    $user_input = $update['message']['text'];
    $current_state = getUserState($chat_id);
    
    // 按状态分支处理输入
    if ($current_state === 'waiting_for_city') {
        // 调用天气接口获取数据
        $weather_info = fetchWeatherData($user_input);
        sendMessage($bot_id, $chat_id, $weather_info);
        // 处理完成后重置状态
        saveUserState($chat_id, 'idle');
    } elseif ($current_state === 'waiting_for_script2_input') {
        $script_result = handleScript2($user_input);
        sendMessage($bot_id, $chat_id, $script_result);
        saveUserState($chat_id, 'idle');
    } else {
        // 用户无状态时,显示初始内联键盘
        $arr1 = array('text' => "weather forecast", 'callback_data' => "weatherscript");
        $arr2 = array('text' => "some other script", 'callback_data' => "script2");
        $keyboard = array(array($arr1, $arr2));
        sendInlineKeyboard($bot_id, $chat_id, "Wähle aus", $keyboard);
    }
}

// 获取用户当前状态的函数
function getUserState($chat_id) {
    $pdo = new PDO('mysql:host=localhost;dbname=your_db', 'db_user', 'db_pass');
    $stmt = $pdo->prepare("SELECT current_state FROM user_states WHERE chat_id = ?");
    $stmt->execute([$chat_id]);
    $state = $stmt->fetchColumn();
    // 默认返回idle表示无待处理状态
    return $state ?: 'idle';
}

// 模拟天气数据获取函数
function fetchWeatherData($city) {
    // 替换为实际天气API调用逻辑
    return "{$city}今日天气:晴,气温26℃,风力2级";
}

关键注意事项

  • 必须回复callback_query:用户点击按钮后,Telegram会等待机器人调用answerCallbackQuery,否则按钮会一直处于加载状态。
  • 状态存储选择:小体量机器人可以用文件或轻量数据库;用户量大时推荐用Redis这类内存存储,提升读写效率。
  • 状态重置:处理完用户输入后,一定要将状态重置为idle或清除,避免后续消息误触发旧逻辑。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 22:57:51