很多开发者初次接触Telegram Web App API时,常常被官方文档的复杂结构搞晕,不知道如何让机器人返回一个Web App,更不清楚前端页面如何与Telegram客户端通信。明明按照文档配置了按钮,点击后却白屏或提示“无法加载”,或者前端无法获取用户身份信息。本文将手把手教你从创建机器人到成功调用Web App API的完整流程,解决实际开发中的常见障碍。
准备开发环境与创建机器人
这是接入Telegram Web App API的第一步,没有正确的机器人Token和基础配置,后续所有操作都无法进行。
具体操作说明:
首先,打开Telegram客户端,搜索 @BotFather并进入对话。发送 /newbot命令,按照提示设置机器人的名称和用户名(用户名必须以 bot结尾)。创建成功后,BotFather会返回一个 API Token,形如 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11,请立即复制并保存到安全位置。接着,发送 /mybots命令,选择刚创建的机器人,点击 Bot Settings,再点击 Menu Button,选择 Web App并输入你的Web App URL(例如 https://yourdomain.com/app)。最后,返回BotFather主界面,发送 /setdomain命令,绑定你的Web App域名(必须使用HTTPS)。
注意事项/小提示:
- 必须使用HTTPS协议,本地开发可使用 ngrok或 localhost.run生成临时公网地址。
- Web App URL不能包含路径参数或查询字符串,例如
https://example.com/app可以,https://example.com/app?user=1则不行。 - 如果后续需要修改Web App URL,只需重复上述“Menu Button”设置步骤即可。
备用方案:
- 如果没有公网服务器,可使用 GitHub Pages或 Vercel部署静态页面作为临时测试。
- 如果BotFather设置菜单按钮失败,可直接通过 setChatMenuButtonAPI方法设置,请求格式为
https://api.telegram.org/bot<你的Token>/setChatMenuButton,参数中web_app的url字段填写你的地址。
在机器人消息中嵌入Web App按钮
完成机器人基础设置后,需要让机器人在聊天中发送一个带有“打开Web App”按钮的消息,用户点击后才会触发Web App加载。
具体操作说明:
使用任何编程语言(Python、Node.js、PHP等)向Telegram Bot API发送请求。以Python为例,安装 python-telegram-bot库后,使用 InlineKeyboardMarkup和 InlineKeyboardButton创建按钮,其中 web_app参数传入你的Web App URL。核心代码如下:
`python
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
button = InlineKeyboardButton(text="打开应用", web_app={"url": "https://yourdomain.com/app"})
keyboard = InlineKeyboardMarkup([[button]])
await update.message.reply_text("点击下方按钮打开Web App:", reply_markup=keyboard)
`
发送后,用户会在聊天中看到带有“打开应用”文字的内联按钮。点击按钮,Telegram客户端会弹出Web App页面。
注意事项/小提示:
- 按钮的
text参数建议简短明确,例如“开始使用”、“打开商店”等。 - 如果用户使用的是Telegram桌面版,Web App会在新窗口打开;移动端则会在应用内全屏打开。
- 一个消息中可以包含多个Web App按钮,但每个按钮必须指向不同的URL(或相同URL),且不能与其他类型的按钮(如回调按钮)混用。
备用方案:
- 如果不想使用内联按钮,也可以使用 ReplyKeyboardMarkup中的
KeyboardButton,设置其web_app属性,效果类似但显示在输入框上方。 - 如果机器人需要在群组中发送Web App按钮,确保机器人有发送消息的权限,且群组未限制机器人功能。
前端页面初始化与Telegram Web App对象
当用户点击按钮后,Web App页面被加载,此时需要在页面中正确初始化Telegram Web App对象,否则无法获取用户数据或关闭应用。
具体操作说明:
在Web App的HTML页面中,在 标签内或页面加载完成后,添加以下JavaScript代码:
`javascript
let tg = window.Telegram.WebApp;
tg.ready(); // 通知Telegram客户端页面已准备就绪
`
tg.ready()方法是必须调用的,它告诉Telegram客户端页面已经加载完成,可以安全地调用其他API了。之后,你可以通过 tg.initData获取初始化数据(一个包含用户信息的加密字符串),通过 tg.initDataUnsafe获取未加密的用户对象(包含 id、first_name、last_name、username等字段)。例如:
`javascript
let user = tg.initDataUnsafe.user;
console.log(user.id, user.first_name);
`
注意事项/小提示:
- 不要在页面加载完成前调用
tg对象的方法,否则可能报错。建议将代码放在window.onload或DOMContentLoaded事件中。 initData是一个经过HMAC-SHA256签名的字符串,可用于后端验证用户真实性;initDataUnsafe仅供前端快速获取用户信息,不可完全信任。- 如果页面在Telegram客户端外(如普通浏览器)打开,
window.Telegram可能不存在,需要做兼容处理:if (window.Telegram && window.Telegram.WebApp) { ... }。
备用方案:
- 如果需要在页面加载前就获取Telegram对象,可以使用Telegram提供的 Web App SDK,通过CDN引入 ,该脚本会自动注入
window.Telegram对象。 - 如果
tg.initDataUnsafe返回undefined,检查机器人是否在 Privacy Mode下,或者用户是否通过匿名方式打开Web App(例如从频道按钮进入)。
实现前端与Telegram客户端的双向通信
Web App不仅仅是一个静态页面,它需要能够与Telegram客户端交互,例如关闭应用、显示主按钮、发送数据回机器人等。
具体操作说明:
1. 关闭Web App:调用 tg.close()方法即可关闭当前Web App页面。例如在用户完成操作后使用。
2. 显示主按钮:Telegram客户端在Web App底部会有一个默认的“关闭”按钮,你可以通过 tg.MainButton对象自定义它。设置文本和点击事件:
`javascript
tg.MainButton.setText("提交");
tg.MainButton.onClick(function() {
let data = { action: "submit", value: "some_data" };
tg.sendData(JSON.stringify(data)); // 将数据发送回机器人
tg.close();
});
tg.MainButton.show();
`
3. 发送数据回机器人:使用 tg.sendData(data)方法,data必须是字符串(通常为JSON字符串)。机器人会通过 message.web_app_data字段接收到该数据。
4. 监听客户端事件:例如 tg.onEvent('themeChanged', function() { ... })可监听Telegram主题变化,动态调整页面样式。
注意事项/小提示:
sendData只能在用户点击主按钮或内联按钮后触发,不能在页面加载时自动调用。- 主按钮的文本长度建议不超过64个字符,否则可能被截断。
- 如果需要在发送数据后立即关闭应用,确保
sendData调用在close之前,因为关闭后数据传输可能中断。
备用方案:
- 如果不需要主按钮,也可以使用
tg.BackButton显示返回按钮,并监听其点击事件。 - 对于更复杂的通信需求,可以使用
tg.postEvent方法向客户端发送自定义事件,但需要客户端版本支持(Telegram 8.0以上)。
验证Web App集成是否成功
完成上述步骤后,需要实际测试整个流程,确保从点击按钮到数据返回机器人一切正常。
具体操作说明:
1. 在Telegram客户端中,找到你的机器人,点击“打开应用”按钮,观察Web App是否正常加载并显示页面。
2. 在Web App中,通过 console.log(tg.initDataUnsafe)输出用户信息,在开发者工具的控制台中查看是否正确显示用户ID和名称。
3. 点击你设置的主按钮(例如“提交”),观察Web App是否关闭,并返回聊天界面。
4. 在机器人后端,监听 message更新,检查是否收到 web_app_data字段。以Python为例:
`python
if update.message and update.message.web_app_data:
data = update.message.web_app_data.data
print(f"收到Web App数据:{data}")
`
5. 测试异常情况:在普通浏览器中打开Web App URL,确认页面有降级处理(例如显示“请在Telegram内打开”)。
注意事项/小提示:
- 测试时建议使用真实Telegram账号,不要使用测试环境或第三方客户端。
- 如果Web App白屏,检查控制台是否有跨域或资源加载错误,确保所有资源(JS、CSS、图片)使用HTTPS。
- 如果收不到
web_app_data,检查sendData是否在MainButton.onClick回调内调用,且数据格式为字符串。
备用方案:
- 如果无法在真实设备上测试,可使用Telegram Desktop的 WebView调试工具:在桌面版按
Ctrl+Shift+I打开开发者工具,切换到“WebView”标签页即可调试。 - 使用 ngrok或 localtunnel将本地开发服务器暴露到公网,结合Telegram移动端进行实时调试。
常见问题补充
问:Web App页面加载后一直显示“Loading...”怎么办?
答:检查页面是否调用了 tg.ready()方法,且该方法在页面完全加载后执行。另外,确保Web App URL没有重定向,Telegram客户端只允许一次302跳转。
问:用户点击按钮后,Web App在部分手机上无法全屏显示?
答:这是Telegram客户端的版本差异。确保用户Telegram版本不低于8.0。可以在页面中通过 tg.isExpanded判断是否全屏,如果不是,调用 tg.expand()尝试展开。
问:如何在后端验证 initData的真实性?
答:使用你的机器人Token对 initData字符串进行HMAC-SHA256签名验证,具体算法参考Telegram官方文档的“Validating data received via the Web App”部分。简而言之,检查 hash参数是否与计算出的签名一致。
问:Web App能否发送照片或文件到聊天?
答:不能直接发送。Web App只能通过 sendData发送字符串数据。如果需要发送文件,需在Web App内让用户上传到你的服务器,然后通过机器人API的 sendDocument方法由机器人代为发送。
总结:
接入Telegram Web App API的核心在于正确配置机器人菜单按钮、在前端调用
tg.ready()初始化并利用initDataUnsafe获取用户信息,最后通过主按钮和sendData实现数据回传;遇到问题时优先检查HTTPS、URL配置和ready()调用时机。