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

Python Telegram投注机器人问题:按ID调用InlineKeyboardButton及多赛事投注

解决Telegram模拟投注机器人多赛事独立投注问题

我正在开发一款模拟投注平台的Python Telegram机器人,需求是:

  • 展示赛事列表,用户选择任意赛事时唤起该赛事的投注选项
  • 用户选择支持的队伍后,对应赛事的奖池金额累加并显示实时总额
  • 切换其他赛事时,独立执行上述投注逻辑

但当前代码仅能处理单个赛事,无法实现多赛事独立投注功能,请求协助解决。

原代码:

from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.decorators import api_view

from .serializers import BetSerializer
from api.models import Bets   
from aiogram import Bot, Dispatcher, executor, types


from aiogram import Bot, Dispatcher, executor, types
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton


import telegram

keyboard_inline = types.InlineKeyboardMarkup()
kb_inline = types.InlineKeyboardMarkup()
button1 = types.InlineKeyboardButton(text="Team 1", callback_data="team_1")
button2 = types.InlineKeyboardButton(text="Team 2", callback_data="team_2")
button3 = types.InlineKeyboardButton(text="result", callback_data="result")
button4 = types.InlineKeyboardButton(text="FCB vs PSG", callback_data="bet_1")
button5 = types.InlineKeyboardButton(text="RMD vs MCI", callback_data="bet_2")
button6 = types.InlineKeyboardButton(text="CMR vs BRS", callback_data="bet_3")
keyboard_inline.add(button1, button2)
keyboard_inline.add(button3)
kb_inline.add(button4)
kb_inline.add(button5)
kb_inline.add(button6)



bot = Bot(token='TOKEN')
dp = Dispatcher(bot)


@dp.message_handler(commands=['start'])
async def welcome(message: types.Message):
    await message.reply("Hello! Im Lele bot, Please follow the instruction")
    


@dp.message_handler(commands=['bet'])
async def option(message):
    global a, b
    a = 0
    b = 0
    await message.reply("Select a team:", reply_markup=kb_inline)
    # await bot.send_message(message.chat.id, "Team 1 - " + str(a) + " FCFA\nTeam 2 - " + str(b) +" FCFA")


@dp.callback_query_handler(lambda call: True)
async def choice(call: types.CallbackQuery):
    global a, b
    if call.data == "bet_1":
        
        await bot.send_message(call.message.chat.id, "Select a team:", reply_markup=keyboard_inline)
    if call.data == "team_1":
        a += 100
        await bot.send_message(call.message.chat.id, "Team 1 - " + str(a) + " FCFA\nTeam 2 - " + str(b) +" FCFA")
    elif call.data == "team_2":
        b += 100
        await bot.send_message(call.message.chat.id, "Team 1 - " + str(a) + " FCFA\nTeam 2 - " + str(b) +" FCFA")
    elif call.data == "result":
        sum = a + b
        print(sum)
        await bot.send_message(call.message.chat.id, "---CAGNOTTE---\n"
                                                     "Total = " + str(sum) + " fCFA")
        a = b = 0
        
    await call.answer()

executor.start_polling(dp)

问题核心

原代码用全局变量a、b记录投注额,无法区分不同赛事的数据源,导致切换赛事后数据混乱。以下是针对性修改方案:

修改后的完整代码

from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.decorators import api_view

from .serializers import BetSerializer
from api.models import Bets   
from aiogram import Bot, Dispatcher, executor, types
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
import telegram

# 定义赛事列表:键为赛事ID,值为赛事名称
EVENTS = {
    "bet_1": "FCB vs PSG",
    "bet_2": "RMD vs MCI",
    "bet_3": "CMR vs BRS"
}

# 全局字典存储各赛事独立投注数据:{赛事ID: {'team1': 金额, 'team2': 金额}}
bet_data = {event_id: {'team1': 0, 'team2': 0} for event_id in EVENTS.keys()}

# 生成赛事选择键盘
event_selection_kb = InlineKeyboardMarkup()
for event_id, event_name in EVENTS.items():
    btn = InlineKeyboardButton(text=event_name, callback_data=f"select_event_{event_id}")
    event_selection_kb.add(btn)

bot = Bot(token='TOKEN')
dp = Dispatcher(bot)


@dp.message_handler(commands=['start'])
async def welcome(message: types.Message):
    await message.reply("Hello! Im Lele bot, Please follow the instruction")


@dp.message_handler(commands=['bet'])
async def show_event_list(message):
    await message.reply("Select an event:", reply_markup=event_selection_kb)


def get_bet_keyboard(event_id):
    """生成指定赛事的专属投注键盘"""
    kb = InlineKeyboardMarkup()
    kb.add(
        InlineKeyboardButton(text="Team 1", callback_data=f"bet_team1_{event_id}"),
        InlineKeyboardButton(text="Team 2", callback_data=f"bet_team2_{event_id}")
    )
    kb.add(InlineKeyboardButton(text="Show Total Pool", callback_data=f"show_total_{event_id}"))
    return kb


@dp.callback_query_handler(lambda call: call.data.startswith("select_event_"))
async def select_event(call: types.CallbackQuery):
    # 解析回调数据中的赛事ID
    event_id = call.data.split("_")[-1]
    await bot.send_message(
        call.message.chat.id,
        f"You selected {EVENTS[event_id]}\nChoose a team to bet:",
        reply_markup=get_bet_keyboard(event_id)
    )
    await call.answer()


@dp.callback_query_handler(lambda call: call.data.startswith("bet_team"))
async def process_bet(call: types.CallbackQuery):
    # 解析操作类型和对应赛事ID
    parts = call.data.split("_")
    team = parts[2]
    event_id = parts[3]
    
    # 更新对应赛事的投注金额
    bet_data[event_id][team] += 100
    team1_amount = bet_data[event_id]['team1']
    team2_amount = bet_data[event_id]['team2']
    
    await bot.send_message(
        call.message.chat.id,
        f"{EVENTS[event_id]} Bet Status:\n"
        f"Team 1 - {team1_amount} FCFA\n"
        f"Team 2 - {team2_amount} FCFA"
    )
    await call.answer()


@dp.callback_query_handler(lambda call: call.data.startswith("show_total_"))
async def show_total_pool(call: types.CallbackQuery):
    event_id = call.data.split("_")[-1]
    total = bet_data[event_id]['team1'] + bet_data[event_id]['team2']
    await bot.send_message(
        call.message.chat.id,
        f"---{EVENTS[event_id]} CAGNOTTE---\n"
        f"Total Pool = {total} FCFA"
    )
    await call.answer()


executor.start_polling(dp)

关键改动说明

  1. 多赛事数据隔离:用bet_data字典替代全局变量,每个赛事的投注数据独立存储,互不干扰
  2. 回调数据带赛事标识:所有操作的回调数据都带上赛事ID后缀,确保操作能精准定位到对应赛事
  3. 动态生成专属键盘:新增get_bet_keyboard函数,根据赛事ID生成专属投注键盘,避免不同赛事的操作混淆
  4. 拆分回调逻辑:按操作类型(选择赛事、投注、查看总额)拆分处理函数,代码逻辑更清晰易维护

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 02:25:20