Telegram机器人早已不只是聊天工具,它们能处理文本、图片、文件,还能获取用户的位置信息。有了位置数据,机器人可以实现附近推荐、配送跟踪、天气查询等功能。而Telegram原生提供的地图展示能力,让位置分享变得更加直观。本文将从零开始,教你如何让机器人获取用户位置,并以地图卡片的形式发送给用户。
一、准备工作:创建机器人并获取Token
在开始编写代码之前,你需要拥有一个Telegram机器人。打开与@BotFather的对话,发送/newbot,按提示设置机器人昵称和用户名,即可获得一个API Token(形如123456:ABC-DEF...)。这个Token是你调用Bot API的唯一凭证,务必妥善保存。
本文示例代码使用Python语言和python-telegram-bot库(v20+版本)。安装命令:pip install python-telegram-bot。
二、请求用户位置:使用ReplyKeyboardMarkup
要让用户主动分享位置,最便捷的方式是在聊天界面显示一个带有“分享位置”按钮的自定义键盘。Telegram Bot API提供了KeyboardButton,只需将其中的request_location参数设为True,用户点击后就会自动发送自己的当前位置。
以下代码使用ReplyKeyboardMarkup创建一个一次性键盘:
from telegram import ReplyKeyboardMarkup, KeyboardButton
from telegram.ext import Application, CommandHandler, MessageHandler, filters
# 构建请求位置的按钮
location_button = KeyboardButton(text="分享我的位置", request_location=True)
keyboard_markup = ReplyKeyboardMarkup(
[[location_button]],
resize_keyboard=True,
one_time_keyboard=True
)在/start命令处理函数中发送该键盘,用户点击“分享我的位置”后,Telegram客户端会自动发送一条包含location的消息。
三、接收并处理位置消息
当用户点击位置按钮后,Bot会收到一条message类型为location的Update。我们需要在消息处理器中捕获它,并读取其中的经纬度。在python-telegram-bot中,可以通过update.message.location获取。
示例处理函数:
async def location_handler(update, context):
# 获取用户位置对象
user_location = update.message.location
latitude = user_location.latitude
longitude = user_location.longitude
# 可以在这里进行业务处理,例如存入数据库、计算距离等
await update.message.reply_text(f"您的位置:, ")
注意:Telegram的位置消息会同时包含latitude和longitude属性,某些场景下还可能包含horizontal_accuracy(水平精度)等字段,你可以根据需求选择使用。
四、发送原生地图位置给用户
Telegram Bot API提供了sendLocation方法,可以直接向用户发送一个经纬度坐标,客户端会自动展示为一张可交互的地图卡片。这比单纯的文本链接或图片更美观、更实用。
以下是发送原生地图位置的代码:
await context.bot.send_location(
chat_id=update.effective_chat.id,
latitude=latitude,
longitude=longitude
)你还可以在send_location中附加title和address参数,让地图卡片显示具体地址名称。例如:
await context.bot.send_location(
chat_id=update.effective_chat.id,
latitude=latitude,
longitude=longitude,
title="我的当前位置",
address="根据坐标解析出的地址"
)注意:title和address参数仅在Telegram客户端版本较新时支持,且可能存在平台差异。
五、完整示例代码
下面给出一个完整的Telegram机器人脚本,它实现了“请求位置→接收位置→回复地图”的全流程。请将YOUR_TOKEN替换为你自己的Bot Token。
#!/usr/bin/env python3
import asyncio
from telegram import ReplyKeyboardMarkup, KeyboardButton
from telegram.ext import Application, CommandHandler, MessageHandler, filters
BOT_TOKEN = "YOUR_TOKEN"
async def start(update, context):
"""发送带位置请求按钮的启动消息"""
location_button = KeyboardButton(text="分享我的位置", request_location=True)
markup = ReplyKeyboardMarkup(
[[location_button]],
resize_keyboard=True,
one_time_keyboard=True
)
await update.message.reply_text(
"你好!点击下方按钮,即可向你发送地图。",
reply_markup=markup
)
async def location_handler(update, context):
"""处理用户发送的位置消息,并回复原生地图"""
user_location = update.message.location
lat = user_location.latitude
lon = user_location.longitude
# 发送原生地图位置
await context.bot.send_location(
chat_id=update.effective_chat.id,
latitude=lat,
longitude=lon
)
# 也可以额外回复地图链接
map_link = f"https://www.openstreetmap.org/?mlat=&mlon=#map=15//"
await update.message.reply_text(f"也可以点击查看地图:")
def main():
app = Application.builder().token(BOT_TOKEN).build()
app.add_handler(CommandHandler("start", start))
app.add_handler(MessageHandler(filters.LOCATION, location_handler))
print("Bot启动中...")
app.run_polling()
if __name__ == "__main__":
main()运行脚本后,给机器人发送/start,点击“分享我的位置”,机器人就会向你发送一个可缩放的地图卡片。
六、增强功能:发送静态地图图片或链接
除了原生地图卡片,你也可以通过其他方式展示地图:
- 发送地图链接:直接将经纬度拼接到Google Maps、OpenStreetMap等链接中,以文本或Inline Keyboard形式发送。
- 发送静态地图图片:使用Google Static Maps API或百度静态图等生成一张带标记的图片,然后以
sendPhoto发送。优点是无需依赖Telegram客户端的地图渲染。 - 自定义地图服务:对于专业应用,可以调用高德、Mapbox等Web服务,生成更丰富的地图卡片。
例如,Google Maps链接格式:https://www.google.com/maps?q=,;OpenStreetMap链接格式:https://www.openstreetmap.org/?mlat=&mlon=。静态图片示例(需申请API Key):https://maps.googleapis.com/maps/api/staticmap?center=,&zoom=15&sensor=false。
七、注意事项与常见问题
在开发位置相关机器人时,请务必注意以下几点:
- 用户隐私:请求位置前应明确告知用途,避免过度收集。Telegram要求机器人不得在用户未授权时获取位置,用户每次点击位置按钮都被视为主动授权。
- 位置精度:Telegram提供的位置基于GPS/网络定位,通常精度在几十米内。在室内或无GPS环境下可能误差较大,需在文案中提示。
- 权限请求无强制:Telegram无法强制用户分享位置,用户随时可以取消或使用“发送当前位置”的快捷操作。机器人应做好无位置处理的兜底逻辑。
- 使用场景合规:如果机器人涉及商业用途(如配送、定位打卡),请确保符合当地法律法规与Telegram Bot政策。
总结
通过本文,你已经掌握了Telegram机器人获取用户位置并发送地图的完整方法。核心步骤只有三步:使用带request_location=True的KeyboardButton请求位置→在MessageHandler中接收经纬度→调用sendLocation发送地图卡片。结合静态地图或链接,你可以灵活构建各种基于位置的服务。现在,试着写出你的第一个位置机器人吧!