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

Python Telebot:点击按钮调用vivod方法及代码、功能咨询

Telegram债务机器人问题解决方案

需求梳理

  • 点击按钮「Чекнуть долги」时调用vivod方法展示所有债务
  • 检查现有代码的正确性并修复问题
  • 新增功能:点击按钮后输入人名及±金额,修改对应用户的债务金额

现有代码问题修复

  1. SQLite语法错误:原代码中id int auto_increment primary key是MySQL语法,SQLite需改为INTEGER PRIMARY KEY AUTOINCREMENT
  2. 按钮绑定错误:KeyboardButton不能直接传入register_next_step_handler,需通过message_handler监听按钮文本触发对应函数
  3. SQL注入风险:插入数据时使用字符串拼接,改为参数化查询避免注入
  4. 事件监听错误:vivod函数使用callback_query_handler,但ReplyKeyboard按钮触发的是普通消息,需改为message_handler

完整实现代码

import telebot
from telebot import types
import sqlite3

# 替换为你的机器人Token
bot = telebot.TeleBot('-------------------------')
current_user_data = {}  # 存储当前用户临时数据,替代全局变量,支持多用户


@bot.message_handler(commands=['start'])
def start(message):
    # 初始化数据库
    conn = sqlite3.connect('dbOplat.sql')
    cur = conn.cursor()
    # 修正SQLite自增主键语法
    cur.execute('''CREATE TABLE IF NOT EXISTS baza 
                   (id INTEGER PRIMARY KEY AUTOINCREMENT, 
                    nikChela varchar(50), 
                    money int)''')
    conn.commit()
    cur.close()
    conn.close()

    # 创建键盘按钮
    bts = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=2)
    btn_record = types.KeyboardButton("Запись")
    btn_check_debts = types.KeyboardButton("Чекнуть долги")
    btn_edit_debt = types.KeyboardButton("Изменить долг")  # 新增修改按钮
    bts.add(btn_record, btn_check_debts, btn_edit_debt)
    bot.send_message(message.chat.id, 'Привет! Выбери действие:', reply_markup=bts)


# 处理「Запись」按钮点击
@bot.message_handler(func=lambda msg: msg.text == "Запись")
def prodazha(message):
    bot.send_message(message.chat.id, 'Ник чела:')
    bot.register_next_step_handler(message, zapNik)


def zapNik(message):
    user_id = message.chat.id
    current_user_data[user_id] = {'nik': message.text.strip()}
    bot.send_message(message.chat.id, 'Сколько должен?')
    bot.register_next_step_handler(message, dengi)


def dengi(message):
    user_id = message.chat.id
    try:
        dolg = int(message.text.strip())
        nik = current_user_data[user_id]['nik']
        
        # 参数化查询避免SQL注入
        conn = sqlite3.connect('dbOplat.sql')
        cur = conn.cursor()
        cur.execute('INSERT INTO baza (nikChela, money) VALUES (?, ?)', (nik, dolg))
        conn.commit()
        cur.close()
        conn.close()
        
        bot.send_message(message.chat.id, 'Запись сделана успешно')
        del current_user_data[user_id]  # 清除临时数据
    except ValueError:
        bot.send_message(message.chat.id, 'Некорректная сумма! Введи число.')
        bot.register_next_step_handler(message, dengi)


# 处理「Чекнуть долги」按钮点击
@bot.message_handler(func=lambda msg: msg.text == "Чекнуть долги")
def vivod(message):
    conn = sqlite3.connect('dbOplat.sql')
    cur = conn.cursor()
    cur.execute('SELECT nikChela, money FROM baza')  # 只查询需要的字段
    records = cur.fetchall()

    if not records:
        info = 'Нет записанных долгов'
    else:
        info = 'Список долгов:\n'
        for nik, money in records:
            info += f'{nik}: {money}\n'

    cur.close()
    conn.close()
    bot.send_message(message.chat.id, info)


# 新增功能:处理「Изменить долг」按钮点击
@bot.message_handler(func=lambda msg: msg.text == "Изменить долг")
def start_edit_debt(message):
    bot.send_message(message.chat.id, 'Введи ник пользователя:')
    bot.register_next_step_handler(message, get_edit_nik)


def get_edit_nik(message):
    user_id = message.chat.id
    nik = message.text.strip()
    # 先检查用户是否存在
    conn = sqlite3.connect('dbOplat.sql')
    cur = conn.cursor()
    cur.execute('SELECT id FROM baza WHERE nikChela = ?', (nik,))
    exists = cur.fetchone()
    cur.close()
    conn.close()
    
    if exists:
        current_user_data[user_id] = {'nik': nik}
        bot.send_message(message.chat.id, 'Введи сумму для изменения (например: +500 или -300):')
        bot.register_next_step_handler(message, get_edit_amount)
    else:
        bot.send_message(message.chat.id, 'Пользователь не найден!')


def get_edit_amount(message):
    user_id = message.chat.id
    try:
        amount = int(message.text.strip())
        nik = current_user_data[user_id]['nik']
        
        conn = sqlite3.connect('dbOplat.sql')
        cur = conn.cursor()
        # 更新债务金额:原金额加上输入的数值
        cur.execute('UPDATE baza SET money = money + ? WHERE nikChela = ?', (amount, nik))
        conn.commit()
        affected_rows = cur.rowcount
        cur.close()
        conn.close()
        
        if affected_rows > 0:
            bot.send_message(message.chat.id, f'Долг пользователя {nik} обновлен на {amount}!')
        else:
            bot.send_message(message.chat.id, 'Ошибка обновления долга')
        del current_user_data[user_id]
    except ValueError:
        bot.send_message(message.chat.id, 'Некорректная сумма! Введи число с + или -.')
        bot.register_next_step_handler(message, get_edit_amount)


bot.polling(none_stop=True)

关键修改说明

  • 数据库语法修正:将MySQL风格的自增主键改为SQLite支持的INTEGER PRIMARY KEY AUTOINCREMENT
  • 按钮事件处理:用message_handler监听按钮文本,替代错误的register_next_step_handler直接传入按钮构造
  • SQL注入防护:所有数据库操作使用参数化查询(?占位符),避免字符串拼接风险
  • 多用户支持:用current_user_data字典存储每个用户的临时输入数据,替代全局变量chelZapis
  • 新增修改功能:添加「Изменить долг」按钮,实现查询用户、输入增减金额、更新数据库的流程
  • 错误处理:对金额输入做类型校验,避免非数字输入导致崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 17:16:11