2022年4月Telegram的MiniApp(之前为Web App,6.0版后改名为Mini App)上线,Mini Apps(简称 TMAs,中文名:小程序)很可能会变成一个类似于微信小程序的平台,使得Telegram 更接近一个“超级应用”。目前,电报小程序推出不久,版本还在快速迭代中,开发人员也较少,但电报庞大的用户群基础很可能会产生大量的小程序。
作为Web3的开发者,大多数应用都是前端和区块链直接交互,但电报bot只支持消息通过电报服务和bot所在的服务器进行交互,导致大量DAPP无法给到用户可靠的账户安全保障。电报小程序在电报应用中“嵌入”了Web前端应用,通过它与区块链和智能合约直接交互,将账户信息通过安全策略在本地进行保存,大幅度提高账户安全性。同时,将与区块链无关的业务逻辑通过bot与服务器进行交互,提高用户体验。
所以,Telegram+小程序+bot+智能合约的开发模式,可能会称为一种全新的Web3开发技术栈。事实上,从时间上看,电报小程序与TON链同时推出,也可能有这方面的用意。但是这种开发模式不仅仅适用于电报和TON链,更适用于用户量庞大的各种EVM链。
目前,尚未有中文教程对电报小程序做过系统介绍,笔者在开发过程中学习并翻译了官方开发文档如下。
1. Telegram Mini Apps(电报小程序)简介
通过电报小程序(Mini Apps),开发者可以使用JavaScript创建无限灵活的前端应用,直接在Telegram内启动小程序,并取代相类似功能的普通网站。
与电报机器人类似,电报小程序支持无缝授权,支持20多家支付提供商(包括Google Pay和Apple Pay)的集成支付,并向用户发送定制的推送通知等功能。
添加 @DurgerKingBot,体验下电报小程序。
2. 更新
2023年9月22日
Bot API 6.9
- 向
WebApp
类添加了cloudStorage
属性。 - 向
WebApp
类添加了requestWriteAccess
和requestContact
方法。 - 向
WebAppUser
类添加了added_to_attachment_menu
和allows_write_to_pm
属性。 - 添加了
writeAccessRequested
和contactRequested
事件。 - 通过
setHeaderColor
方法可设置任何标题颜色。
2023年4月21日
Bot API 6.7
- 支持通过
内联查询inline query
和直接链接direct link
启动小应用程序。 - 向
WebApp类
添加了switchInlineQuery
方法。
2022年12月30日
Bot API 6.4
- 向
WebApp
类添加了platform
属性,方法openLink
的可选参数options
,以及showScanQrPopup
、closeScanQrPopup
、readTextFromClipboard
方法。 - 添加了
qrTextReceived
、clipboardTextReceived
事件。
2022年8月12日
Bot API 6.2
- 向
WebApp
类添加了isClosingConfirmationEnabled
属性,以及enableClosingConfirmation
、disableClosingConfirmation
、showPopup
、showAlert
、showConfirm
方法。 - 向
WebAppUser
类添加了is_premium
属性。 - 添加了
popupClosed
事件。
2022年6月20日
Bot API 6.1
- 在群组、超级群组和频道聊天中,添加了使用添加到
Attachment menu附件菜单
的机器人的能力。 - 添加了支持
t.me
链接,可用于选择打开附件菜单的聊天。 - 向
WebApp
类添加了version
、headerColor
、backgroundColor
、BackButton
、HapticFeedback
属性,以及isVersionAtLeast
、setHeaderColor
、setBackgroundColor
、openLink
、openTelegramLink
、openInvoice
等方法。 - 向
ThemeParams
类添加了secondary_bg_color
属性。 - 向
MainButton
类添加了offClick
方法。 - 向
WebAppInitData
类添加了chat
、can_send_after
属性。 - 添加了
backButtonClicked
、settingsButtonClicked
、invoiceClosed
事件。
3. 设计小程序
3.1 配色方案
小程序始终实时接收用户当前颜色主题的数据,因此您可以调整界面的外观以匹配它。例如,当用户在白天和夜间模式之间切换或使用各种自定义主题。
3.2 设计准则
Telegram以其迅捷、流畅和一致的跨平台设计而闻名。您的小程序在理想情况下应反映这些原则:
- 所有元素应具有响应性,并采用以
移动设备
为优先的设计方法。 - 交互元素应模仿已存在的UI组件的样式、行为和意图。
- 所有动画应该流畅,理想情况下为60帧每秒。
- 所有输入和图像应包含标签,以便实现无障碍访问。
- 应用程序应通过API提供的基于主题的动态颜色,并相应地使用它们,以提供无缝的体验。
4. 启动小程序
Telegram目前支持六种不同的方式启动小程序:
- 通过键盘按钮 keyboard button
- 通过内联按钮 inline button
- 通过机器人菜单按钮 menu button
- 通过内联模式 inline mode
- 通过直接链接 direct link
- 通过附件菜单启动 attatchment link
各种启动方法见下图:
4.1 键盘按钮启动 keyboard button
从
web_app
类型的键盘按钮启动的小程序,可以使用Telegram.WebApp.sendData
将数据以消息的形式发送回bot。这使得bot可以在不与任何外部服务器通信的情况下生成响应,bot在接收到数据后可以继续与用户进行通信。
用户可以通过自定义的bot键盘和按钮进行与bot的交互,也可以发送任意格式的文本消息或Telegram支持的任何附件类型:照片和视频、文件、位置、联系人和投票。为了更灵活,bot还可利用HTML5
的全部功能来创建用户友好的输入界面。
您可以发送一个打开指定URL
的web_app
类型的KeyboardButton
,以启动小程序。
该方案适用于:
自定义数据输入界面
,例如个性化的日期选择日历;具有高级搜索选项的列表中选择数据;让用户“旋转轮盘”并选择其中一个可用选项的随机数等。- 不依赖于特定机器人的
可复用组件
。
4.2 内联按钮 inline button
对于像 @DurgerKingBot 这样高互动性的小程序,可以使用
web_app
类型的内联按钮Inline Keyboard Button
,该按钮可以获取基本用户信息,并可用于代表用户向bot的发送聊天消息。
如果仅接收文本数据不满足需求或者需要更高级和个性化的界面,可以使用web_app
类型的Inline Keyboard Button
打开一个小程序。
从按钮中,小程序将打开指定的URL。除了用户的主题设置外,它还将接收基本用户信息(id
、name
、username
、language_code
)和会话的唯一标识符query_id
,该标识符允许小程序代表用户向bot发送消息。
Bot可以调用Bot API的answerWebAppQuery
方法,将用户发来的内联消息发送回机器人并关闭小程序。在接收到消息后,机器人可以继续与用户进行通信。
该方案适用于:
- 成熟度高的Web服务和各种集成。
- 可能性几乎无限的应用。
4.3 机器人菜单按钮 menu button
可以从Telegram的自定义菜单按钮启动小程序。这只是提供了一种更快捷的访问小程序的方式,除此之外与从
内联按钮
启动小程序完全相同。
默认情况下,与机器人的聊天会通过一个方便的菜单按钮,提供快速访问所有列出的命令。从Bot API 6.0
开始,可以使用该按钮来启动小程序。
配置菜单按钮,您需要指定它应显示的文本和小程序的URL。有两种设置这些参数的方式:
-
为所有用户定义按钮,使用 @BotFather(使用/setmenubutton命令或Bot Settings > Menu Button)。
-
为所有用户和特定用户自定义按钮,请使用
Bot API
的setChatMenuButton
方法。例如,根据用户的语言更改按钮文本,或者根据用户在您的机器人中的设置显示不同小程序的链接。
除配置方法不同之外,通过菜单按钮打开的小程序的工作方式与使用内联按钮完全相同。
@DurgerKingBot允许从内联按钮和菜单按钮启动小程序。
4.4 内联结果按钮模式 inline mode
通过
web_app
类型的Inline Query Results Button
启动的小程序可以在内联模式下的任何地方使用。用户可以在Web界面中创建内容,然后通过内联模式无缝地将其发送到当前聊天中。
您可以在answerInlineQuery
方法中使用button
参数,在内联结果的上方或替代位置显示一个特殊的切换到小程序
按钮。该按钮将打开指定URL的小程序。完成后,您可以调用Telegram.WebApp.switchInlineQuery
方法将用户发送回内联模式。
内联小程序无法访问聊天内容, 通过这种方式打开的小程序无法读取消息或代表用户发送新消息。要发送消息,必须将用户重定向到内联模式,并主动选择一个结果。
该方案适用于:
- 完全成熟的内联模式下的Web服务和集成。
4.5 直接链接 direct link
可以从任何聊天中的直接链接启动小程序。它们支持
startapp
参数,并且了解当前聊天的上下文。
您可以使用直接链接
直接在当前聊天中打开小程序。如果链接中包含非空的startapp
参数,它将传递给小程序的start_param
属性和GET
参数tgWebAppStartParam
。
在此模式下,小程序可以使用chat_type
和chat_instance
参数来跟踪当前聊天的上下文。这为多个聊天成员的并发和共享使用提供了支持,如用于创建实时白板、群组订单、多人游戏和类似的应用程序。
从直接链接
打开的小程序无法访问聊天内容, 它们无法读取消息或代表用户发送新消息。要发送消息,必须将用户重定向到内联模式,并主动选择一个结果。
例子:
适用于:
- 任何用户可以一次点击打开的完全成熟的Web服务。
- 基于协作、多人游戏或团队合作的聊天上下文服务。
4.6 附件菜单启动 attatchment link
小程序可以请求直接添加到用户的附件菜单中,使它们可以在任何类型的聊天中快速启动。您可以配置您的小程序在哪些类型的聊天中可以从附件菜单中启动(私聊、群组、超级群组或频道)。
目前,附件菜单集成仅适用于Telegram广告平台上的主要广告商。但是,在测试服务器环境中,所有机器人都可以使用它。
要为您的机器人启用此功能,请从测试服务器上的帐户打开@BotFather,并发送/setattach
命令,或转到Bot Settings > Configure Attachment Menu
。然后,指定将通过附件菜单中的图标启动小程序的URL。
您可以使用@BotFather向您的小程序上下文菜单添加一个“设置”项。当用户从菜单中选择此选项时,您的机器人将收到一个settingsButtonClicked
事件。
除了用户的主题设置外,机器人还将接收到用户的基本信息(id
、name
、username
、language_code
、photo
),以及与聊天伙伴的公共信息(id
、name
、username
、photo
)或聊天信息(id
、title
、username
、photo
),以及用于Web会话的唯一标识符query_id
,该标识符允许以打开机器人的用户的身份向聊天发送任何类型的消息。
机器人可以调用Bot API
的answerWebAppQuery
方法,将来自用户的内联消息通过机器人发送到启动该机器人的聊天,并关闭小程序。
您可以在此处阅读有关将机器人添加到附件菜单的更多信息。
5. 初始化小程序
5.1 连接库
在前端脚本的<head>标签中放置telegram-web-app.js
脚本,使用以下代码:
<script src="https://telegram.org/js/telegram-web-app.js"></script>
5.2 类 Class
5.2.1 WebApp Class
一旦脚本连接成功,将可使用window.Telegram.WebApp
对象,该对象具有以下属性:
Field | Type | Description |
---|---|---|
initData | String | 包含原始数据传输到小程序的参数。 注意:在将此属性用于机器人服务器之前,请对数据进行验证 |
initDataUnsafe | WebAppInitData(见下) | 包含传输到小程序的输入数据的对象。 注意:不应信任此属性中的数据。您应仅在机器人服务器上使用 initData 中的数据,并且仅在验证后使用 |
version | String | Bot API版本 |
platform | String | 电报运行的平台 |
colorScheme | String | 当前在Telegram中使用的颜色方案。可以是light 或dark 。也可以作为CSS变量var(--tg-color-scheme) 使用 |
themeParams | ThemeParams(见下) | 一个包含Telegram中使用的当前主题设置的对象 |
isExpanded | Boolean | 如果小程序已展开到最大可用高度,则为True 。如果小程序占据屏幕的一部分并可以使用expand() 方法展开到全高度,则为False |
viewportHeight | Float | 小程序可见区域的当前高度。也可以在CSS中使用var(--tg-viewport-height) 作为变量。应用程序可以仅显示小程序的顶部部分,其底部部分仍位于屏幕区域外。从这个位置,用户可以通过“拉动”小程序将其展开到最大高度,bot也可以通过调用 expand() 方法实现相同效果。随着小程序位置的变化,可见区域的当前高度值将实时更新。请注意,此值的刷新率不足以平滑地跟随窗口的下边界。它不应该用于将界面元素固定在可见区域的底部。更适合使用 viewportStableHeight 属性的值来实现此目的 |
viewportStableHeight | Float | 小程序可见区域在其最后稳定状态下的高度。也可以在CSS中使用变量var(--tg-viewport-stable-height) 。应用程序可以仅显示小程序的顶部部分,其底部部分仍位于屏幕区域外。从这个位置,用户可以通过“拉动”小程序将其展开到最大高度,机器人也可以通过调用 expand() 方法实现相同效果。与 viewportHeight 不同,viewportStableHeight 的值不会随着小程序位置的变化而改变,无论是由用户手势还是动画引起。在所有手势和动画完成并且小程序达到其最终大小之后,viewportStableHeight 的值将被更新。请注意,事件 viewportChanged 将传递参数isStateStable=true ,这将允许您跟踪可见区域高度的稳定状态何时发生变化 |
headerColor | String | 当前标题颜色,格式 #RRGGBB |
backgroundColor | String | 当前背景色,格式 #RRGGBB |
isClosingConfirmationEnabled | Boolean | 如果用户在尝试关闭小程序时启用了确认对话框,则为True 。如果禁用了确认对话框,则为False |
BackButton | BackButton(见下) | 用于控制在Telegram界面中小程序标题栏中显示的返回按钮的对象 |
MainButton | MainButton(见下) | 用于控制在Telegram界面中小程序底部显示的主按钮的对象 |
HapticFeedback | HapticFeedback(见下) | 用于触感反馈的对象 |
CloudStorage(新API) | CloudStorage(见下) | 用于云存储的对象 |
WebApp方法:
Field | Version | Description |
---|---|---|
isVersionAtLeast(version) | 如果用户的应用程序支持与参数传递的版本相等或更高版本的Bot API,则返回true | |
setHeaderColor(color) | 6.1+ | 一个以#RRGGBB 格式设置应用程序标题栏颜色的方法。您还可以使用关键字bg_color 和secondary_bg_color 。在 Bot API 6.9 之前,只能将Telegram.WebApp.themeParams.bg_color 或Telegram.WebApp.themeParams.secondary_bg_color 作为颜色或bg_color 、secondary_bg_color 关键字传递 |
setBackgroundColor(color) | 6.1+ | 一个以#RRGGBB 格式设置应用程序背景颜色的方法。还可以使用关键字bg_color 和secondary_bg_color |
enableClosingConfirmation() | 6.2+ | 启用在用户尝试关闭小程序时显示确认对话框 |
disableClosingConfirmation() | 6.2+ | 关闭在用户尝试关闭小程序时显示确认对话框 |
onEvent(eventType, eventHandler) | 设置小程序事件响应(见下) | |
offEvent(eventType, eventHandler) | 关闭小程序事件响应 | |
sendData(data) | 用于从小程序向bot发送数据。当调用此方法时,将向bot发送一个包含数据data(长度最多为4096字节)的消息,并关闭小程序。请参阅消息类中的web_app_data 熟悉。此方法仅适用于通过键盘按钮启动的小程序 |
|
switchInlineQuery(query[, choose_chat_types]) | 6.7+ | 用于在当前聊天的输入框中插入bot的用户名和指定的内联查询。查询可以为空,这种情况下只会插入机器人的用户名。如果传递了一个可选的choose_chat_types 参数,客户端会提示用户选择一个特定的聊天,然后打开该聊天并在输入框中插入机器人的用户名和指定的内联查询。您可以指定用户可以选择的聊天类型。可以是以下类型之一:用户、机器人、群组、频道。 |
openLink(url[, options]) | 在外部浏览器中打开链接。小程序不会被关闭。Bot API 6.4+ 如果传递了可选的options 参数,并且其中的try_instant_view 属性为true ,则如果可能,链接将以即时视图模式打开 |
|
openTelegramLink(url) | 在Telegram内打开Telegram链接的方法,这时小程序将被关闭 | |
openInvoice(url[, callback]) | 6.1+ | 使用链接URL打开发票。当发票关闭时,小程序将接收到invoiceClosed 事件。如果传递了可选的回调参数,回调函数将被调用,并将发票状态作为第一个参数传递 |
showPopup(params[, callback]) | 6.2+ | 显示由参数类型为PopupParams 的params 参数描述的本机弹出窗口的方法。当弹出窗口关闭时,小程序将接收到popupClosed 事件。如果传递了可选的回调参数,回调函数将被调用,并将按下按钮的id 属性作为第一个参数传递 |
showAlert(message[, callback]) | 6.2+ | 以简单警告框形式显示消息,带有一个“关闭”按钮。如果传递了可选的回调参数,当弹出窗口关闭时,将调用回调函数 |
showConfirm(message[, callback]) | 6.2+ | 以简单确认窗口形式显示消息,带有“确定”和“取消”按钮。如果传递了可选的回调参数,当弹出窗口关闭时,将调用回调函数,并且第一个参数将是一个Boolean,指示用户是否按下了“确定”按钮 |
showScanQrPopup(params[, callback]) | 6.4+ | 显示系统弹出窗口以扫描由类型为ScanQrPopupParams 的params 参数描述的QR码的方法。每当扫描器捕捉到带有文本数据的代码时,小程序将接收到qrTextReceived 事件。如果传递了可选的回调参数,当调用回调函数时,QR码中的文本将作为第一个参数传递。在此回调函数内返回true会导致弹出窗口关闭 |
closeScanQrPopup() | 6.4+ | 关闭由showScanQrPopup 方法打开的用于扫描QR码的系统弹出窗口的方法。如果在qrTextReceived 事件中收到有效数据,请运行此方法 |
readTextFromClipboard([callback]) | 6.4+ | 请求从剪贴板获取文本。小程序将接收到clipboardTextReceived 事件。如果传递了可选的回调参数,将调用回调函数,并将剪贴板中的文本作为第一个参数传递。注意:此方法只能针对从附件菜单启动的小程序进行调用,并且只能作为对小程序界面的用户交互(例如,在小程序内部点击或点击主按钮)的响应 |
requestWriteAccess([callback]) | 6.9+ | 显示系统弹出窗口,请求允许机器人向用户发送消息的方法。如果传递了可选的回调参数,当弹出窗口关闭时,将调用回调函数,并且第一个参数将是一个布尔值,指示用户是否授予了此访问权限 |
requestContact([callback]) | 6.9+ | 显示系统弹出窗口,提示用户输入其电话号码。如果传递了可选的回调参数,当弹出窗口关闭时,将调用回调函数,并且第一个参数将是一个Boolean,指示用户是否分享了其电话号码 |
ready() | 通知Telegram小程序已准备好显示。 建议尽早调用此方法,即在加载所有必要的界面元素后立即调用。一旦调用了此方法,加载占位符将被隐藏,小程序将显示出来。 如果未调用此方法,占位符将仅在页面完全加载后被隐藏 |
|
expand() | 将小程序展开到最大可用高度的方法。要了解小程序是否已展开到最大高度,请参考Telegram.WebApp.isExpanded 参数的值 |
|
close() | 关闭小程序 |
5.2.2 ThemeParams Class
小程序可以实时调整界面的外观以与Telegram匹配。该对象包含用户当前的主题设置:
Field | Type | Description |
---|---|---|
bg_color | String | 背景颜色以#RRGGBB格式表示。也可以作为CSS变量var(--tg-theme-bg-color) 使用 |
text_color | String | 主要文本颜色以#RRGGBB格式表示。也可以作为CSS变量var(--tg-theme-text-color) 使用 |
hint_color | String | 提示文本颜色以#RRGGBB格式表示。也可以作为CSS变量var(--tg-theme-hint-color) 使用 |
link_color | String | 链接颜色以#RRGGBB格式表示。也可以作为CSS变量var(--tg-theme-link-color) 使用 |
button_color | String | 按钮颜色以#RRGGBB格式表示。也可以作为CSS变量var(--tg-theme-button-color) 使用 |
button_text_color | String | 按钮文本颜色以#RRGGBB格式表示。也可以作为CSS变量var(--tg-theme-button-text-color) 使用 |
secondary_bg_color | String | 6.1+ 次要背景颜色以#RRGGBB格式表示。也可以作为CSS变量var(--tg-theme-secondary-bg-color) 使用 |
上述属性都可选。
5.2.3 PopupParams Class
用于原生弹窗
Field | Type | Description |
---|---|---|
title | String | (可选)弹窗标题,0-64个字符 |
message | String | 弹窗内容,1-256个字符 |
buttons | PopupButton数组 | (可选)在弹窗中显示的按钮列表,1-3个按钮。默认情况下设置为[{“type”:“close”}] |
5.2.4 ScanQrPopupParams Class
用于系统原生的二维码扫描对象
Field | Type | Description |
---|---|---|
text | String | (可选)“扫描QR码”标题下显示的文本,0-64个字符。 |
5.2.5 PopupButton Class
用于系统原生的弹出按钮
Field | Type | Description |
---|---|---|
id | String | (可选)按钮的标识符,0-64个字符。默认情况下设置为空字符串。如果按下按钮,它的id将在回调函数和popupClosed 事件中返回 |
type | String | (可选)按钮类型。默认情况下设置为”default”。 可以是以下值之一: - default,带有默认样式的按钮 - ok,带有本地化文本“确定”的按钮 - close,带有本地化文本“关闭”的按钮 - cancel,带有本地化文本“取消”的按钮 - destructive,带有表示破坏性操作的样式的按钮(例如“删除”、“取消”等) |
text | String | (可选)按钮文本,0-64个字符。如果类型为”default”或”destructive”,则必填。对于其他类型可不填 |
5.2.6 BackButton Class
该对象控制返回按钮,该按钮可以显示在Telegram界面中小程序的标题栏中。
Field | Type | Description |
---|---|---|
isVisible | Boolean | 是否显示 |
方法:
Field | Version | Description |
---|---|---|
onClick(callback) | 6.1+ | 按钮按下事件处理程序的方法,同Telegram.WebApp.onEvent('backButtonClicked', callback) |
offClick(callback) | 6.1+ | 删除按钮按下事件,同Telegram.WebApp.offEvent('backButtonClicked', callback) |
show() | 6.1+ | 显示返回按钮 |
hide() | 6.1+ | 隐藏 |
5.2.7 MainButton Class
主按钮位于电报输入框下方。
Field | Type | Description |
---|---|---|
text | String | 按钮文本,默认为CONTINUE |
color | String | 按钮颜色,默认为themeParams.button_color |
textColor | String | 按钮文本颜色,默认为themeParams.button_text_color |
isVisible | Boolean | 是否显示,默认为false |
isActive | Boolean | 是否激活,默认为true |
isProgressVisible | Boolean | (只读)显示是否显示加载过程 |
方法:
Field | Version | Description |
---|---|---|
setText(text) | 设置按钮文本 | |
onClick(callback) | 设置点击事件回调函数,同Telegram.WebApp.onEvent('mainButtonClicked', callback) |
|
offClick(callback | 关闭点击事件,同Telegram.WebApp.offEvent('mainButtonClicked', callback) |
|
show() | 显示主按钮,请注意,从附件菜单打开小程序会隐藏主按钮,直到用户与小程序界面进行交互 | |
hide() | 隐藏主按钮 | |
enable() | 激活主按钮 | |
disable() | 失效主按钮 | |
showProgress(leaveActive) | 用于在按钮上显示加载指示器。 如果与按钮相关的操作可能需要很长时间,请显示加载进度是推荐的做法。默认情况下,在操作进行中时,按钮是禁用的。如果传递了参数 leaveActive=true ,按钮将保持启用状态 |
|
hideProgress() | 隐藏进度条 | |
setParams(params) | 设置按钮参数。params参数是一个包含一个或多个需要更改的属性的对象: text - 按钮文本; color - 按钮颜色; text_color - 按钮文本颜色; is_active - 启用按钮; is_visible - 显示按钮 |
5.2.8 HapticFeedback Class
触感反馈
Field | Version | Description |
---|---|---|
impactOccurred(style) | 6.1+ | 用于指示发生了触觉反馈。Telegram可以根据传递的style值播放适当的触觉反馈。 style可以是以下值之一: - light,表示小型或轻量级UI对象之间的碰撞, - medium,表示中等大小或中等重量的UI对象之间的碰撞, - heavy,表示大型或重型UI对象之间的碰撞, - rigid,表示硬或不可弯曲的UI对象之间的碰撞, - soft,表示柔软或可弯曲的UI对象之间的碰撞 |
notificationOccurred(type) | 6.1+ | 用于指示任务或操作是否成功、失败或产生警告。Telegram可以根据传递的type值播放适当的触觉反馈。 type可以是以下值之一: - error,表示任务或操作失败, - success,表示任务或操作成功完成, - warning,表示任务或操作产生警告 |
selectionChanged() | 6.1+ | 用于指示用户已更改选择。Telegram可以根据需要播放适当的触觉反馈。 在用户进行选择或确认选择时,请不要使用此反馈;仅在选择发生更改时使用 |
5.2.9 CloudStorage Class
只支持6.9+版本。
Field | Description |
---|---|
setItem(key, value[, callback]) | 使用键将值存储在云存储中。键应包含1-128 个字符,只允许使用A-Z、a-z、0-9、_和- 。值应包含0-4096 个字符。您可以在云存储中存储多达1024 个键。如果传递了可选的回调参数,则将调用回调函数。如果发生错误,第一个参数将包含错误信息。如果成功,第一个参数将为null ,第二个参数将是一个布尔值,指示值是否已存储 |
getItem(key, callback) | 使用键从云存储中接收值。键应包含1-128 个字符,只允许使用A-Z、a-z、0-9、_和- 。如果发生错误,将调用回调函数,第一个参数将包含错误信息。如果成功,第一个参数将为null ,并且值将作为第二个参数传递 |
getItems(keys, callback) | 使用多个键从云存储中接收值。键应包含1-128 个字符,只允许使用A-Z、a-z、0-9、_和- 。如果发生错误,将调用回调函数,第一个参数将包含错误信息。如果成功,第一个参数将为null ,并且值将作为第二个参数传递 |
removeItem(key[, callback]) | 从云存储中删除指定键值的方法。键应包含1-128 个字符,只允许使用A-Z、a-z、0-9、_和- 。如果传递了可选的回调参数,则将调用回调函数。如果发生错误,第一个参数将包含错误信息。如果成功,第一个参数将为null,第二个参数将是一个布尔值,指示值是否已删除 |
removeItems(keys[, callback]) | 从云存储中删除多组键值的方法。键应包含1-128 个字符,只允许使用A-Z、a-z、0-9、_和- 。如果传递了可选的回调参数,则将调用回调函数。如果发生错误,第一个参数将包含错误信息。如果成功,第一个参数将为null,第二个参数将是一个布尔值,指示值是否已删除 |
getKeys(callback) | 获取在云存储中的所有键列表。如果发生错误,将调用回调函数,第一个参数将包含错误信息。如果成功,第一个参数将为null ,并且键列表将作为第二个参数传递 |
上述所有方法都会返回CloudStorage
对象。
5.2.10 WebAppInitData Class
该对象定义了在打开小程序时传递给它的数据。如果小程序是从键盘按钮
或内联模式
启动的,则该对象为空。
Field | Type | Description |
---|---|---|
query_id | String | (可选)用于小程序会话的唯一标识符,对于通过answerWebAppQuery 方法发送消息是必需的 |
user | WebAppUser | (可选)一个包含有关当前用户的数据的对象 |
receiver | WebAppUser | (可选)一个包含有关当前用户在通过附件菜单启动的聊天中的聊天伙伴的数据的对象。仅适用于私聊,并且仅适用于通过附件菜单启动的小程序 |
chat | WebAppChat | (可选)一个包含有关通过附件菜单启动的聊天中的聊天数据的对象。仅适用于超级群组、频道和群聊,且通过附件菜单启动的小程序 |
chat_type | String | (可选)小程序打开的聊天类型。可以是“sender”(与打开链接的用户进行的私聊)、“private”(私聊)、“group”(群聊)、“supergroup”(超级群组)或“channel”(频道)。仅适用于从直接链接启动的小程序 |
chat_instance | String | (可选)全局标识符,唯一对应于打开小程序的聊天。仅适用于从直接链接启动的小程序 |
start_param |
String | (可选)通过链接传递的startattach 参数的值。仅适用于通过链接从附件菜单启动的小程序start_param 参数的值也将通过GET参数tgWebAppStartParam 传递,因此小程序可以立即加载正确的界面 |
can_send_after |
Integer | (可选)以秒为单位的时间,在此时间之后可以通过answerWebAppQuery 方法发送消息 |
auth_date | Integer | Unix timestamp when the form was opened |
hash | String | 所有传递参数的哈希值,bot服务器可以用它来验证它们的有效性 |
5.2.11 WebAppUser Class
Field | Type | Description |
---|---|---|
id | Integer | 用户或机器人的唯一标识符。该id可能具有超过32位有效位,某些编程语言可能在解释时存在困难或潜在缺陷。它最多具有52位有效位,因此使用64位整数或双精度浮点类型来存储此标识符是安全的 |
is_bot | Boolean | (可选)返回是否是bot |
first_name | String | |
last_name | String | (可选) |
username | String | (可选)用户/bot名 |
language_code | String | (可选)依据IETF语言的用户语言代码 |
is_premium | Boolean | 是否是高级用户 |
added_to_attachment_menu | Boolean | 是否添加到Attachment menu |
allows_write_to_pm | Boolean | 是否允许bot向用户发送消息 |
photo_url | String | 用户个人资料照片的URL。照片可以是.jpeg或.svg格式。仅适用于从附件菜单启动的小程序,并在该情况下返回 |
5.2.12 WebAppChat Class
Field | Type | Description |
---|---|---|
id | Integer | 此聊天的唯一标识符。该id可能具有超过32位有效位,某些编程语言可能在解释时存在困难或潜在缺陷。但它最多具有52位有效位,因此使用有符号的64位整数或双精度浮点类型来存储此标识符是安全的 |
type | String | 对话类型:“group”, “supergroup” or “channel” |
title | String | 对话标题 |
username | String | 对话(群组)用户名 |
photo_url | String | 可选项。聊天的照片URL。照片可以是.jpeg或.svg格式。仅适用于从附件菜单启动的小程序,并在该情况下返回。 |
5.3 验证小程序收到的消息
为了验证通过小程序接收到的数据,应该将数据从Telegram.WebApp.initData
发送到机器人的后端。该数据是一个查询字符串,由一系列key-value
对组成。
您可以通过将接收到的hash参数
与使用密钥生成的数据检查字符串的HMAC-SHA-256
签名的十六进制表示进行比较,来验证接收到的数据的完整性。密钥是将机器人的令牌与常量字符串WebAppData
一起作为密钥生成的HMAC-SHA-256
签名。
数据检查字符串是所有接收到的属性按字母顺序排序的字符串,格式为key=<value>
,使用换行符(’\n’,0x0A)作为分隔符,例如'auth_date=<auth_date>\nquery_id=<query_id>\nuser=<user>'
。
完整的检查过程可能如下所示:
data_check_string = ...
secret_key = HMAC_SHA256(<bot_token>, "WebAppData")
if (hex(HMAC_SHA256(data_check_string, secret_key)) == hash) {
// 数据来自Telegram
}
为了防止使用过时的数据,您还可以额外检查auth_date
属性,该属性包含小程序接收到数据的Unix时间戳。
一旦验证通过,数据可以在您的服务器上使用。复杂的数据类型表示为JSON序列化对象。
5.4 小程序事件
小程序可以从Telegram接收事件,并使用Telegram.WebApp.onEvent(eventType, eventHandler)
方法处理程序。在eventHandler
中,this
对象指的是Telegram.WebApp
,发送到处理程序的参数集取决于事件类型。以下是可能的事件列表:
event | Version | description |
---|---|---|
themeChanged | 每当用户的Telegram中更改主题设置(包括切换到夜间模式)时触发。eventHandler 不接收任何参数,可以通过this.themeParams 和this.colorScheme 分别获取新的主题设置和颜色方案 |
|
viewportChanged | 当小程序的可见部分发生变化时触发。eventHandler 接收一个带有单个属性isStateStable 的对象。如果isStateStable 为true ,则小程序的调整大小已完成。如果为false ,则调整大小正在进行中(用户正在展开或折叠小程序,或正在播放动画对象)。可通过this.viewportHeight 获取可见部分的当前高度值 |
|
mainButtonClicked | 点击主按钮触发,eventHandler无参数 | |
backButtonClicked | 6.1+ | 点击返回按钮时触发,eventHandler无参数 |
settingsButtonClicked | 6.1+ | 点击设置按钮时触发,eventHandler无参数 |
invoiceClosed | 6.1+ | 当打开的发票关闭时触发。 eventHandler接收一个带有两个属性的对象: 1: url - 提供的发票链接, 2: status - 发票的状态之一: - paid - 发票已成功支付, - cancelled - 用户关闭了该发票而未支付, - failed - 用户尝试支付,但支付失败, - pending - 支付仍在处理中。 当支付成功完成时,机器人将收到一条有关成功支付的服务消息。 |
popupClosed | 6.2+ | 当关闭打开的弹出窗口时触发。 eventHandler接收一个带有单个属性 button_id 的对象,该属性值为按下按钮的id属性值。如果没有按下按钮,则button_id 属性将为null |
qrTextReceived | 6.4+ | 当QR码扫描器捕捉到包含文本数据的代码时触发。 eventHandler接收一个带有单个属性data的对象,该属性包含来自QR码的文本数据 |
clipboardTextReceived | 6.4+ | 当调用readTextFromClipboard 方法时触发。eventHandler接收一个带有单个属性data的对象,该属性包含来自剪贴板的文本数据。如果剪贴板包含非文本数据,则属性data将为空字符串。如果小程序无法访问剪贴板,则属性data将为null |
writeAccessRequested | 6.9+ | 当请求写入权限时触发。 eventHandler接收一个带有单个属性status的对象,该属性包含以下状态之一: - allowed - 用户授予了机器人的写入权限, - cancelled - 用户拒绝了此请求 |
contactRequested | 6.9+ | 当请求用户的手机号码时触发。 eventHandler接收一个带有单个属性status的对象,该属性包含以下状态之一: - sent - 用户与机器人分享了他们的手机号码, - cancelled - 用户拒绝了此请求 |
5.5 Adding Bots to the Attachment Menu
6. 调试小程序
6.1 在测试环境中使用机器人
要登录到测试环境,请使用以下任一方法:
- iOS:点击设置图标10次 > 账户 > 登录到另一个账户 > 测试。
- Telegram桌面版:打开 ☰ 设置 > Shift + Alt + 右键单击“添加账户”,然后选择“测试服务器”。
- macOS:点击设置图标10次以打开调试菜单,⌘ + 单击“添加账户”,然后通过手机号码登录。
测试环境与主要环境完全分离,因此您需要创建一个新的用户账户和一个新的机器人(通过@BotFather)。
在收到您的机器人令牌后,您可以按以下格式向Bot API
发送请求:
https://api.telegram.org/bot<token>/test/METHOD_NAME
注意:在使用测试环境时,您可以使用不带TLS的HTTP链接来测试您的小程序。
6.2 小程序调试模式
使用以下工具来Debug小程序:
Android
- 在您的设备上启用
USB调试
。 - 在Telegram设置中,向下滚动,按住版本号两次。
- 在调试设置中选择启用
WebView
调试。 - 将手机连接到计算机,并在Chrome中打开
chrome://inspect/#devices
- 当您在手机上启动小程序时,您会在那里看到它。
Windows和Linux上的Telegram桌面版
- 下载并启动Telegram桌面版的Beta版本。
- 转到
设置 > 高级 > 实验设置 > 启用WebView检查
。 - 右键单击
WebView
并选择检查元素
。
macOS上的Telegram
- 下载并启动Telegram macOS的Beta版本
- 快速点击5次设置图标以打开调试菜单,并启用
调试Web App
。 - 右键单击小程序并选择
检查元素
。