Laravel后端实现Telegram Bot按搜索选项限制输入类型的方案咨询
Laravel 实现Telegram Bot多维度查询功能方案
前置准备
- 推荐使用Laravel生态成熟的Telegram Bot开发包
irazasyed/telegram-bot-sdk,通过composer安装即可:composer require irazasyed/telegram-bot-sdk - 安装完成后发布配置文件,配置你的Bot token等参数即可。
核心逻辑实现
1. 会话状态存储(关键)
要实现“查询完成前不响应其他命令”的需求,需要存储每个用户的临时会话状态,直接用Laravel自带的缓存系统即可,不需要额外建表:
存储键格式示例:
user:{chat_id}:pending_query,值为用户选中的查询类型(user_id/phone/
2. inline keyboard回调处理
用户点击搜索选项后,触发CallbackQuery事件,处理逻辑如下:
// 提取回调数据中的查询类型,比如你的callback_data可以设为 search:user_id、search:email 格式 $type = Str::after($callbackQuery->getData(), 'search:'); $chatId = $callbackQuery->getFrom()->getId(); // 存储用户待输入状态 cache()->put("user:{$chatId}:pending_query", $type, now()->addMinutes(10)); // 按选中类型返回对应提示 match($type) { 'user_id' => $this->telegram->sendMessage(['chat_id' => $chatId, 'text' => '请输入要查询的User ID(仅支持纯数字格式)']), 'phone' => $this->telegram->sendMessage(['chat_id' => $chatId, 'text' => '请输入要查询的手机号码']), 'email' => $this->telegram->sendMessage(['chat_id' => $chatId, 'text' => '请输入要查询的邮箱地址']), default => $this->telegram->sendMessage(['chat_id' => $chatId, 'text' => '无效的查询类型,请重新选择']) };
3. 普通消息优先校验逻辑
所有用户发送的普通消息、命令,都优先检查是否有未完成的查询状态,有则直接走查询校验逻辑,忽略其他命令:
$chatId = $message->getFrom()->getId(); $pendingType = cache()->get("user:{$chatId}:pending_query"); if ($pendingType) { $input = $message->getText(); // 按类型校验输入格式 $valid = match($pendingType) { 'user_id' => preg_match('/^\d+$/', $input), 'phone' => preg_match('/^1[3-9]\d{9}$/', $input), // 可按你的手机号规则调整 'email' => Validator::make(['email' => $input], ['email' => 'required|email'])->passes(), default => false }; if (!$valid) { $errorMsg = match($pendingType) { 'user_id' => '*错误:User ID仅支持纯数字格式,请重新输入*', 'phone' => '*错误:请输入合法的11位手机号码格式,请重新输入*', 'email' => '*错误:请输入合法的邮箱格式,请重新输入*', default => '*错误:无效的查询类型,请重新选择*' }; $this->telegram->sendMessage([ 'chat_id' => $chatId, 'text' => $errorMsg, 'parse_mode' => 'Markdown' ]); return; } // 校验通过,执行数据库查询逻辑 $result = match($pendingType) { 'user_id' => User::where('id', $input)->first(), 'phone' => User::where('phone', $input)->first(), 'email' => User::where('email', $input)->first() }; // 返回查询结果 if ($result) { $this->telegram->sendMessage(['chat_id' => $chatId, 'text' => "查询结果:\n用户ID:{$result->id}\n手机号:{$result->phone}\n邮箱:{$result->email}"]); } else { $this->telegram->sendMessage(['chat_id' => $chatId, 'text' => '未查询到匹配的用户信息']); } // 查询完成,删除临时状态,恢复正常命令响应 cache()->forget("user:{$chatId}:pending_query"); return; } // 没有待查询状态,走正常的命令/消息响应逻辑,比如响应/start返回查询选项键盘
交互效果参考

额外优化点
- 可以加主动超时提示:用Laravel的延迟任务,用户选中查询类型后10分钟如果状态还存在,就给用户发超时提醒,避免用户不知道自己的会话已经锁定
- 可以加取消查询的入口:比如用户输入/cancel可以主动删除待查询状态,不需要等超时
内容的提问来源于stack exchange,提问作者Naowas Morshed Eimon
相关产品推荐
相关产品推荐

