Telegram机器人不仅是自动回复和通知工具,还能轻松实现问卷调查和投票统计。无论是产品调研、用户反馈,还是群组活动决策,都可以通过机器人快速创建交互式问卷,并实时汇总结果。本教程将使用Python和python-telegram-bot库,从零搭建一个完整的投票机器人,涵盖问卷发布、按钮交互、数据统计和防止重复投票等核心功能。
准备工作:创建机器人与获取API Token
在编写代码之前,需要先在Telegram中创建机器人并获得API Token。
- 打开Telegram,搜索@BotFather。
- 发送
/newbot,按提示输入机器人的显示名称和用户名(必须以bot结尾)。 - 创建成功后,BotFather会返回一条包含API Token的消息,格式类似
123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11。 - 将Token保存下来,后续代码中需要用到。
设计问卷:使用内联键盘(Inline Keyboard)
内联键盘是Telegram机器人实现交互投票的核心组件。与普通键盘不同,内联键盘附着在消息下方,用户点击按钮后,机器人可以接收回调数据,实现动态反馈。
以一个简单的单选投票为例,我们设计一个问题“你最喜欢哪个Telegram功能?”,提供四个选项:频道、群组、机器人、隐私保护。每个按钮绑定一个唯一的callback_data,格式可设为vote_选项名,便于解析。
编写代码:创建机器人与处理投票
以下使用Python的python-telegram-bot库(版本≥20.0)完成开发。首先安装依赖:
pip install python-telegram-bot
然后创建Python文件,例如survey_bot.py,输入以下代码:
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import ApplicationBuilder, CommandHandler, CallbackQueryHandler, ContextTypes
# 存储投票结果和已投票用户
votes = {}
voted_users = set()
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""发送问卷和投票按钮"""
question = "你最喜欢哪个Telegram功能?"
options = ["频道", "群组", "机器人", "隐私保护"]
keyboard = [[InlineKeyboardButton(opt, callback_data=f"vote_")] for opt in options]
reply_markup = InlineKeyboardMarkup(keyboard)
await update.message.reply_text(question, reply_markup=reply_markup)
async def button_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""处理按钮回调,统计票数并展示结果"""
query = update.callback_query
await query.answer()
user_id = query.from_user.id
option = query.data.split("_", 1)[1]
if user_id in voted_users:
await query.edit_message_text("你已经投过票了!")
return
# 记录投票
voted_users.add(user_id)
votes[option] = votes.get(option, 0) + 1
result_text = "\n".join([f": {votes.get(opt, 0)}票" for opt in ["频道", "群组", "机器人", "隐私保护"]])
await query.edit_message_text(f"投票成功!当前结果:\n")
def main():
token = "YOUR_TOKEN" # 替换为自己的Token
app = ApplicationBuilder().token(token).build()
app.add_handler(CommandHandler("start", start))
app.add_handler(CallbackQueryHandler(button_callback))
app.run_polling()
if __name__ == "__main__":
main()
运行此脚本,在Telegram中向你的机器人发送/start,即可看到投票问卷。点击任意选项,机器人会记录票数,并将消息更新为实时统计结果。
关键功能解析:防止重复投票与动态更新
上面的代码实现了两个关键点:
- 防重复投票:通过
voted_users集合存储已投票用户的ID,每次投票前检查,若已存在则提示“你已经投过票了”。 - 动态更新消息:利用
query.edit_message_text()直接替换原消息内容,无需重新发送新消息,界面更干净。
如果需要更复杂的问卷(如多选、匿名投票),可以在回调数据中加入更多信息,并调整存储结构。例如,问卷ID、选项编号等。
数据持久化:保存投票结果
上述代码将数据保存在内存中,机器人重启后会丢失。对于生产环境,建议使用数据库(如SQLite、Redis)或文件存储。以SQLite为例,可以创建一个包含user_id和option字段的表,每次投票时写入,统计时查询。这样即使Bot重启,数据依然保留。
以下是一个简单的SQLite实现示例:
import sqlite3
conn = sqlite3.connect('votes.db', check_same_thread=False)
cursor = conn.cursor()
cursor.execute('CREATE TABLE IF NOT EXISTS votes (user_id INTEGER PRIMARY KEY, option TEXT)')
conn.commit()
# 投票时
cursor.execute('INSERT OR REPLACE INTO votes (user_id, option) VALUES (?, ?)', (user_id, option))
conn.commit()
# 统计
cursor.execute('SELECT option, COUNT(*) FROM votes GROUP BY option')
results = cursor.fetchall()
将以上代码整合到回调函数中,并将初始化部分移到main()函数内即可。
功能扩展:多问题问卷与匿名投票
对于多问题问卷,可以设计不同的callback_data前缀,例如q1_a、q2_b,在回调函数中解析是哪个问题,并分别统计。匿名投票则不需要存储用户ID,只需在机器人设置中不要求用户提供任何个人信息,并且不记录投票者身份。
此外,还可以使用投票插件(Poll)。Telegram原生支持Poll功能,但Poll无法自定义统计逻辑,且不支持匿名(除非指定)。使用机器人实现则灵活性更高,可以控制投票后自动关闭、展示详细图表等。
总结
通过本文的教程,你已经掌握了Telegram机器人发送调查问卷并统计投票结果的核心方法。从创建机器人、设计内联键盘,到处理回调、存储数据,每个步骤都有详细说明。你可以在此基础上扩展更多功能,如定时发布问卷、多组投票对比等。现代开发和运维中,电报机器人是自动化流程的利器,掌握这一技能将为你的工具库增加强大的能力。
如果你在使用过程中遇到问题,欢迎在评论区留言交流。更多机器人开发技巧,请关注本站的“机器人开发”栏目。