Telegram Bot Reply Keyboard按钮文本含#号不生效的修复咨询
问题核心定位
- 该异常并非Telegram平台不支持Reply Keyboard按钮文本包含#号,其他Bot能正常展示带#的按钮已经验证了平台对该字符的兼容性
- 问题出在请求Telegram接口时的URL参数编码缺失:URL协议中#代表片段定位符,当参数内容中裸露出现#字符时,从#开始往后的所有内容都会被HTTP客户端识别为本地页面锚点,不会随请求发送到服务端,直接导致reply_markup参数内容残缺、键盘配置失效
- 原代码仅对text参数做了urlencode转义,却将json_encode生成的reply_markup配置内容直接拼接进URL,刚好配置文本内的#触发了URL解析截断,最终表现为键盘无法正常生效
修复方案
- 所有拼接到GET请求URL中的参数值,必须统一完成URL转义,禁止仅对部分参数做编码处理
- 优先使用PHP内置的
http_build_query函数组装请求参数,该函数会自动对所有参数值做合规的URL编码,从根源上避免手动拼接导致的漏转义问题 - 若对URL长度有顾虑,也可以改用POST方式调用接口,将参数放入请求体传递,同样可以规避URL特殊字符截断的问题
- 修复后的可运行代码示例:
$string = "#number 1"; $markup[] = [ ["text" => $string] ]; $keyboard = [ "keyboard" => $markup, "resize_keyboard" => true ]; // 统一组装所有请求参数 $params = [ 'chat_id' => $chat_id, 'text' => 'MENU', 'reply_markup' => json_encode($keyboard) ]; // 自动编码所有参数,生成合规的接口请求链接 $requestUrl = "https://api.telegram.org/bot" . TOKEN . "/sendMessage?" . http_build_query($params); return file_get_contents($requestUrl);
排查验证方法
- 在本地打印最终生成的完整请求链接,检查原#号位置是否被转义为
%23,如果#号直接裸露在URL中,就会触发截断问题 - 可以对比原代码拼接的未编码链接,查看#位置之后的内容是否被完整截断,是否存在reply_markup参数值残缺的问题
内容的提问来源于stack exchange,提问作者MehdiAbolhassani
相关产品推荐
相关产品推荐

