如何基于Laravel与irazasyed/telegram-bot-sdk实现Telegram购物机器人自定义信息存MySQL
如何用Laravel和Telegram Bot SDK分步收集用户自定义信息
这个需求其实很常见——Telegram Bot本身没有提供现成的分步表单功能,但我们可以通过状态管理来实现,结合Laravel的数据库模型和irazasyed/telegram-bot-sdk的消息处理能力,完全可以搞定。下面是具体的实现思路和代码示例:
核心思路
Telegram Bot是基于"更新驱动"的,每次用户发送消息都会触发你的webhook。我们需要给每个用户维护一个「当前收集步骤」的状态,比如用户现在需要输入姓名/父亲姓名/地址,然后根据这个状态来处理用户的输入,引导下一步操作。
步骤1:创建用户状态表
首先我们需要一个数据库表来存储用户的状态和已收集的信息。运行Laravel迁移命令生成表:
php artisan make:migration create_user_registration_states_table
然后编辑迁移文件,定义表结构:
public function up() { Schema::create('user_registration_states', function (Blueprint $table) { $table->bigInteger('user_id')->primary(); // 对应Telegram用户ID $table->string('current_step')->default('name'); // 当前收集步骤:name/father_name/address/completed $table->string('name')->nullable(); // 用户自定义姓名 $table->string('father_name')->nullable(); // 父亲姓名 $table->text('address')->nullable(); // 地址 $table->timestamps(); }); }
运行迁移:
php artisan migrate
最后生成对应的Eloquent模型:
php artisan make:model UserRegistrationState
步骤2:编写Webhook处理逻辑
在你的Laravel项目中,找到Telegram Bot的webhook路由(通常在routes/api.php),编写消息处理逻辑:
use Telegram\Bot\Laravel\Facades\Telegram; use Illuminate\Http\Request; use App\Models\UserRegistrationState; Route::post('/telegram/webhook', function (Request $request) { $update = Telegram::commandsHandler(true); $message = $update->getMessage(); // 忽略非文本消息(比如图片、贴纸) if (!$message || !$message->getText()) { return response()->json(['status' => 'ok']); } $userId = $message->getFrom()->getId(); $userInput = $message->getText(); // 触发注册流程的命令(比如用户发送/register) if ($userInput === '/register') { // 初始化或重置用户状态 UserRegistrationState::updateOrCreate( ['user_id' => $userId], ['current_step' => 'name'] ); Telegram::sendMessage([ 'chat_id' => $userId, 'text' => '请输入您的姓名:' ]); return response()->json(['status' => 'ok']); } // 获取用户当前的注册状态 $state = UserRegistrationState::where('user_id', $userId)->first(); if (!$state) { Telegram::sendMessage([ 'chat_id' => $userId, 'text' => '请先发送/register开始注册流程哦~' ]); return response()->json(['status' => 'ok']); } // 根据当前步骤处理用户输入 switch ($state->current_step) { case 'name': // 可选:添加输入验证(比如不能为空) if (empty(trim($userInput))) { Telegram::sendMessage([ 'chat_id' => $userId, 'text' => '姓名不能为空,请重新输入:' ]); break; } $state->name = trim($userInput); $state->current_step = 'father_name'; $state->save(); Telegram::sendMessage([ 'chat_id' => $userId, 'text' => '请输入您父亲的姓名:' ]); break; case 'father_name': if (empty(trim($userInput))) { Telegram::sendMessage([ 'chat_id' => $userId, 'text' => '父亲姓名不能为空,请重新输入:' ]); break; } $state->father_name = trim($userInput); $state->current_step = 'address'; $state->save(); Telegram::sendMessage([ 'chat_id' => $userId, 'text' => '请输入您的详细地址:' ]); break; case 'address': if (empty(trim($userInput))) { Telegram::sendMessage([ 'chat_id' => $userId, 'text' => '地址不能为空,请重新输入:' ]); break; } $state->address = trim($userInput); $state->current_step = 'completed'; $state->save(); // 收集完成,给用户反馈 Telegram::sendMessage([ 'chat_id' => $userId, 'text' => '注册完成!您的信息如下:' . PHP_EOL . '姓名:' . $state->name . PHP_EOL . '父亲姓名:' . $state->father_name . PHP_EOL . '地址:' . $state->address ]); break; case 'completed': Telegram::sendMessage([ 'chat_id' => $userId, 'text' => '您已经完成注册啦!如果需要修改信息,请重新发送/register。' ]); break; default: Telegram::sendMessage([ 'chat_id' => $userId, 'text' => '状态异常,请重新发送/register开始注册。' ]); break; } return response()->json(['status' => 'ok']); });
额外优化建议
- 状态存储方式:如果不需要持久化用户信息,也可以用Redis缓存来存储状态,效率更高,适合临时流程。
- 超时处理:可以给状态表加
expires_at字段,定时清理超过24小时未完成的注册状态。 - 错误处理:可以添加更多输入验证规则(比如姓名长度、地址格式),提升用户体验。
- 中断处理:允许用户发送/cancel中断注册流程,重置状态。
内容的提问来源于stack exchange,提问作者Ahmad Badpey
相关产品推荐
相关产品推荐

