很多开发者初次接触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协议,本地开发可使用 ngroklocalhost.run生成临时公网地址。
  • Web App URL不能包含路径参数或查询字符串,例如 https://example.com/app可以,https://example.com/app?user=1则不行。
  • 如果后续需要修改Web App URL,只需重复上述“Menu Button”设置步骤即可。

备用方案:

  • 如果没有公网服务器,可使用 GitHub PagesVercel部署静态页面作为临时测试。
  • 如果BotFather设置菜单按钮失败,可直接通过 setChatMenuButtonAPI方法设置,请求格式为 https://api.telegram.org/bot<你的Token>/setChatMenuButton,参数中 web_appurl字段填写你的地址。

在机器人消息中嵌入Web App按钮

完成机器人基础设置后,需要让机器人在聊天中发送一个带有“打开Web App”按钮的消息,用户点击后才会触发Web App加载。

具体操作说明:

使用任何编程语言(Python、Node.js、PHP等)向Telegram Bot API发送请求。以Python为例,安装 python-telegram-bot库后,使用 InlineKeyboardMarkupInlineKeyboardButton创建按钮,其中 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获取未加密的用户对象(包含 idfirst_namelast_nameusername等字段)。例如:

`javascript

let user = tg.initDataUnsafe.user;

console.log(user.id, user.first_name);

`

注意事项/小提示:

  • 不要在页面加载完成前调用 tg对象的方法,否则可能报错。建议将代码放在 window.onloadDOMContentLoaded事件中。
  • 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”标签页即可调试。
  • 使用 ngroklocaltunnel将本地开发服务器暴露到公网,结合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()调用时机。