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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:02:04