Skip to main content

telegram_webapp_sdk/api/
user.rs

1// SPDX-FileCopyrightText: 2025-2026 RAprogramm <andrey.rozanov.vl@gmail.com>
2// SPDX-License-Identifier: MIT
3
4use js_sys::{Function, Reflect};
5use wasm_bindgen::{JsCast, prelude::*};
6use web_sys::window;
7
8/// Calls `Telegram.WebApp.requestContact()`.
9///
10/// Requires the user's explicit permission to share their contact information.
11///
12/// # Errors
13/// Returns `Err(JsValue)` if `Telegram.WebApp` or the method is unavailable, or
14/// if the call fails.
15///
16/// # Examples
17/// ```no_run
18/// use telegram_webapp_sdk::api::user::request_contact;
19///
20/// let _ = request_contact();
21/// ```
22pub fn request_contact() -> Result<(), JsValue> {
23    let webapp = webapp_object()?;
24    let func =
25        Reflect::get(&webapp, &JsValue::from_str("requestContact"))?.dyn_into::<Function>()?;
26    func.call0(&webapp)?;
27    Ok(())
28}
29
30fn webapp_object() -> Result<JsValue, JsValue> {
31    let win = window().ok_or_else(|| JsValue::from_str("no window"))?;
32    let tg = Reflect::get(&win, &JsValue::from_str("Telegram"))?;
33    Reflect::get(&tg, &JsValue::from_str("WebApp"))
34}
35
36#[cfg(test)]
37mod tests {
38    use js_sys::{Function, Object, Reflect};
39    use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure};
40    use web_sys::window;
41
42    use super::*;
43
44    wasm_bindgen_test_configure!(run_in_browser);
45
46    #[allow(dead_code)]
47    fn setup_webapp() -> Object {
48        let win = window().unwrap();
49        let telegram = Object::new();
50        let webapp = Object::new();
51        let _ = Reflect::set(&win, &"Telegram".into(), &telegram);
52        let _ = Reflect::set(&telegram, &"WebApp".into(), &webapp);
53        webapp
54    }
55
56    #[wasm_bindgen_test]
57    #[allow(dead_code, clippy::unused_unit)]
58    fn request_contact_ok() {
59        let webapp = setup_webapp();
60        let func = Function::new_no_args("this.called = true;");
61        let _ = Reflect::set(&webapp, &"requestContact".into(), &func);
62        assert!(request_contact().is_ok());
63        assert!(
64            Reflect::get(&webapp, &"called".into())
65                .unwrap()
66                .as_bool()
67                .unwrap()
68        );
69    }
70
71    #[wasm_bindgen_test]
72    #[allow(dead_code, clippy::unused_unit)]
73    fn request_contact_err() {
74        let _ = setup_webapp();
75        assert!(request_contact().is_err());
76    }
77}