English 简体中文 繁體中文 한국 사람 日本語 Deutsch русский بالعربية TÜRKÇE português คนไทย french

简体中文 繁體中文 English 日本語 Deutsch 한국 사람 بالعربية TÜRKÇE คนไทย Français русский

回答

收藏

Telegram 小程序 | TypeScript @telegram-apps/sdk @1.x | 方法与事件

开源社区 开源社区 10364 人阅读 | 0 人回复 | 2025-02-23

方法与事件

本节 SDK 涵盖与 apps communication 相关的主题。

调用方法

要调用 Telegram 小应用程序的方法,开发人员应使用 postEvent 函数:

  1. import { postEvent } from '@telegram-apps/sdk';6 m2 n! l) E, P; J
  2.   A1 v4 u' h2 O  D# |# a
  3. postEvent('web_app_setup_back_button', { is_visible: true });
复制代码
该功能会根据当前 环境功能自动找到发送该事件的正确方法。 为提高准确性,它可确定当前的 Telegram 应用类型,并 选择适当的流量。request

如果需要调用某些 Telegram 小应用程序方法 并接收指定事件,则应使用 request 函数。 例如,开发人员希望 调用 web_app_request_viewport 方法并捕获 viewport_changed 事件,以接收实际的视口数据。

  1. import { request } from '@telegram-apps/sdk';: F) v! y: X( c5 v
  2. + b: p, Q7 g# S
  3. const viewport = await request({" y' \. I- ^2 o" l* M* n
  4.   method: 'web_app_request_viewport',7 g" I- @& `9 u$ {! [
  5.   event: 'viewport_changed') k+ R* s9 B; {/ e0 H# `; j( z
  6. });2 a3 `( H% ^6 [9 L( |" W

  7. ( Y; P- @" F' G/ T  z8 M3 D) @
  8. console.log(viewport);
    " F+ ~0 k8 J+ L0 r6 E# r
  9. // Output:9 f8 `- j* |# z9 Z3 W7 u& ]5 N
  10. // {
    ! N! I- m& r& B6 y1 S, `
  11. //   is_state_stable: true,& l5 e: O# v* ]2 V8 m: \, s! j
  12. //   is_expanded: false,  l* A1 b0 R- r, X" d+ S
  13. //   height: 320
    : W9 p7 ?$ x2 `* l% K
  14. // };
复制代码

如果 Telegram 小应用程序方法接受参数,则应在第三个参数的 params 属性中传递这些参数:

  |# D; G; V# Z( y
  1. import { request } from '@telegram-apps/sdk';4 z, r/ |+ ^+ c2 x/ O

  2. $ U; m0 {7 z# {! _
  3. const buttonId = await request({
    . h7 X) @5 _( K1 G' {
  4.   method: 'web_app_open_popup',, N8 j& k4 ?3 [* m- Y) [1 t
  5.   event: 'popup_closed',
    0 j% H: [( n1 l& b# w
  6.   params: {
    3 p  n1 g- _8 w* E
  7.     title: 'Caution',9 j& `5 x: X4 q: Q1 N  m/ Q- Z
  8.     message: 'Should we delete you account?',
    # f+ a- g9 b2 S$ a. R) g8 q
  9.     buttons: [
    7 u/ @7 v* K- f9 ?& p
  10.       { id: 'yes', type: 'ok' },
    ' d, u! G/ B- d% P& B
  11.       { id: 'no', type: 'cancel' },8 P$ `0 V9 G1 n& N5 j
  12.     ],
    3 [+ Z4 D) l; ]* b, f/ h$ c
  13.   },! P! O$ u' j6 z8 {+ h+ b5 r
  14. });
复制代码

此外,您还可以同时跟踪多个事件:

, X% u- R7 A, B: ]! N
  1. import { request } from '@telegram-apps/sdk';
    ! K) R# u. l. t# z

  2. 3 e5 ?4 A/ ]0 y- ]
  3. const result = await request({
    1 T7 W$ o1 B$ U' M( L: f# V+ `
  4.   method: 'web_app_open_scan_qr_popup',& e& b0 d" M3 r/ ]2 g7 q! ^
  5.   event: ['qr_text_received', 'scan_qr_popup_closed'],
    ! M0 ]+ a+ r$ k5 C
  6. });
    . j( `9 h& A2 Z2 c6 w& G

  7. " M! `( Y7 d" g. Y' ~+ Y4 A0 Q
  8. // result will either be qr_text_received or
    ) B" ?* T5 V, T4 W% ~: A. V
  9. // scan_qr_popup_closed events payload.
复制代码

该函数允许传递其他选项,如 postEvent、timeout 和 capture。


, R# G8 H; h6 ~postEvent

我们使用 postEvent 选项重写方法,该方法用于调用 Telegram 迷你应用程序 方法。

  1. import { request, createPostEvent } from '@telegram-apps/sdk';% w7 o! \) q7 y2 V6 h3 {6 ?( L

  2. 4 F0 F. v7 x! s+ s
  3. request({3 h% |9 k+ T( q4 g
  4.   method: 'web_app_request_viewport',
      Z8 I7 S& v- v
  5.   event: 'viewport_changed',
    % h8 m% s" ]$ ?6 Z$ {
  6.   postEvent: createPostEvent('6.5'),
    + W3 B( y* {: {" u) X9 U9 o% e& s
  7. });
复制代码
timeout

timeout 选项负责分配请求超时。 如果超时,则会出现错误。

  1. import { request, isTimeoutError } from '@telegram-apps/sdk';" {- q% d# R1 L! i5 s; c+ Z" X7 i% V
  2. ( M* |6 a+ k4 {; Q3 w! S: ~* U& i
  3. try {0 I" m5 s; c* Z2 d$ P
  4.   await request({
    + B8 t$ Z" e) j* Y3 Y
  5.     method: 'web_app_invoke_custom_method',
    3 n) Z8 X. a0 Q& j' x3 d* L
  6.     event: 'custom_method_invoked',7 Q+ f/ d% a/ w& h
  7.     timeout: 5000,
    * B" P+ h8 w% c* j+ M  |
  8.     params: {, @0 D% N' c. J) ]
  9.       req_id: '1',8 Q# L, F# ^$ ^6 j# i
  10.       method: 'deleteStorageValues',6 b: N& O8 e5 C0 k; X
  11.       params: { keys: ['a'] },, Y$ E& }+ t, U& U( _9 U
  12.     },
    # m  r/ U* T4 Z( }( K  [6 B
  13.   });
    2 S( [5 B0 ~. J4 ^3 F% b' u
  14. } catch (e) {9 B1 ^% Y# d8 {# H! ]
  15.   console.error(isTimeoutError(e) ? 'Timeout error' : 'Some different error', e);
    : u* {5 \1 i, L9 M
  16. }
复制代码
capture

capture 属性是一个函数,允许开发人员确定是否应捕获 Mini Apps 事件并从 request 函数中返回:

  1. const slug = 'jjKSJnm1k23lodd';! d8 Q1 q1 n' g$ ~9 e6 C* ]

  2. $ L) b4 ?! z/ L( v
  3. request({2 p7 ^: j$ E/ m3 x: F8 z/ N5 K
  4.   method: 'web_app_open_invoice',
    ; Z0 E8 Q; v1 b4 m8 ~
  5.   event: 'invoice_closed',
    ( t9 W& T  E# I0 d% E/ X
  6.   params: { slug },
    8 n+ w2 u$ U' V8 R, c9 ~
  7.   capture(data) {* X" o3 q0 S& F
  8.     return slug === data.slug;
    ) x7 @, m0 L% X- q# G1 ?9 [
  9.   },
    / R( f1 |- ^( U1 C
  10. });
复制代码
默认情况下,request 函数会捕获带有所需名称的第一个事件。 在 的情况下,request 函数只有在事件具有预期的标签时才会捕获事件。& l: @6 N3 I/ t. P! {# K
调用自定义方法

自定义方法是 Telegram 迷你应用程序 web_app_invoke_custom_method 方法可以使用的方法。 invokeCustomMethod 函数简化了此类方法的使用,并重复使用了 request 函数。

以下是不使用该函数的代码示例:

  1. import { request } from '@telegram-apps/sdk';& ]" t9 ?1 T2 U* y+ Q3 P6 n$ |

  2. + n6 h: T% ?# F2 I# m8 q2 Z  Y% j
  3. const reqId = 'ABC';
    - @5 L$ @+ T9 J8 q. F; t

  4. $ {  d: r* [1 W3 i$ R
  5. request({0 E7 P# g- u8 W6 C8 B# e
  6.   method: 'web_app_invoke_custom_method',
    $ K2 b' ^/ C, w  y4 ^* W# M1 K
  7.   event: 'custom_method_invoked'," H1 {' v# g4 J6 v9 T
  8.   params: {7 {4 r1 I' t9 b/ p9 I
  9.     req_id: reqId,
    * ^' x+ Y3 Z( b* J
  10.     method: 'deleteStorageValues',
    + s% M  n, i; Z& y+ z" `
  11.     params: { keys: ['a'] },# b  |  E& W1 M3 v
  12.   },9 S" U) J4 h- A3 k9 l) `  Y$ z
  13.   capture(data) {4 I) _# ~- y3 Y2 w8 H
  14.     return data.req_id === reqId;4 r; G0 l' _& j7 f, \
  15.   }
    & e1 Z) }  n! h' C0 d3 R
  16. });
复制代码
这样,我们就可以使用 invokeCustomMethod 函数重写它了:6 l2 A) x1 S  G9 m" y! g

& J# V, [7 U, l6 K
  1. import { invokeCustomMethod } from '@telegram-apps/sdk';
    6 J) }2 K( Z' d0 Z9 `& v
  2. $ j7 t$ r: |# I  f  i8 n
  3. invokeCustomMethod('deleteStorageValues', { keys: ['a'] }, 'ABC');
复制代码
invokeCustomMethod('deleteStorageValues', { keys: ['a'] }, 'ABC');
1 `8 `7 B. A+ e

与request函数相反,invokeCustomMethod函数解析结果,并 检查是否包含error属性。 如果出现这种情况,函数将抛出相应的 错误。 否则,将返回 result 属性。

事件监听on 和 off

要开始处理事件,开发人员可以使用 on 和 off 函数。 下面是 on 函数的基本用法

  1. import { on } from '@telegram-apps/sdk';+ v' m( x( S3 n9 L1 {
  2. 9 E. z1 J% \0 l" m* O5 \2 i# o
  3. // Start listening to "viewport_changed" event. Returned value
    2 W& s8 D9 a; n" Y6 n, [8 G8 l" l
  4. // is a function, which removes this event listener.
    ( Z9 Q. S/ p; t
  5. const removeListener = on('viewport_changed', payload => {5 X; \5 P* }9 p- R9 X% E3 S. Q
  6.   console.log('Viewport changed:', payload);: O" v& U0 V5 d6 s. z, N/ l* p% P
  7. });$ X5 Y% l" p4 |7 ?& B2 X
  8. $ Q7 [- G2 x# b" u+ U* R6 ^/ A
  9. // Remove this event listener.4 {0 O) U/ V- y1 s- X2 X3 k9 }
  10. removeListener();
复制代码

要停止监听事件,开发人员也可以使用 off 函数:

% j, Y# N& S% L* M) L! Q* ~2 t# c
  1. import { on, off, type MiniAppsEventListener } from '@telegram-apps/sdk';" U# G+ ?& I* T) X  H5 x& c6 y

  2. 0 L; t* Z. X4 Z- E
  3. const listener: MiniAppsEventListener<'viewport_changed'> = payload => {  Z& a% `- k' |) C2 i/ J- c4 H. o0 }
  4.   console.log('Viewport changed:', payload);
    6 h$ Z' x$ K+ J- D% M8 ]4 k7 k
  5. };( \# L% J, f: T1 I, C; C

  6. . s% }; K& d$ [$ f9 K' _
  7. // Start listening to event.
    1 k; ]  K: {# T
  8. on('viewport_changed', listener);1 ]7 X% D6 }: a5 p/ w

  9. * Y; R7 B+ D7 u/ ]' n, F
  10. // Remove event listener." g5 v: y! K4 A: Q, _
  11. off('viewport_changed', listener);
复制代码

要只调用监听器一次,请使用第三个布尔参数。


8 p9 |: Y7 ~: i, G
  1. import { on } from '@telegram-apps/sdk';
    8 H- K8 {- T4 s. V- m% A$ D5 `

  2. 0 o& D9 d' H6 d: m" M$ e( H
  3. // Will be automatically removed after the first listener execution.
    . ?% g2 n& Z& r8 y* U# h& @/ P# w
  4. on('viewport_changed', (payload) => {
    ; z: x; W) K9 k9 a) Z! O8 R
  5.   console.log('Viewport changed:', payload);
    $ T$ _; i  f4 r# V/ Q/ I+ `
  6. }, true);
复制代码
subscribe 和 unsubscribe

要监听从本地 Telegram 应用程序发送的所有事件,开发人员应使用 subscribe 和 unsubscribe:

  1. import {
    6 U1 m3 U  o4 E" e' L/ X
  2.   subscribe,
    # [6 a7 g+ {  \6 R6 F
  3.   unsubscribe,8 w, r- I; B$ S: I. b. o* o
  4.   type MiniAppsGlobalEventListener,9 a% J4 ?, n1 I# u& K' e! }
  5. } from '@telegram-apps/sdk';+ Z( K+ @* \! H& h% B, m% f5 ?
  6. 6 b; ^8 |- d* n0 u) X; {
  7. const listener: MiniAppsSubscribeListener = (event) => {& l. Y# Y, U! t3 Z
  8.   console.log('Received event', event);
    5 g7 s8 D5 q" x/ i
  9. };
    ( B" w" {9 j' U. ?7 X8 f- \$ m& ^

  10. 0 C) B) {' T% E# }" f+ t
  11. // Listen to all events.# f* M4 L) K; a. a9 Z/ e- K
  12. subscribe(listener);
    # Z7 g  k7 X' S/ L$ A
  13. & G! h  y0 ]0 L- n- P( M3 b
  14. // Remove this listener.
    . q/ a9 S  _; Q& ?$ w, K0 s
  15. unsubscribe(listener);
复制代码
监听器接受一个包含 namepayload 属性的对象,这些属性是迷你应用程序 事件名称和有效载荷。
4 s8 L* ^% [+ J0 R  U检查方法支持

postEvent 函数本身未检查当前本地 Telegram 应用程序是否支持指定方法。 为此,开发人员可以使用 supports 函数,该函数接受 Mini Apps 方法名称和当前平台版本:

  1. import { supports } from '@telegram-apps/sdk';
    7 p6 O% q+ q  Q, u% S3 y% x

  2. 0 B# s3 B# P6 a
  3. supports('web_app_trigger_haptic_feedback', '6.0'); // false) q2 C" T2 b- [4 X& H. |0 m
  4. supports('web_app_trigger_haptic_feedback', '6.1'); // true
复制代码

supports 函数还允许检查方法参数中的指定参数是否受 支持:

$ {1 `: o- n6 l# c
  1. import { supports } from '@telegram-apps/sdk';% V, ?* Q9 f. Z5 M8 Y$ d9 p- j

  2. 3 L, l( \( y. x
  3. supports('web_app_open_link', 'try_instant_view', '6.0'); // false& F4 I! R4 R! s. N2 Y
  4. supports('web_app_open_link', 'try_instant_view', '6.7'); // true
复制代码

TIP

建议在调用 Mini Apps 方法之前使用该函数,以防止应用程序出现 停顿和其他意外行为。

创建更安全的 postEvent

该软件包包含一个名为 createPostEvent 的函数,它将当前 Mini Apps 版本作为输入。 它返回 postEvent 函数,内部检查是否支持指定的 方法和参数。 如果不是,函数将出错。

  1. import { createPostEvent } from '@telegram-apps/sdk';1 n7 c( L3 u2 W( g+ A! g, Z* K
  2. . ^$ v: E7 P( \" ^' a- L" D
  3. const postEvent = createPostEvent('6.5');
    ! @# y, F/ L6 |6 Y: t, R

  4. ' t- O, {4 a0 v6 }/ L7 Z
  5. // Will work fine.. \2 L/ ]+ \/ w% N7 J
  6. postEvent('web_app_read_text_from_clipboard');
    " _9 T; u4 N/ _3 N- k
  7. 7 u- n" w, C! G; I
  8. // Will throw an error./ X/ ]* W* l8 q  m( T- y- H
  9. postEvent('web_app_request_phone');
复制代码
强烈建议使用此 postEvent 生成器,以确保方法调用按照 的预期运行。
1 k: U5 e2 \6 {调试

软件包支持启用调试模式,从而记录与事件 处理相关的信息。 要更改调试模式,请使用setDebug函数:

  1. import { setDebug } from '@telegram-apps/sdk';$ t( A2 m, b2 }$ O( ~+ m1 t
  2. " H, T& Z" a8 D  |* ^/ X8 b+ a
  3. setDebug(true);
复制代码
目标源

如果软件包在浏览器环境(iframe)中使用,则软件包会使用 函数 window.parent.postMessage 。 此功能需要指定目标来源,以确保 事件只发送到受信任的父 iframe。 默认情况下,软件包 使用 https://web.telegram.org 作为原点。 开发人员应使用 setTargetOrigin 函数将事件传输到其他来源:

  1. import { setTargetOrigin } from '@telegram-apps/sdk';$ L, C, l" m6 X8 q, o# L
  2. $ Y0 x' x0 E- M
  3. setTargetOrigin('https://myendpoint.org');
复制代码


6 b9 V" Q, J# I; t' Q, D% Y* m. S

WARNING

强烈建议不要长期覆盖此值,否则可能导致安全问题。 只有当您知道自己在做什么时,才能指定该值。

- Z: h! [4 n4 g3 f& a
6 ^$ R0 O% S9 {, X& z  M( e
; S9 W& d% S0 {

0 Q6 I% h' o7 ]9 {( C2 G! H% A7 f/ |: r$ G/ W. P8 f* p

! J! d$ J- `* }6 @. L5 n4 q9 u$ w/ ^
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则