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

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

回答

收藏

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

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

方法与事件

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

调用方法

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

  1. import { postEvent } from '@telegram-apps/sdk';
    & i+ d& E' Y- f2 i* k

  2. % T2 l! W' U7 I1 }6 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';3 `- |3 L. w5 r! w8 N, S9 y5 _

  2. ' f9 f0 X/ @' \  x
  3. const viewport = await request({# u" p* d/ J3 H' P5 M2 b" e6 t5 J
  4.   method: 'web_app_request_viewport',
    : A+ g% b3 _, N1 Q0 w
  5.   event: 'viewport_changed'/ m, y( K# I1 m
  6. });
    # `+ O$ S! k/ y4 P
  7. 9 v* S3 A6 ]6 D" b
  8. console.log(viewport);
    9 u9 L8 @, C. Q7 u! C
  9. // Output:
    % g, K; W% @4 A( i4 G
  10. // {
      e# q* C) G# X* c- O
  11. //   is_state_stable: true,
    * Z/ H* Y: N+ x5 L/ i8 m
  12. //   is_expanded: false,
    0 _9 a* P7 x& e1 ]. _& y. G
  13. //   height: 3204 ?8 j2 P" w  o( N' R: l
  14. // };
复制代码

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

, d& ~# H$ b! v- m
  1. import { request } from '@telegram-apps/sdk';* e' a9 K) y% |# c

  2. ! t' u- h  k/ @( j; x( w
  3. const buttonId = await request({
    ) m3 m* N, _3 |0 J' U) `* F# f; ?
  4.   method: 'web_app_open_popup',0 M5 y* |9 ~$ h: q4 _- @
  5.   event: 'popup_closed',, q4 ]. k  ~* I: b
  6.   params: {
    1 }. s& Y; Q8 H
  7.     title: 'Caution',* Z5 b( H) x  [4 R9 {
  8.     message: 'Should we delete you account?',& M1 N/ O0 I* O3 m
  9.     buttons: [0 |; g* u2 ^7 }, U3 v
  10.       { id: 'yes', type: 'ok' },
    , v3 ?/ _; r$ P6 R1 Y: Y
  11.       { id: 'no', type: 'cancel' },
    & Z+ ?4 j  n0 U$ J4 e
  12.     ],, g4 y& Y; f: F& f
  13.   },
    ( K7 V5 \# [2 @' O* {
  14. });
复制代码

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

' W9 }! }; M7 z  ?4 c6 w
  1. import { request } from '@telegram-apps/sdk';9 f: e& i% K( ?! I

  2. ' u9 r$ C# m0 ~3 \1 D4 Z. l
  3. const result = await request({0 e9 I8 s% w8 G  m/ M8 k+ [. f" X: k# @
  4.   method: 'web_app_open_scan_qr_popup',
    6 \8 J) F4 M; ^* E
  5.   event: ['qr_text_received', 'scan_qr_popup_closed'],# \  k6 g4 P& T( k6 w2 w
  6. });
    : U( G# k/ }9 A( f1 m- X9 k; o

  7. 8 t' g5 D. X7 H+ [- j5 Y
  8. // result will either be qr_text_received or
    * i& v- {! W: `6 B2 V" i6 G
  9. // scan_qr_popup_closed events payload.
复制代码

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


$ T5 V; l" o& vpostEvent

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

  1. import { request, createPostEvent } from '@telegram-apps/sdk';) ^; W1 h- X9 i) z. Q& R

  2. 2 `' b' F& s" ~8 M9 ?
  3. request({( P: z  ]5 A  B
  4.   method: 'web_app_request_viewport',
    ( K* X7 I4 Z8 l+ Q/ F% t
  5.   event: 'viewport_changed',
    ) |0 `' X1 g, a$ d9 o' y
  6.   postEvent: createPostEvent('6.5'),
    ! \6 A) W, u! ?6 e8 r8 A4 z6 y
  7. });
复制代码
timeout

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

  1. import { request, isTimeoutError } from '@telegram-apps/sdk';
    & j2 i/ m! `1 P/ U

  2. & I' c, I( D4 _
  3. try {) A6 r/ `4 M) h  Y3 A/ e# ^, `2 q9 e
  4.   await request({* h& u8 ^+ ?+ K; o2 \& E% D
  5.     method: 'web_app_invoke_custom_method',
    # E3 j* g& G; I# _, k* R+ q/ }
  6.     event: 'custom_method_invoked',) d! o* \2 ~+ h! ^& L
  7.     timeout: 5000,
    8 y0 x$ }2 o. A* i) y
  8.     params: {
    ! y1 ?. r- Y* q7 o8 I% F8 G" ?
  9.       req_id: '1',
    ' P  c: k/ |8 X  X, p& Q8 L
  10.       method: 'deleteStorageValues',* B% i) Z  \0 O
  11.       params: { keys: ['a'] },
    5 y0 q) l8 B# ^% Q$ [; n6 c
  12.     },
    1 B# E8 z" C! H5 ?8 h" Q0 N3 H
  13.   });: b. q/ n3 {; I8 K  B/ U5 D
  14. } catch (e) {
    * h' o8 r& L6 P  B+ ?& i9 e& t4 {; x
  15.   console.error(isTimeoutError(e) ? 'Timeout error' : 'Some different error', e);
    8 O9 `+ o+ t3 s8 }
  16. }
复制代码
capture

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

  1. const slug = 'jjKSJnm1k23lodd';
    6 m3 X9 a' x4 M1 X- K' O

  2. : y- p+ a4 d" p: c9 M& D% L
  3. request({
    ! `9 y! y0 }2 P# t+ K: y
  4.   method: 'web_app_open_invoice',( M( u) B& g: y3 o7 P$ f% F
  5.   event: 'invoice_closed'," o7 J  h  D5 {1 f6 V
  6.   params: { slug },
    # c. W$ e5 N8 i. ^9 k: j  L
  7.   capture(data) {
    2 z( X. c( f  S
  8.     return slug === data.slug;
    & R* d9 O/ {' L" _# o% m
  9.   },
    4 A& A) `; Q9 R& u
  10. });
复制代码
默认情况下,request 函数会捕获带有所需名称的第一个事件。 在 的情况下,request 函数只有在事件具有预期的标签时才会捕获事件。
* ]1 T5 N; C. q6 Z( ~调用自定义方法

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

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

  1. import { request } from '@telegram-apps/sdk';8 K! D8 u" A5 d1 O3 r
  2. 6 y! a! I& E; x0 g6 @  n: V7 ]
  3. const reqId = 'ABC';
    1 P" V$ r) R$ c7 t8 n

  4. 2 S) [0 k+ O& y3 j
  5. request({
    ( Y! L4 i( W* i( j
  6.   method: 'web_app_invoke_custom_method',
    7 {0 L+ `! t" S& \' F
  7.   event: 'custom_method_invoked',2 C6 `& O" d0 k; e
  8.   params: {
    ( m3 X* r& E9 P& Y' M. ?
  9.     req_id: reqId,: w. A, ]& b, C) I1 `4 a( u3 c
  10.     method: 'deleteStorageValues',
    9 E2 {5 M& u  q- ^, z
  11.     params: { keys: ['a'] },) l* _4 B" |- r" [% W
  12.   },
    % H8 ]9 r, ]% m" X9 J& S
  13.   capture(data) {
    3 t) ^; g# f) V) i7 D9 ]
  14.     return data.req_id === reqId;
    $ ]* A" H0 a, H, w" H
  15.   }% \8 ~1 d/ S( R$ R! t% s
  16. });
复制代码
这样,我们就可以使用 invokeCustomMethod 函数重写它了:
( ^$ z3 D  X# N: E# l
5 u: E% B' Y. b* t2 S
  1. import { invokeCustomMethod } from '@telegram-apps/sdk';
    - Z" {0 Q2 I& N0 _8 g

  2. % ~( I3 H( W) t6 A
  3. invokeCustomMethod('deleteStorageValues', { keys: ['a'] }, 'ABC');
复制代码
invokeCustomMethod('deleteStorageValues', { keys: ['a'] }, 'ABC');
# O; Y0 Q! E; B: I5 r/ O

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

事件监听on 和 off

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

  1. import { on } from '@telegram-apps/sdk';
    2 J. b) _% [7 R+ q- M1 ?, Z, ~5 D+ E

  2. ( D2 k% D& l% }) H
  3. // Start listening to "viewport_changed" event. Returned value( d1 d9 e$ ^$ ?+ i" r5 m3 F3 k
  4. // is a function, which removes this event listener.& S; a, o( |0 \$ V9 u7 `0 |% i
  5. const removeListener = on('viewport_changed', payload => {4 H& C6 R+ L% N( e
  6.   console.log('Viewport changed:', payload);. I( h0 F6 ^3 R3 c
  7. });- `7 E1 a; h& Q+ s" V

  8. # l7 T  Q2 [: @# u2 ^
  9. // Remove this event listener.
    : E. ^+ Q( d, U( S& l8 [, Q" R6 g
  10. removeListener();
复制代码

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

3 |: N" S5 l8 I
  1. import { on, off, type MiniAppsEventListener } from '@telegram-apps/sdk';% v9 j4 W% l2 x1 c! W" ]- H# H
  2. ) x! y: g) t7 J
  3. const listener: MiniAppsEventListener<'viewport_changed'> = payload => {
    # @/ X2 n9 E# |4 J( L: r
  4.   console.log('Viewport changed:', payload);
    # R8 }6 R. P( }$ u) W
  5. };
    ' p) v5 Z+ S" m3 A
  6. 6 j* d1 @- _2 _. R: G/ u# m
  7. // Start listening to event." n! B  b7 c% g$ C3 p  o  E9 P
  8. on('viewport_changed', listener);. u% D9 V4 |& @- D
  9. & B1 ?) q) {' Q/ _: I5 u
  10. // Remove event listener.
    7 Y" w% j5 ?+ l) E: s" P
  11. off('viewport_changed', listener);
复制代码

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

9 y  `3 H4 r( T# V5 c6 q+ F  }9 A
  1. import { on } from '@telegram-apps/sdk';0 A/ [6 U3 ]- @" n
  2. ! D8 H4 y9 g- l1 w; b$ J3 f
  3. // Will be automatically removed after the first listener execution.9 T% s0 ~3 h5 Z0 c$ o. H4 H
  4. on('viewport_changed', (payload) => {! g8 S# }  P; u1 [" N. @/ [
  5.   console.log('Viewport changed:', payload);4 l, i3 L! |, u5 ~
  6. }, true);
复制代码
subscribe 和 unsubscribe

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

  1. import {
    % H9 K: `5 T, {! ]
  2.   subscribe,
    & t0 s8 g. B0 u3 _7 B
  3.   unsubscribe,& f, `% y4 F7 C. q
  4.   type MiniAppsGlobalEventListener,
    * U5 T" Q8 R0 q; W
  5. } from '@telegram-apps/sdk';$ i. u* `4 l3 L! ^* J& c1 \6 B

  6. : [; }: j; Q( N9 M* t- A
  7. const listener: MiniAppsSubscribeListener = (event) => {
    / c. Z7 n6 l2 d) P0 r9 w- \- [: O, m
  8.   console.log('Received event', event);$ }) q9 `( W6 t. g( Y1 N
  9. };
    5 Q5 p- s; c, Z3 T* U

  10. 5 n$ k" {# N0 T3 J4 i& ^- I5 T
  11. // Listen to all events.3 ?- B0 g; l& B
  12. subscribe(listener);' E& Z; P. \: M( \# V, p
  13. 5 P2 J" {! R) n6 s0 W, z# T
  14. // Remove this listener.
    2 `1 r) [* \( V$ Z2 b
  15. unsubscribe(listener);
复制代码
监听器接受一个包含 namepayload 属性的对象,这些属性是迷你应用程序 事件名称和有效载荷。" O  F5 c, V  z. l+ s! `
检查方法支持

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

  1. import { supports } from '@telegram-apps/sdk';5 K5 S- r; s/ A

  2. 2 j2 R  `/ c* w
  3. supports('web_app_trigger_haptic_feedback', '6.0'); // false  D7 z' _  ?; o8 y
  4. supports('web_app_trigger_haptic_feedback', '6.1'); // true
复制代码

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

1 ^/ G8 w, k- \& X( `" r
  1. import { supports } from '@telegram-apps/sdk';
    2 U( w! q+ \, Q

  2. * H- P' r! {8 D0 L
  3. supports('web_app_open_link', 'try_instant_view', '6.0'); // false. ^- Y$ H4 P) Q8 p+ K$ W
  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';% J$ o3 x! v: v
  2. ' v2 ~: W7 `8 B& S& d5 S7 F7 z
  3. const postEvent = createPostEvent('6.5');
    " {: p, ]/ W, t. W4 F
  4. 6 F, r# N* V: C# Q, T/ X
  5. // Will work fine." N: Q( ]& A/ z& T" H! q7 X- l, n
  6. postEvent('web_app_read_text_from_clipboard');
    , {4 X  J+ ]& u) b) i0 A% x) R. `
  7. : K3 `2 T- O9 ^* X
  8. // Will throw an error.
    ' Y7 `( b  x/ p( J) t* H
  9. postEvent('web_app_request_phone');
复制代码
强烈建议使用此 postEvent 生成器,以确保方法调用按照 的预期运行。* v9 i6 j7 n9 U8 e+ ~
调试

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

  1. import { setDebug } from '@telegram-apps/sdk';5 P6 N6 u' X6 O; w# |2 Q- \
  2. 6 c5 U. _2 d0 N4 ~0 \, z
  3. setDebug(true);
复制代码
目标源

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

  1. import { setTargetOrigin } from '@telegram-apps/sdk';
    : }. X1 V# [3 c+ V) f# b
  2. $ M, p6 [, x) L; H( w. `& N  @
  3. setTargetOrigin('https://myendpoint.org');
复制代码

% t* k9 F* m: h7 V! r

WARNING

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

& R# g- f# o: e0 _( R5 y" X

! s, ]# |4 P+ ?  i9 i* M' l
% u' G4 e) n, D' B) l$ v; h* d8 y+ k6 W: A- b( ~

6 B. v. m" b3 m2 f- m5 B4 r) R4 ?# R: k1 v
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则