Telegram机器人能否向用户发送短信?如何实现相关功能
核心结论
Telegram 官方 Bot API 不支持直接向用户的手机号发送运营商短信,你要做短信验证可以根据自己的需求选下面两种实现方案,都是Python新手能快速跑通的。
方案1:用Telegram原生手机号授权(零成本、最适合新手)
如果你只是要验证正在和机器人对话的Telegram用户本人的手机号,完全不用自己对接短信服务——Telegram要求用户绑定账号时必须完成手机号短信验证,你可以直接让用户授权把他绑定的手机号发给你的机器人,全程不需要你自己发任何短信。
实现步骤非常简单:
- 先安装最常用的Python Telegram机器人库,命令行执行:
pip install python-telegram-bot==20.7 - 给用户发送消息时,带上特殊的「请求手机号」按钮,用户点击同意后,Telegram会自动把用户的加密手机号信息推送给你的机器人
- 你拿到手机号后直接标记用户验证通过就行,不需要额外校验
最小可运行的示例代码,替换成自己从@BotFather拿到的bot token就能跑:
from telegram import Update, KeyboardButton, ReplyKeyboardMarkup from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, filters, ContextTypes # 替换成你自己的机器人token BOT_TOKEN = "你的机器人TOKEN" async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): # 构造请求手机号的按钮 button = KeyboardButton(text="点击授权我的手机号", request_contact=True) keyboard = ReplyKeyboardMarkup([[button]], resize_keyboard=True, one_time_keyboard=True) await update.message.reply_text("请点击下方按钮完成手机号验证:", reply_markup=keyboard) async def handle_contact(update: Update, context: ContextTypes.DEFAULT_TYPE): # 拿到用户授权的手机号信息 contact = update.effective_message.contact user_phone = contact.phone_number await update.message.reply_text(f"验证通过!你的手机号是:{user_phone}") if __name__ == "__main__": app = ApplicationBuilder().token(BOT_TOKEN).build() app.add_handler(CommandHandler("start", start)) # 专门处理用户发回来的手机号授权信息 app.add_handler(MessageHandler(filters.CONTACT, handle_contact)) print("机器人启动成功") app.run_polling()
这个方案的优缺点:
- 优点:完全免费,不用处理短信发送、验证码防刷、送达率这些麻烦事,代码量极少
- 缺点:只能获取用户当前Telegram账号绑定的手机号,不能给用户自定义输入的任意手机号发验证码
方案2:给任意手机号发送短信验证码
如果你需要让用户输入任意手机号、再发验证码完成验证(比如验证非Telegram绑定的手机号),这部分逻辑和Telegram API没关系,你需要自己对接第三方短信服务商,整个流程是:
- 用户在Telegram对话里给机器人发送要验证的手机号
- 你的代码生成6位随机验证码,存下来(新手练手可以先存在字典里,记得设5分钟过期时间)
- 调用你选的短信服务商的Python SDK,把验证码发到用户填的手机号上
- 用户把收到的验证码发回给机器人,你比对存的验证码和用户发的是否一致,一致就标记验证通过
给新手的实操提醒:
- 选短信服务商的时候优先选带官方Python SDK的,比如国内用阿里云/腾讯云短信、海外用Twilio,直接照着服务商的Python示例代码抄就行,不用自己写复杂的接口请求
- 一定要加频率限制:同一个手机号1分钟内最多发1次验证码,避免被恶意刷走短信额度
- 刚开始练手可以先把「调用短信服务商发消息」的步骤换成打印到控制台,先把整个验证逻辑跑通,再对接真实的短信服务,省得调试的时候浪费短信费
简化版逻辑示例(去掉了短信服务商的具体调用,你换成自己用的服务商代码就行):
import random import time from telegram import Update from telegram.ext import ApplicationBuilder, MessageHandler, filters, ContextTypes BOT_TOKEN = "你的机器人TOKEN" # 新手练手先用字典存验证码,格式是 {用户ID: {"phone":手机号, "code": 验证码, "expire_time": 过期时间戳}} verify_code_storage = {} async def send_verify_code(update: Update, context: ContextTypes.DEFAULT_TYPE): user_id = update.effective_user.id # 假设用户发的消息内容就是手机号,先做简单的格式校验 phone = update.effective_message.text.strip() if not phone.isdigit() or len(phone) != 11: await update.message.reply_text("手机号格式不对,请输入11位手机号") return # 频率限制:1分钟内不能重复发 if user_id in verify_code_storage and time.time() - verify_code_storage[user_id]["expire_time"] < 240: await update.message.reply_text("验证码发送太频繁,请1分钟后再试") return # 生成6位随机验证码 code = str(random.randint(100000, 999999)) # 存到临时存储,5分钟后过期 verify_code_storage[user_id] = {"phone": phone, "code": code, "expire_time": time.time() + 300} # 这里替换成你用的短信服务商的发送代码,练手的时候可以先打印 print(f"给手机号{phone}发送验证码:{code}") await update.message.reply_text("验证码已发送,请输入你收到的6位验证码") async def check_verify_code(update: Update, context: ContextTypes.DEFAULT_TYPE): user_id = update.effective_user.id input_code = update.effective_message.text.strip() if user_id not in verify_code_storage: await update.message.reply_text("请先提交手机号获取验证码") return if time.time() > verify_code_storage[user_id]["expire_time"]: await update.message.reply_text("验证码已过期,请重新获取") del verify_code_storage[user_id] return if input_code == verify_code_storage[user_id]["code"]: await update.message.reply_text("验证通过") del verify_code_storage[user_id] else: await update.message.reply_text("验证码错误,请重新输入") if __name__ == "__main__": app = ApplicationBuilder().token(BOT_TOKEN).build() # 匹配11位手机号的消息,触发发验证码逻辑 app.add_handler(MessageHandler(filters.Regex(r'^1\d{10}$'), send_verify_code)) # 匹配6位数字的消息,触发验证码校验逻辑 app.add_handler(MessageHandler(filters.Regex(r'^\d{6}$'), check_verify_code)) print("机器人启动成功") app.run_polling()
新手避坑提醒
- 不要白费力气找Telegram Bot API里直接发短信的接口,官方从来没开放过这个能力
- 用方案1的手机号授权功能时,拿到的手机号只能用于你告知用户的验证场景,不要随意泄露或者滥用
- 刚开始学的时候先把方案1跑通,熟悉机器人的消息交互逻辑之后,再尝试对接第三方短信服务,不要一开始就搞太复杂的逻辑
内容的提问来源于stack exchange,提问作者Michael Constantine
相关产品推荐
相关产品推荐

