Telegram Bot:PHP实现用户位置共享与任意地点选择的教程
Telegram Bot作为轻量化的交互工具,经常需要实现地理位置相关的功能,比如让用户发送当前位置,或者选择地图上的任意地点。本文将介绍如何使用PHP开发Telegram Bot,实现这两种地理位置交互能力,所有代码都基于Telegram Bot API官方规范,可直接复用。
前置准备
在开始开发前,你需要完成以下准备工作:
- 拥有一个Telegram账号,并且已经通过@BotFather创建了Bot,获取到Bot的Token
- 准备一台可以运行PHP的环境,PHP版本建议在7.4及以上,并且开启curl扩展
- 如果你的Bot需要接收用户消息,需要配置Webhook或者使用长轮询方式获取更新,本文示例采用长轮询方式,更方便本地测试
核心原理说明
Telegram的地理位置相关交互基于两种消息类型:
- 用户共享位置:用户点击Telegram输入框旁的附件按钮,选择「位置」,发送当前定位,Bot会收到类型为
location的Update消息,其中包含经纬度信息 - 用户选择任意地点:Bot可以发送一个带
reply_markup的特殊消息,其中包含request_location参数为true的键盘按钮,用户点击该按钮会弹出地图选择器,选择任意地点后发送的消息同样是location类型,只是位置不是用户当前位置
两种场景的消息结构一致,只是在业务逻辑上可以根据需求区分处理,比如共享位置用于打卡,任意选点用于标记目的地。
PHP实现用户位置共享接收
首先我们实现长轮询获取用户消息,当收到用户发送的共享位置时,解析出经纬度并回复确认信息。下面是一段基础的长轮询处理代码:
<?php
// 替换为你的Bot Token
$botToken = 'YOUR_BOT_TOKEN_HERE';
$apiBase = "https://api.telegram.org/bot{$botToken}";
$lastUpdateId = 0;
// 长轮询获取消息
while (true) {
$params = [
'offset' => $lastUpdateId + 1,
'timeout' => 30 // 长轮询超时时间,单位秒
];
$url = $apiBase . '/getUpdates?' . http_build_query($params);
$response = file_get_contents($url);
$updates = json_decode($response, true);
if ($updates['ok'] && !empty($updates['result'])) {
foreach ($updates['result'] as $update) {
$lastUpdateId = $update['update_id'];
// 处理位置消息
if (isset($update['message']['location'])) {
$chatId = $update['message']['chat']['id'];
$location = $update['message']['location'];
$latitude = $location['latitude'];
$longitude = $location['longitude'];
// 回复用户位置信息
$replyText = "已收到你分享的位置:\n纬度:{$latitude}\n经度:{$longitude}";
$replyParams = [
'chat_id' => $chatId,
'text' => $replyText
];
$replyUrl = $apiBase . '/sendMessage?' . http_build_query($replyParams);
file_get_contents($replyUrl);
}
}
}
// 避免请求过于频繁
sleep(1);
}
?>这段代码会持续监听Bot收到的消息,当用户发送共享位置时,会提取出纬度latitude和经度longitude,然后向用户回复包含位置信息的文本。你可以根据实际需求把经纬度存入数据库,或者调用第三方地图API获取具体地址。
PHP实现任意地点选择功能
要让用户可以选择地图上的任意地点,需要发送一个自定义键盘,键盘按钮设置request_location为true,用户点击后会触发地图选择。下面是发送自定义键盘的示例代码:
<?php
// 替换为你的Bot Token
$botToken = 'YOUR_BOT_TOKEN_HERE';
$apiBase = "https://api.telegram.org/bot{$botToken}";
// 接收用户chat_id,实际场景中可以从消息中获取
$chatId = 'USER_CHAT_ID_HERE';
// 构造自定义键盘,请求位置
$keyboard = [
[
['text' => '选择任意地点', 'request_location' => true]
]
];
$replyMarkup = json_encode([
'keyboard' => $keyboard,
'one_time_keyboard' => true, // 点击后键盘消失
'resize_keyboard' => true // 调整键盘大小适配屏幕
]);
// 发送提示消息和键盘
$params = [
'chat_id' => $chatId,
'text' => '请点击下方按钮,在地图上选择你需要的地点:',
'reply_markup' => $replyMarkup
];
$url = $apiBase . '/sendMessage?' . http_build_query($params);
$response = file_get_contents($url);
echo $response;
?>用户点击「选择任意地点」按钮后,Telegram会弹出地图界面,用户可以在地图上任意点击选择位置,确认后发送的位置同样会被上一步的长轮询代码捕获,解析出对应的经纬度。如果需要区分是共享位置还是任意选点,可以在发送键盘时附带额外的标识参数,或者在业务逻辑中根据场景判断。
常见问题与注意事项
- 长轮询方式适合本地测试,正式上线建议配置Webhook,将消息推送到你的服务器接口,避免长轮询占用资源
- 如果用户发送的位置消息没有
location字段,说明不是位置类型消息,需要做容错处理,避免代码报错 - Telegram Bot API对请求频率有限制,不要短时间内发送大量请求,否则会被暂时封禁
- 如果需要将经纬度转换为具体地址,可以调用公开的地理编码API,注意遵守对应API的使用规范
总结
本文介绍了使用PHP开发Telegram Bot实现地理位置交互的完整流程,包含用户共享位置接收和任意地点选择两个核心功能。两者本质都是处理location类型的Update消息,区别仅在于触发方式的配置。你可以基于这些基础代码,扩展出打卡签到、地点标记、周边服务查询等更多实用功能。