Laravel中基于Telegram Bot SDK实现交互式投票功能求助
实现Laravel Telegram交互式投票机器人方案
1. 配置会话跟踪
用Laravel缓存存储用户操作状态,以Telegram用户ID作为缓存键,控制会话有效期(示例设为1小时)。
2. 创建投票启动命令
新建StartVoteCommand触发投票创建流程:
<?php namespace App\Telegram\Commands; use Telegram\Bot\Commands\Command; use Illuminate\Support\Facades\Cache; class StartVoteCommand extends Command { protected $name = 'startvote'; protected $description = '开始创建投票'; public function handle() { $userId = $this->update->getMessage()->getFrom()->getId(); // 标记用户状态为等待输入投票问题 Cache::put("telegram_vote_state_{$userId}", 'waiting_question', 3600); $this->replyWithMessage(['text' => '请输入你的投票问题:']); } }
在TelegramServiceProvider的boot方法注册命令:
$this->app->make('Telegram')->addCommand(StartVoteCommand::class);
3. Webhook控制器处理交互式逻辑
创建控制器处理用户消息,根据当前状态分支执行:
<?php namespace App\Http\Controllers; use Telegram\Bot\Laravel\Facades\Telegram; use Illuminate\Support\Facades\Cache; class TelegramWebhookController extends Controller { public function handle() { $update = Telegram::commandsHandler(true); $message = $update->getMessage(); if (!$message || !$message->getText()) return response()->json(['status' => 'ok']); $userId = $message->getFrom()->getId(); $state = Cache::get("telegram_vote_state_{$userId}"); switch ($state) { case 'waiting_question': $this->saveQuestion($userId, $message->getText()); break; case 'waiting_options': $this->saveOptions($userId, $message->getText()); break; case 'waiting_confirmation': $this->processConfirmation($userId, $message->getText()); break; default: $this->sendDefaultTip($userId); break; } return response()->json(['status' => 'ok']); } // 存储投票问题并引导输入选项 private function saveQuestion(int $userId, string $question) { Cache::put("telegram_vote_question_{$userId}", $question, 3600); Cache::put("telegram_vote_state_{$userId}", 'waiting_options', 3600); Telegram::sendMessage([ 'chat_id' => $userId, 'text' => '请输入投票选项,每个选项换行分隔(最多10个):' ]); } // 验证并存储选项,发起确认 private function saveOptions(int $userId, string $optionsText) { $options = array_filter(explode("\n", $optionsText)); if (count($options) < 2 || count($options) > 10) { Telegram::sendMessage([ 'chat_id' => $userId, 'text' => '选项数量必须在2-10个之间,请重新输入:' ]); return; } Cache::put("telegram_vote_options_{$userId}", $options, 3600); Cache::put("telegram_vote_state_{$userId}", 'waiting_confirmation', 3600); $confirmText = "确认投票信息:\n"; $confirmText .= "问题:" . Cache::get("telegram_vote_question_{$userId}") . "\n"; $confirmText .= "选项:\n"; foreach ($options as $index => $option) { $confirmText .= ($index + 1) . ". {$option}\n"; } $confirmText .= "是否发送至群组?回复「是」或「否」"; Telegram::sendMessage(['chat_id' => $userId, 'text' => $confirmText]); } // 处理确认并发送投票 private function processConfirmation(int $userId, string $reply) { if (strtolower($reply) !== '是') { $this->clearVoteCache($userId); Telegram::sendMessage(['chat_id' => $userId, 'text' => '投票已取消。']); return; } // 替换为你的目标群组ID $groupChatId = '-1001234567890'; try { Telegram::sendPoll([ 'chat_id' => $groupChatId, 'question' => Cache::get("telegram_vote_question_{$userId}"), 'options' => Cache::get("telegram_vote_options_{$userId}"), 'is_anonymous' => true, 'allows_multiple_answers' => false ]); $this->clearVoteCache($userId); Telegram::sendMessage(['chat_id' => $userId, 'text' => '投票已成功发送至群组!']); } catch (\Exception $e) { Telegram::sendMessage([ 'chat_id' => $userId, 'text' => "发送失败:{$e->getMessage()}" ]); } } // 清除投票相关缓存 private function clearVoteCache(int $userId) { Cache::forget("telegram_vote_state_{$userId}"); Cache::forget("telegram_vote_question_{$userId}"); Cache::forget("telegram_vote_options_{$userId}"); } // 默认提示 private function sendDefaultTip(int $userId) { Telegram::sendMessage(['chat_id' => $userId, 'text' => '发送 /startvote 开始创建投票。']); } }
4. 路由配置
在web.php添加Webhook路由:
use App\Http\Controllers\TelegramWebhookController; Route::post('/telegram/webhook', [TelegramWebhookController::class, 'handle']);
关键注意事项
- 确保机器人已加入目标群组并拥有发送消息权限
- 群组ID可通过
/getUpdates命令获取(先关闭Webhook用轮询模式获取) - 可根据需求调整缓存过期时间,或添加非文本消息的错误处理
- 需开启Laravel缓存服务(默认文件缓存即可)
内容的提问来源于stack exchange,提问作者Davron Valiyevich
相关产品推荐
相关产品推荐

