├── example ├── .npmignore ├── index.html ├── tsconfig.json └── package.json ├── .gitignore ├── src ├── index.ts ├── TelegramWebAppContext.ts ├── Telegram │ ├── WebAppEvents.d.ts │ └── Telegram.d.ts └── TelegramWebApp.tsx ├── .idea ├── .gitignore ├── vcs.xml ├── modules.xml └── react-telegram-menu.iml ├── .github └── workflows │ ├── size.yml │ └── main.yml ├── LICENSE ├── tsconfig.json ├── package.json └── README.md /example/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .cache 3 | dist -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | .DS_Store 3 | node_modules 4 | .cache 5 | dist 6 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./TelegramWebApp"; 2 | export * from "./TelegramWebAppContext"; 3 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.github/workflows/size.yml: -------------------------------------------------------------------------------- 1 | name: size 2 | on: [pull_request] 3 | jobs: 4 | size: 5 | runs-on: ubuntu-latest 6 | env: 7 | CI_JOB_NUMBER: 1 8 | steps: 9 | - uses: actions/checkout@v1 10 | - uses: andresz1/size-limit-action@v1 11 | with: 12 | github_token: ${{ secrets.GITHUB_TOKEN }} 13 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Playground 8 | 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/react-telegram-menu.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": false, 4 | "target": "es5", 5 | "module": "commonjs", 6 | "jsx": "react", 7 | "moduleResolution": "node", 8 | "noImplicitAny": false, 9 | "noUnusedLocals": false, 10 | "noUnusedParameters": false, 11 | "removeComments": true, 12 | "strictNullChecks": true, 13 | "preserveConstEnums": true, 14 | "sourceMap": true, 15 | "lib": ["es2015", "es2016", "dom"], 16 | "types": ["node"] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "start": "parcel index.html", 8 | "build": "parcel build index.html" 9 | }, 10 | "dependencies": { 11 | "react-app-polyfill": "^1.0.0" 12 | }, 13 | "alias": { 14 | "react": "../node_modules/react", 15 | "react-dom": "../node_modules/react-dom/profiling", 16 | "scheduler/tracing": "../node_modules/scheduler/tracing-profiling" 17 | }, 18 | "devDependencies": { 19 | "@types/react": "^16.9.11", 20 | "@types/react-dom": "^16.8.4", 21 | "parcel": "^1.12.3", 22 | "typescript": "^3.4.5" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/TelegramWebAppContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext, useContext } from "react"; 2 | import { Telegram } from "./Telegram/Telegram"; 3 | 4 | export type TelegramWebAppModel = { 5 | app: Telegram.Unsafe.WebApp; 6 | startParam: string | null; 7 | isReady: boolean; 8 | }; 9 | 10 | export const TelegramWebAppContext = createContext({} as any); 11 | 12 | export function useStartParam() { 13 | const { startParam } = useContext(TelegramWebAppContext); 14 | return startParam; 15 | } 16 | 17 | export function useTelegramWebApp() { 18 | const { app } = useContext(TelegramWebAppContext); 19 | return app; 20 | } 21 | 22 | export function useIsTelegramWebAppReady() { 23 | const { isReady } = useContext(TelegramWebAppContext); 24 | return isReady; 25 | } 26 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push] 3 | jobs: 4 | build: 5 | name: Build, lint, and test on Node ${{ matrix.node }} and ${{ matrix.os }} 6 | 7 | runs-on: ${{ matrix.os }} 8 | strategy: 9 | matrix: 10 | node: ['10.x', '12.x', '14.x'] 11 | os: [ubuntu-latest, windows-latest, macOS-latest] 12 | 13 | steps: 14 | - name: Checkout repo 15 | uses: actions/checkout@v2 16 | 17 | - name: Use Node ${{ matrix.node }} 18 | uses: actions/setup-node@v1 19 | with: 20 | node-version: ${{ matrix.node }} 21 | 22 | - name: Install deps and build (with cache) 23 | uses: bahmutov/npm-install@v1 24 | 25 | - name: Test 26 | run: yarn test --ci --coverage --maxWorkers=2 27 | 28 | - name: Build 29 | run: yarn build 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 David Slutsky 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /src/Telegram/WebAppEvents.d.ts: -------------------------------------------------------------------------------- 1 | namespace Telegram.Unsafe.Events { 2 | /** Receives no parameters, new theme settings and color scheme can be received via `this.themeParams` and `this.colorScheme` respectively. */ 3 | type OnThemeChangedHandler = () => void; 4 | 5 | /** Receives an object with the single field `isStateStable`. If `isStateStable` = true, the resizing of the Web App is finished. If it is false, the resizing is ongoing (the user is expanding or collapsing the Web App or an animated object is playing). The current value of the visible section’s height is available in `this.viewportHeight`. */ 6 | type OnViewPortChangedHandler = ( 7 | this: WebApp, 8 | props: { 9 | isStateStable: boolean; 10 | } 11 | ) => void; 12 | 13 | /** Receives no parameters. */ 14 | type OnMainButtonClickedHandler = (this: WebApp) => void; 15 | 16 | type Events = { 17 | /** Occurs whenever theme settings are changed in the user's Telegram app (including switching to night mode). */ 18 | themeChanged: OnThemeChangedHandler; 19 | viewPortChanged: OnViewPortChangedHandler; 20 | mainButtonClicked: OnMainButtonClickedHandler; 21 | }; 22 | 23 | export type EventsNames = keyof Events; 24 | export type EventHandlerArguments = Parameters; 25 | export type EventHandlerReturnType = ReturnType; 26 | export type EventHandler = ( 27 | this: WebApp, 28 | ...args: EventHandlerArguments 29 | ) => EventHandlerReturnType; 30 | } 31 | 32 | export = Telegram.Unsafe.Events; 33 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs 3 | "include": ["src", "types"], 4 | "compilerOptions": { 5 | "module": "esnext", 6 | "target": "ES5", 7 | "lib": ["dom", "esnext"], 8 | "importHelpers": true, 9 | // output .d.ts declaration files for consumers 10 | "declaration": true, 11 | // output .js.map sourcemap files for consumers 12 | "sourceMap": true, 13 | // match output dir to input dir. e.g. dist/index instead of dist/src/index 14 | "rootDir": "./src", 15 | // stricter type-checking for stronger correctness. Recommended by TS 16 | "strict": true, 17 | // linter checks for common issues 18 | "noImplicitReturns": true, 19 | "noFallthroughCasesInSwitch": true, 20 | // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative 21 | "noUnusedLocals": true, 22 | "noUnusedParameters": true, 23 | // use Node's module resolution algorithm, instead of the legacy TS one 24 | "moduleResolution": "node", 25 | // transpile JSX to React.createElement 26 | "jsx": "react", 27 | // interop between ESM and CJS modules. Recommended by TS 28 | "esModuleInterop": true, 29 | // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS 30 | "skipLibCheck": true, 31 | // error out if import and file system have a casing mismatch. Recommended by TS 32 | "forceConsistentCasingInFileNames": true, 33 | // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` 34 | "noEmit": true 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "repository": { 3 | "type": "git", 4 | "url": "https://github.com/davidsl4/react-telegram-webapp" 5 | }, 6 | "version": "0.1.5", 7 | "license": "MIT", 8 | "main": "dist/index.js", 9 | "typings": "dist/index.d.ts", 10 | "files": [ 11 | "dist", 12 | "src" 13 | ], 14 | "engines": { 15 | "node": ">=10" 16 | }, 17 | "scripts": { 18 | "lint": "tsdx lint", 19 | "size": "size-limit", 20 | "start": "tsdx watch", 21 | "build": "tsdx build", 22 | "prepare": "tsdx build", 23 | "analyze": "size-limit --why", 24 | "test": "tsdx test --passWithNoTests" 25 | }, 26 | "peerDependencies": { 27 | "react": ">=16" 28 | }, 29 | "husky": { 30 | "hooks": { 31 | "pre-commit": "tsdx lint" 32 | } 33 | }, 34 | "prettier": { 35 | "semi": true, 36 | "tabWidth": 2, 37 | "printWidth": 130, 38 | "singleQuote": false, 39 | "trailingComma": "es5" 40 | }, 41 | "name": "react-telegram-webapp", 42 | "author": "David Slutsky", 43 | "module": "dist/react-telegram-webapp.esm.js", 44 | "size-limit": [ 45 | { 46 | "path": "dist/react-telegram-webapp.cjs.production.min.js", 47 | "limit": "10 KB" 48 | }, 49 | { 50 | "path": "dist/react-telegram-webapp.esm.js", 51 | "limit": "10 KB" 52 | } 53 | ], 54 | "devDependencies": { 55 | "@size-limit/preset-small-lib": "^7.0.8", 56 | "@types/react": "^18.0.5", 57 | "@types/react-dom": "^18.0.1", 58 | "husky": "^7.0.4", 59 | "react": "^18.0.0", 60 | "react-dom": "^18.0.0", 61 | "size-limit": "^7.0.8", 62 | "tsdx": "^0.14.1", 63 | "tslib": "^2.3.1", 64 | "typescript": "^3.9.10" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React context for Telegram WebApp 2 | This library can be used to create React UIs in use with the new Telegram WebApp feature. 3 | This library use context to feed all your components with the current state of the Telegram props. 4 | 5 | ## Usage (with Component) 6 | Wrap your components with a `TelegramWebApp` component. 7 | It receives a `validateHash` function, which will be called to validate the hash received from Telegram. 8 | 9 | ```js 10 | import React from 'react'; 11 | import ReactDOM from 'react-dom'; 12 | import { TelegramWebApp } from 'react-telegram-webapp'; 13 | 14 | async function validateHash(hash) { 15 | const response = await fetch(`/api/validate`, { 16 | method: 'POST', 17 | headers: { 18 | 'Content-Type': 'application/json', 19 | }, 20 | body: JSON.stringify({ hash }), 21 | }); 22 | 23 | return response.ok; 24 | } 25 | 26 | ReactDOM.render( 27 | 28 | 29 | , 30 | document.getElementById('root') 31 | ); 32 | ``` 33 | 34 | ## Usage (with wrapper function) 35 | You can also wrap your components with a `withTelegramWebApp` function. 36 | It also receives a `validateHash` function, which will be called to validate the hash received from Telegram. 37 | 38 | ```js 39 | import React from 'react'; 40 | import { withTelegramWebApp } from 'react-telegram-webapp'; 41 | 42 | function App() { 43 | return ; 44 | } 45 | 46 | async function validateHash(hash) { 47 | const response = await fetch(`/api/validate`, { 48 | method: 'POST', 49 | headers: { 50 | 'Content-Type': 'application/json', 51 | }, 52 | body: JSON.stringify({ hash }), 53 | }); 54 | 55 | return response.ok; 56 | } 57 | 58 | export default withTelegramWebApp(App, { 59 | validateHash 60 | }); 61 | ``` 62 | 63 | ## Useful hooks 64 | `useStartParam` - return the [start params](https://core.telegram.org/bots/webapps#webappinitdata) 65 | `useTelegramWebApp` - return the [TelegramWebApp](https://github.com/davidsl4/react-telegram-webapp/blob/ee7861dbfa9f42d42f1a200a33a47c11c59d4a87/src/Telegram/Telegram.d.ts#L4-L99) object 66 | `useIsTelegramWebAppReady` - returns true if the TelegramWebApp is ready. You can use this to show loading screen 67 | 68 | 69 | ## Contribute 70 | If you want to contribute to this library, please open an issue or pull request. 71 | -------------------------------------------------------------------------------- /src/TelegramWebApp.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { ComponentType, useEffect, useRef, useState } from "react"; 3 | import { TelegramWebAppModel, TelegramWebAppContext } from "./TelegramWebAppContext"; 4 | 5 | type TelegramWebAppProps = { 6 | children: JSX.Element; 7 | validateHash(hash: string): boolean | Promise; 8 | }; 9 | 10 | export function TelegramWebApp({ children, validateHash }: TelegramWebAppProps) { 11 | const [isReady, setIsReady] = useState(false); 12 | const [isValid, setIsValid] = useState(false); 13 | const tgWebAppStartParamRef = useRef(new URLSearchParams(window.location.search).get("tgWebAppStartParam")); 14 | 15 | const model: TelegramWebAppModel = { 16 | get app() { 17 | return (window as any).Telegram?.WebApp; 18 | }, 19 | startParam: tgWebAppStartParamRef.current!, 20 | isReady, 21 | }; 22 | 23 | const onReady = () => { 24 | const hashValidation = validateHash(model.app.initData); 25 | if (hashValidation instanceof Promise) { 26 | hashValidation.then(setIsValid).finally(() => setIsReady(true)); 27 | } else { 28 | setIsValid(hashValidation); 29 | setIsReady(true); 30 | } 31 | }; 32 | 33 | useEffect(() => { 34 | if (isReady && !isValid) throw new Error("Invalid hash"); 35 | }, [isReady, isValid]); 36 | 37 | return ( 38 | 39 | {children} 40 | 41 | ); 42 | } 43 | 44 | export function withTelegramWebApp(Component: ComponentType, contextProps: Omit) { 45 | return function WithTelegramWebApp(props: any) { 46 | return ( 47 | 48 | 49 | 50 | ); 51 | }; 52 | } 53 | 54 | function TelegramWebAppScript({ children, onLoad }: { children: JSX.Element; onLoad: () => void }) { 55 | // inject on load, remove on unload (using effect), but only once per page 56 | useEffect(() => { 57 | const tgWebAppScript = document.createElement("script"); 58 | tgWebAppScript.src = "https://telegram.org/js/telegram-web-app.js"; 59 | tgWebAppScript.onload = onLoad; 60 | 61 | document.head.appendChild(tgWebAppScript); 62 | (window as any).__TELEGRAM_WEB_APP_SCRIPT_INJECTED__ = true; 63 | 64 | return () => { 65 | document.head.removeChild(tgWebAppScript); 66 | (window as any).__TELEGRAM_WEB_APP_SCRIPT_INJECTED__ = false; 67 | }; 68 | }, []); 69 | 70 | return children; 71 | } 72 | -------------------------------------------------------------------------------- /src/Telegram/Telegram.d.ts: -------------------------------------------------------------------------------- 1 | import { EventHandler } from "./WebAppEvents"; 2 | 3 | export namespace Telegram.Unsafe { 4 | export type WebApp = { 5 | /** A string with raw data transferred to the Web App, convenient for [validating data](https://core.telegram.org/bots/webapps#validating-data-received-via-the-web-app). 6 | * 7 | * **WARNING:** [Validate data](https://core.telegram.org/bots/webapps#validating-data-received-via-the-web-app) from this field before using it on the bot's server. */ 8 | initData: string; 9 | 10 | /** 11 | * An object with input data transferred to the Web App. 12 | * 13 | * **WARNING:** Data from this field should not be trusted. You should only use data from initData on the bot's server and only after it has been [validated](https://core.telegram.org/bots/webapps#validating-data-received-via-the-web-app). 14 | */ 15 | initDataUnsafe: WebAppInitData; 16 | 17 | /** The color scheme currently used in the Telegram app. */ 18 | colorScheme: "light" | "dark"; 19 | 20 | /** An object containing the current theme settings used in the Telegram app. */ 21 | themeParams: ThemeParams; 22 | 23 | /** 24 | * _True_ if the Web App is expanded to the maximum available height. _False_, if the Web App occupies part of the screen and can be expanded to the full height using the **expand()** method. 25 | * 26 | * @see expand 27 | */ 28 | isExpanded: boolean; 29 | 30 | /** 31 | * The current height of the visible area of the Web App. 32 | * 33 | * The application can display just the top part of the Web App, with its lower part remaining outside the screen area. From this position, the user can “pull” the Web App to its maximum height, while the bot can do the same by calling the **expand()** method. As the position of the Web App changes, the current height value of the visible area will be updated in real time. 34 | * 35 | * Please note that the refresh rate of this value is not sufficient to smoothly follow the lower border of the window. It should not be used to pin interface elements to the bottom of the visible area. It's more appropriate to use the value of the `viewportStableHeight` field for this purpose. 36 | */ 37 | viewportHeight: number; 38 | 39 | /** 40 | * The height of the visible area of the Web App in its last stable state. 41 | * 42 | * Unlike the value of `viewportHeight`, the value of `viewportStableHeight` does not change as the position of the Web App changes with user gestures or during animations. The value of `viewportStableHeight` will be updated after all gestures and animations are completed and the Web App reaches its final size. 43 | */ 44 | viewportStableHeight: number; 45 | 46 | /** An object for controlling the main button, which is displayed at the bottom of the Web App in the Telegram interface. */ 47 | MainButton: MainButton; 48 | 49 | /** 50 | * Occurs whenever theme settings are changed in the user's Telegram app (including switching to night mode). 51 | * 52 | * @param event The name of the event. 53 | * @param eventHandler The callback to execute. Receives no parameters, new theme settings and color scheme can be received via `this.themeParams` and `this.colorScheme` respectively. 54 | */ 55 | onEvent(event: "themeChanged", eventHandler: EventHandler<"themeChanged">): void; 56 | 57 | /** 58 | * Occurs when the visible section of the Web App is changed. 59 | * @param event The name of the event. 60 | * @param eventHandler The callback to execute. Receives an object with the single field `isStateStable`. If `isStateStable` = true, the resizing of the Web App is finished. If it is false, the resizing is ongoing (the user is expanding or collapsing the Web App or an animated object is playing). The current value of the visible section’s height is available in `this.viewportHeight`. 61 | */ 62 | onEvent(event: "viewportChanged", eventHandler: EventHandler<"viewPortChanged">): void; 63 | 64 | /** 65 | * Occurs when the {@link MainButton main button} is pressed. 66 | * @param event The name of the event. 67 | * @param eventHandler The callback to execute. Receives no parameters. 68 | */ 69 | onEvent(event: "mainButtonClicked", eventHandler: EventHandler<"mainButtonClicked">): void; 70 | 71 | /** A method that deletes a previously set event handler. */ 72 | offEvent( 73 | event: "themeChanged" | "viewportChanged" | "mainButtonClicked", 74 | eventHandler: EventHandler<"themeChanged" | "viewportChanged" | "mainButtonClicked"> 75 | ): void; 76 | 77 | /** 78 | * A method used to send data to the bot. When this method is called, a service message is sent to the bot containing the data `data` of the length up to 4096 bytes, and the Web App is closed. See the field `web_app_data` in the class [Message](https://core.telegram.org/bots/api#message). 79 | * 80 | * _This method is only available for Web Apps launched via a [Keyboard button](https://core.telegram.org/bots/webapps#keyboard-button-web-apps)._ 81 | */ 82 | sendData(data: any): void; 83 | 84 | /** 85 | * A method that informs the Telegram app that the Web App is ready to be displayed. 86 | * 87 | * It is recommended to call this method as early as possible, as soon as all essential interface elements are loaded. Once this method is called, the loading placeholder is hidden and the Web App is shown. 88 | * 89 | * If the method is not called, the placeholder will be hidden only when the page is fully loaded. 90 | */ 91 | ready(): void; 92 | 93 | /** 94 | * A method that expands the Web App to the maximum available height. 95 | * 96 | * @see isExpanded 97 | */ 98 | expand(): void; 99 | 100 | /** A method that closes the Web App. */ 101 | close(): void; 102 | }; 103 | 104 | export type ThemeParams = { 105 | /** Background color in the `#RRGGBB` format */ 106 | bg_color?: string; 107 | 108 | /** Main text color in the `#RRGGBB` format */ 109 | text_color?: string; 110 | 111 | /** Hint text color in the `#RRGGBB` format */ 112 | hint_color?: string; 113 | 114 | /** Link color in the `#RRGGBB` format */ 115 | link_color?: string; 116 | 117 | /** Button color in the `#RRGGBB` format */ 118 | button_color?: string; 119 | 120 | /** Button text color in the `#RRGGBB` format */ 121 | button_text_color?: string; 122 | }; 123 | 124 | export type MainButton = { 125 | /** Current button text. Set to `CONTINUE` by default. */ 126 | text: string; 127 | 128 | /** Current button color. Set to `themeParams.button_color` by default. */ 129 | color: string; 130 | 131 | /** Current button text color. Set to `themeParams.button_text_color` by default. */ 132 | text_color: string; 133 | 134 | /** Shows whether the button is visible. Set to `false` by default */ 135 | isVisible: boolean; 136 | 137 | /** Shows whether the button is active. Set to `true` by default */ 138 | isActive: boolean; 139 | 140 | /** @readonly Shows whether the button is displaying a loading indicator */ 141 | isLoading: boolean; 142 | 143 | /** 144 | * A method to set the button text. 145 | * 146 | * @param text New button text. 147 | */ 148 | setText(this: MainButton, text: string): void; 149 | 150 | /** A method that sets the button press event handler 151 | * 152 | * An alias for {@link WebApp.onEvent WebApp.onEvent with `mainButtonClicked` event}. 153 | */ 154 | onClick(this: MainButton, handler: EventHandler<"mainButtonClicked">): void; 155 | 156 | /** 157 | * A method to make the button visible. 158 | * 159 | * _Note that opening the Web App from the [attachment menu](https://core.telegram.org/bots/webapps#launching-web-apps-from-the-attachment-menu) hides the main button until the user interacts with the Web App interface._ 160 | */ 161 | show(this: MainButton): void; 162 | 163 | /** A method to hide the button. */ 164 | hide(this: MainButton): void; 165 | 166 | /** A method to enable the button. */ 167 | enable(this: MainButton): void; 168 | 169 | /** A method to disable the button. */ 170 | disable(this: MainButton): void; 171 | 172 | /** 173 | * A method to show a loading indicator on the button. 174 | * 175 | * It is recommended to display loading progress if the action tied to the button may take a long time. 176 | * 177 | * @param leaveActive If `true`, the button remains enabled while the action in progress. Set to `false` by default. 178 | */ 179 | showProgress(this: MainButton, leaveActive: boolean = false): void; 180 | 181 | /** A method to hide the loading indicator on the button. */ 182 | hideProgress(this: MainButton): void; 183 | 184 | /** 185 | * A method to set the button parameters. 186 | * @param params An object containing one or several fields that need to be changed. 187 | */ 188 | setParams( 189 | this: MainButton, 190 | params: { 191 | /** Current button text. */ 192 | text?: string; 193 | 194 | /** Current button color. */ 195 | color?: string; 196 | 197 | /** Current button text color. */ 198 | text_color?: string; 199 | 200 | /** Shows whether the button is visible. */ 201 | is_visible?: boolean; 202 | 203 | /** Shows whether the button is active. */ 204 | is_active?: boolean; 205 | } 206 | ): void; 207 | }; 208 | 209 | export type WebAppInitData = { 210 | /** A unique identifier for the Web App session, required for sending messages via the [answerWebAppQuery](https://core.telegram.org/bots/api#answerwebappquery) method. */ 211 | query_id?: string; 212 | 213 | /** An object containing data about the current user. */ 214 | user?: WebAppUser; 215 | 216 | /** An object containing data about the chat partner of the current user in the chat where the bot was launched via the attachment menu. Returned only for Web Apps launched via the attachment menu. */ 217 | receiver?: WebAppUser; 218 | 219 | /** 220 | * The value of the `startattach` parameter, passed via link. Only returned for Web Apps when launched from the attachment menu via link. 221 | * 222 | * The value of the `start_param` parameter will also be returned in the {@link useStartParam}, so the Web App can load the correct interface right away. 223 | * 224 | * @see useStartParam 225 | */ 226 | start_param?: string; 227 | 228 | /** Unix time when the form was opened. */ 229 | auth_date: number; 230 | 231 | /** A hash of all passed parameters, which the bot server can use to [check their validity](https://core.telegram.org/bots/webapps#validating-data-received-via-the-web-app). */ 232 | hash: string; 233 | }; 234 | 235 | export type WebAppUser = { 236 | /** A unique identifier for the user or bot. */ 237 | id: number; 238 | 239 | /** `True`, if this user is a bot. Returns in the {@link WebAppInitData.receiver receiver} field only */ 240 | is_bot?: boolean; 241 | 242 | /** First name of the user or bot. */ 243 | first_name: string; 244 | 245 | /** Last name of the user or bot. */ 246 | last_name?: string; 247 | 248 | /** Username of the user or bot. */ 249 | username?: string; 250 | 251 | /** [IETF language tag](https://en.wikipedia.org/wiki/IETF_language_tag) of the user's language. Returns in {@link WebAppInitData.user user} field only */ 252 | language_code?: 253 | | "af" 254 | | "af-NA" 255 | | "af-ZA" 256 | | "agq" 257 | | "agq-CM" 258 | | "ak" 259 | | "ak-GH" 260 | | "am" 261 | | "am-ET" 262 | | "ar" 263 | | "ar-001" 264 | | "ar-AE" 265 | | "ar-BH" 266 | | "ar-DJ" 267 | | "ar-DZ" 268 | | "ar-EG" 269 | | "ar-EH" 270 | | "ar-ER" 271 | | "ar-IL" 272 | | "ar-IQ" 273 | | "ar-JO" 274 | | "ar-KM" 275 | | "ar-KW" 276 | | "ar-LB" 277 | | "ar-LY" 278 | | "ar-MA" 279 | | "ar-MR" 280 | | "ar-OM" 281 | | "ar-PS" 282 | | "ar-QA" 283 | | "ar-SA" 284 | | "ar-SD" 285 | | "ar-SO" 286 | | "ar-SS" 287 | | "ar-SY" 288 | | "ar-TD" 289 | | "ar-TN" 290 | | "ar-YE" 291 | | "as" 292 | | "as-IN" 293 | | "asa" 294 | | "asa-TZ" 295 | | "ast" 296 | | "ast-ES" 297 | | "az" 298 | | "az-Cyrl" 299 | | "az-Cyrl-AZ" 300 | | "az-Latn" 301 | | "az-Latn-AZ" 302 | | "bas" 303 | | "bas-CM" 304 | | "be" 305 | | "be-BY" 306 | | "bem" 307 | | "bem-ZM" 308 | | "bez" 309 | | "bez-TZ" 310 | | "bg" 311 | | "bg-BG" 312 | | "bm" 313 | | "bm-ML" 314 | | "bn" 315 | | "bn-BD" 316 | | "bn-IN" 317 | | "bo" 318 | | "bo-CN" 319 | | "bo-IN" 320 | | "br" 321 | | "br-FR" 322 | | "brx" 323 | | "brx-IN" 324 | | "bs" 325 | | "bs-Cyrl" 326 | | "bs-Cyrl-BA" 327 | | "bs-Latn" 328 | | "bs-Latn-BA" 329 | | "ca" 330 | | "ca-AD" 331 | | "ca-ES" 332 | | "ca-ES-VALENCIA" 333 | | "ca-FR" 334 | | "ca-IT" 335 | | "ccp" 336 | | "ccp-BD" 337 | | "ccp-IN" 338 | | "ce" 339 | | "ce-RU" 340 | | "ceb" 341 | | "ceb-PH" 342 | | "cgg" 343 | | "cgg-UG" 344 | | "chr" 345 | | "chr-US" 346 | | "ckb" 347 | | "ckb-IQ" 348 | | "ckb-IR" 349 | | "cs" 350 | | "cs-CZ" 351 | | "cu" 352 | | "cu-RU" 353 | | "cy" 354 | | "cy-GB" 355 | | "da" 356 | | "da-DK" 357 | | "da-GL" 358 | | "dav" 359 | | "dav-KE" 360 | | "de" 361 | | "de-AT" 362 | | "de-BE" 363 | | "de-CH" 364 | | "de-DE" 365 | | "de-IT" 366 | | "de-LI" 367 | | "de-LU" 368 | | "dje" 369 | | "dje-NE" 370 | | "dsb" 371 | | "dsb-DE" 372 | | "dua" 373 | | "dua-CM" 374 | | "dyo" 375 | | "dyo-SN" 376 | | "dz" 377 | | "dz-BT" 378 | | "ebu" 379 | | "ebu-KE" 380 | | "ee" 381 | | "ee-GH" 382 | | "ee-TG" 383 | | "el" 384 | | "el-CY" 385 | | "el-GR" 386 | | "en" 387 | | "en-001" 388 | | "en-150" 389 | | "en-AE" 390 | | "en-AG" 391 | | "en-AI" 392 | | "en-AS" 393 | | "en-AT" 394 | | "en-AU" 395 | | "en-BB" 396 | | "en-BE" 397 | | "en-BI" 398 | | "en-BM" 399 | | "en-BS" 400 | | "en-BW" 401 | | "en-BZ" 402 | | "en-CA" 403 | | "en-CC" 404 | | "en-CH" 405 | | "en-CK" 406 | | "en-CM" 407 | | "en-CX" 408 | | "en-CY" 409 | | "en-DE" 410 | | "en-DG" 411 | | "en-DK" 412 | | "en-DM" 413 | | "en-ER" 414 | | "en-FI" 415 | | "en-FJ" 416 | | "en-FK" 417 | | "en-FM" 418 | | "en-GB" 419 | | "en-GD" 420 | | "en-GG" 421 | | "en-GH" 422 | | "en-GI" 423 | | "en-GM" 424 | | "en-GU" 425 | | "en-GY" 426 | | "en-HK" 427 | | "en-IE" 428 | | "en-IL" 429 | | "en-IM" 430 | | "en-IN" 431 | | "en-IO" 432 | | "en-JE" 433 | | "en-JM" 434 | | "en-KE" 435 | | "en-KI" 436 | | "en-KN" 437 | | "en-KY" 438 | | "en-LC" 439 | | "en-LR" 440 | | "en-LS" 441 | | "en-MG" 442 | | "en-MH" 443 | | "en-MO" 444 | | "en-MP" 445 | | "en-MS" 446 | | "en-MT" 447 | | "en-MU" 448 | | "en-MW" 449 | | "en-MY" 450 | | "en-NA" 451 | | "en-NF" 452 | | "en-NG" 453 | | "en-NL" 454 | | "en-NR" 455 | | "en-NU" 456 | | "en-NZ" 457 | | "en-PG" 458 | | "en-PH" 459 | | "en-PK" 460 | | "en-PN" 461 | | "en-PR" 462 | | "en-PW" 463 | | "en-RW" 464 | | "en-SB" 465 | | "en-SC" 466 | | "en-SD" 467 | | "en-SE" 468 | | "en-SG" 469 | | "en-SH" 470 | | "en-SI" 471 | | "en-SL" 472 | | "en-SS" 473 | | "en-SX" 474 | | "en-SZ" 475 | | "en-TC" 476 | | "en-TK" 477 | | "en-TO" 478 | | "en-TT" 479 | | "en-TV" 480 | | "en-TZ" 481 | | "en-UG" 482 | | "en-UM" 483 | | "en-US" 484 | | "en-US-POSIX" 485 | | "en-VC" 486 | | "en-VG" 487 | | "en-VI" 488 | | "en-VU" 489 | | "en-WS" 490 | | "en-ZA" 491 | | "en-ZM" 492 | | "en-ZW" 493 | | "eo" 494 | | "eo-001" 495 | | "es" 496 | | "es-419" 497 | | "es-AR" 498 | | "es-BO" 499 | | "es-BR" 500 | | "es-BZ" 501 | | "es-CL" 502 | | "es-CO" 503 | | "es-CR" 504 | | "es-CU" 505 | | "es-DO" 506 | | "es-EA" 507 | | "es-EC" 508 | | "es-ES" 509 | | "es-GQ" 510 | | "es-GT" 511 | | "es-HN" 512 | | "es-IC" 513 | | "es-MX" 514 | | "es-NI" 515 | | "es-PA" 516 | | "es-PE" 517 | | "es-PH" 518 | | "es-PR" 519 | | "es-PY" 520 | | "es-SV" 521 | | "es-US" 522 | | "es-UY" 523 | | "es-VE" 524 | | "et" 525 | | "et-EE" 526 | | "eu" 527 | | "eu-ES" 528 | | "ewo" 529 | | "ewo-CM" 530 | | "fa" 531 | | "fa-AF" 532 | | "fa-IR" 533 | | "ff" 534 | | "ff-Adlm" 535 | | "ff-Adlm-BF" 536 | | "ff-Adlm-CM" 537 | | "ff-Adlm-GH" 538 | | "ff-Adlm-GM" 539 | | "ff-Adlm-GN" 540 | | "ff-Adlm-GW" 541 | | "ff-Adlm-LR" 542 | | "ff-Adlm-MR" 543 | | "ff-Adlm-NE" 544 | | "ff-Adlm-NG" 545 | | "ff-Adlm-SL" 546 | | "ff-Adlm-SN" 547 | | "ff-Latn" 548 | | "ff-Latn-BF" 549 | | "ff-Latn-CM" 550 | | "ff-Latn-GH" 551 | | "ff-Latn-GM" 552 | | "ff-Latn-GN" 553 | | "ff-Latn-GW" 554 | | "ff-Latn-LR" 555 | | "ff-Latn-MR" 556 | | "ff-Latn-NE" 557 | | "ff-Latn-NG" 558 | | "ff-Latn-SL" 559 | | "ff-Latn-SN" 560 | | "fi" 561 | | "fi-FI" 562 | | "fil" 563 | | "fil-PH" 564 | | "fo" 565 | | "fo-DK" 566 | | "fo-FO" 567 | | "fr" 568 | | "fr-BE" 569 | | "fr-BF" 570 | | "fr-BI" 571 | | "fr-BJ" 572 | | "fr-BL" 573 | | "fr-CA" 574 | | "fr-CD" 575 | | "fr-CF" 576 | | "fr-CG" 577 | | "fr-CH" 578 | | "fr-CI" 579 | | "fr-CM" 580 | | "fr-DJ" 581 | | "fr-DZ" 582 | | "fr-FR" 583 | | "fr-GA" 584 | | "fr-GF" 585 | | "fr-GN" 586 | | "fr-GP" 587 | | "fr-GQ" 588 | | "fr-HT" 589 | | "fr-KM" 590 | | "fr-LU" 591 | | "fr-MA" 592 | | "fr-MC" 593 | | "fr-MF" 594 | | "fr-MG" 595 | | "fr-ML" 596 | | "fr-MQ" 597 | | "fr-MR" 598 | | "fr-MU" 599 | | "fr-NC" 600 | | "fr-NE" 601 | | "fr-PF" 602 | | "fr-PM" 603 | | "fr-RE" 604 | | "fr-RW" 605 | | "fr-SC" 606 | | "fr-SN" 607 | | "fr-SY" 608 | | "fr-TD" 609 | | "fr-TG" 610 | | "fr-TN" 611 | | "fr-VU" 612 | | "fr-WF" 613 | | "fr-YT" 614 | | "fur" 615 | | "fur-IT" 616 | | "fy" 617 | | "fy-NL" 618 | | "ga" 619 | | "ga-GB" 620 | | "ga-IE" 621 | | "gd" 622 | | "gd-GB" 623 | | "gl" 624 | | "gl-ES" 625 | | "gsw" 626 | | "gsw-CH" 627 | | "gsw-FR" 628 | | "gsw-LI" 629 | | "gu" 630 | | "gu-IN" 631 | | "guz" 632 | | "guz-KE" 633 | | "gv" 634 | | "gv-IM" 635 | | "ha" 636 | | "ha-GH" 637 | | "ha-NE" 638 | | "ha-NG" 639 | | "haw" 640 | | "haw-US" 641 | | "he" 642 | | "he-IL" 643 | | "hi" 644 | | "hi-IN" 645 | | "hr" 646 | | "hr-BA" 647 | | "hr-HR" 648 | | "hsb" 649 | | "hsb-DE" 650 | | "hu" 651 | | "hu-HU" 652 | | "hy" 653 | | "hy-AM" 654 | | "ia" 655 | | "ia-001" 656 | | "id" 657 | | "id-ID" 658 | | "ig" 659 | | "ig-NG" 660 | | "ii" 661 | | "ii-CN" 662 | | "is" 663 | | "is-IS" 664 | | "it" 665 | | "it-CH" 666 | | "it-IT" 667 | | "it-SM" 668 | | "it-VA" 669 | | "ja" 670 | | "ja-JP" 671 | | "jgo" 672 | | "jgo-CM" 673 | | "jmc" 674 | | "jmc-TZ" 675 | | "jv" 676 | | "jv-ID" 677 | | "ka" 678 | | "ka-GE" 679 | | "kab" 680 | | "kab-DZ" 681 | | "kam" 682 | | "kam-KE" 683 | | "kde" 684 | | "kde-TZ" 685 | | "kea" 686 | | "kea-CV" 687 | | "khq" 688 | | "khq-ML" 689 | | "ki" 690 | | "ki-KE" 691 | | "kk" 692 | | "kk-KZ" 693 | | "kkj" 694 | | "kkj-CM" 695 | | "kl" 696 | | "kl-GL" 697 | | "kln" 698 | | "kln-KE" 699 | | "km" 700 | | "km-KH" 701 | | "kn" 702 | | "kn-IN" 703 | | "ko" 704 | | "ko-KP" 705 | | "ko-KR" 706 | | "kok" 707 | | "kok-IN" 708 | | "ks" 709 | | "ks-Arab" 710 | | "ks-Arab-IN" 711 | | "ksb" 712 | | "ksb-TZ" 713 | | "ksf" 714 | | "ksf-CM" 715 | | "ksh" 716 | | "ksh-DE" 717 | | "ku" 718 | | "ku-TR" 719 | | "kw" 720 | | "kw-GB" 721 | | "ky" 722 | | "ky-KG" 723 | | "lag" 724 | | "lag-TZ" 725 | | "lb" 726 | | "lb-LU" 727 | | "lg" 728 | | "lg-UG" 729 | | "lkt" 730 | | "lkt-US" 731 | | "ln" 732 | | "ln-AO" 733 | | "ln-CD" 734 | | "ln-CF" 735 | | "ln-CG" 736 | | "lo" 737 | | "lo-LA" 738 | | "lrc" 739 | | "lrc-IQ" 740 | | "lrc-IR" 741 | | "lt" 742 | | "lt-LT" 743 | | "lu" 744 | | "lu-CD" 745 | | "luo" 746 | | "luo-KE" 747 | | "luy" 748 | | "luy-KE" 749 | | "lv" 750 | | "lv-LV" 751 | | "mai" 752 | | "mai-IN" 753 | | "mas" 754 | | "mas-KE" 755 | | "mas-TZ" 756 | | "mer" 757 | | "mer-KE" 758 | | "mfe" 759 | | "mfe-MU" 760 | | "mg" 761 | | "mg-MG" 762 | | "mgh" 763 | | "mgh-MZ" 764 | | "mgo" 765 | | "mgo-CM" 766 | | "mi" 767 | | "mi-NZ" 768 | | "mk" 769 | | "mk-MK" 770 | | "ml" 771 | | "ml-IN" 772 | | "mn" 773 | | "mn-MN" 774 | | "mni" 775 | | "mni-Beng" 776 | | "mni-Beng-IN" 777 | | "mr" 778 | | "mr-IN" 779 | | "ms" 780 | | "ms-BN" 781 | | "ms-ID" 782 | | "ms-MY" 783 | | "ms-SG" 784 | | "mt" 785 | | "mt-MT" 786 | | "mua" 787 | | "mua-CM" 788 | | "my" 789 | | "my-MM" 790 | | "mzn" 791 | | "mzn-IR" 792 | | "naq" 793 | | "naq-NA" 794 | | "nb" 795 | | "nb-NO" 796 | | "nb-SJ" 797 | | "nd" 798 | | "nd-ZW" 799 | | "nds" 800 | | "nds-DE" 801 | | "nds-NL" 802 | | "ne" 803 | | "ne-IN" 804 | | "ne-NP" 805 | | "nl" 806 | | "nl-AW" 807 | | "nl-BE" 808 | | "nl-BQ" 809 | | "nl-CW" 810 | | "nl-NL" 811 | | "nl-SR" 812 | | "nl-SX" 813 | | "nmg" 814 | | "nmg-CM" 815 | | "nn" 816 | | "nn-NO" 817 | | "nnh" 818 | | "nnh-CM" 819 | | "nus" 820 | | "nus-SS" 821 | | "nyn" 822 | | "nyn-UG" 823 | | "om" 824 | | "om-ET" 825 | | "om-KE" 826 | | "or" 827 | | "or-IN" 828 | | "os" 829 | | "os-GE" 830 | | "os-RU" 831 | | "pa" 832 | | "pa-Arab" 833 | | "pa-Arab-PK" 834 | | "pa-Guru" 835 | | "pa-Guru-IN" 836 | | "pcm" 837 | | "pcm-NG" 838 | | "pl" 839 | | "pl-PL" 840 | | "prg" 841 | | "prg-001" 842 | | "ps" 843 | | "ps-AF" 844 | | "ps-PK" 845 | | "pt" 846 | | "pt-AO" 847 | | "pt-BR" 848 | | "pt-CH" 849 | | "pt-CV" 850 | | "pt-GQ" 851 | | "pt-GW" 852 | | "pt-LU" 853 | | "pt-MO" 854 | | "pt-MZ" 855 | | "pt-PT" 856 | | "pt-ST" 857 | | "pt-TL" 858 | | "qu" 859 | | "qu-BO" 860 | | "qu-EC" 861 | | "qu-PE" 862 | | "rm" 863 | | "rm-CH" 864 | | "rn" 865 | | "rn-BI" 866 | | "ro" 867 | | "ro-MD" 868 | | "ro-RO" 869 | | "rof" 870 | | "rof-TZ" 871 | | "root" 872 | | "ru" 873 | | "ru-BY" 874 | | "ru-KG" 875 | | "ru-KZ" 876 | | "ru-MD" 877 | | "ru-RU" 878 | | "ru-UA" 879 | | "rw" 880 | | "rw-RW" 881 | | "rwk" 882 | | "rwk-TZ" 883 | | "sah" 884 | | "sah-RU" 885 | | "saq" 886 | | "saq-KE" 887 | | "sat" 888 | | "sat-Olck" 889 | | "sat-Olck-IN" 890 | | "sbp" 891 | | "sbp-TZ" 892 | | "sd" 893 | | "sd-Arab" 894 | | "sd-Arab-PK" 895 | | "sd-Deva" 896 | | "sd-Deva-IN" 897 | | "se" 898 | | "se-FI" 899 | | "se-NO" 900 | | "se-SE" 901 | | "seh" 902 | | "seh-MZ" 903 | | "ses" 904 | | "ses-ML" 905 | | "sg" 906 | | "sg-CF" 907 | | "shi" 908 | | "shi-Latn" 909 | | "shi-Latn-MA" 910 | | "shi-Tfng" 911 | | "shi-Tfng-MA" 912 | | "si" 913 | | "si-LK" 914 | | "sk" 915 | | "sk-SK" 916 | | "sl" 917 | | "sl-SI" 918 | | "smn" 919 | | "smn-FI" 920 | | "sn" 921 | | "sn-ZW" 922 | | "so" 923 | | "so-DJ" 924 | | "so-ET" 925 | | "so-KE" 926 | | "so-SO" 927 | | "sq" 928 | | "sq-AL" 929 | | "sq-MK" 930 | | "sq-XK" 931 | | "sr" 932 | | "sr-Cyrl" 933 | | "sr-Cyrl-BA" 934 | | "sr-Cyrl-ME" 935 | | "sr-Cyrl-RS" 936 | | "sr-Cyrl-XK" 937 | | "sr-Latn" 938 | | "sr-Latn-BA" 939 | | "sr-Latn-ME" 940 | | "sr-Latn-RS" 941 | | "sr-Latn-XK" 942 | | "su" 943 | | "su-Latn" 944 | | "su-Latn-ID" 945 | | "sv" 946 | | "sv-AX" 947 | | "sv-FI" 948 | | "sv-SE" 949 | | "sw" 950 | | "sw-CD" 951 | | "sw-KE" 952 | | "sw-TZ" 953 | | "sw-UG" 954 | | "ta" 955 | | "ta-IN" 956 | | "ta-LK" 957 | | "ta-MY" 958 | | "ta-SG" 959 | | "te" 960 | | "te-IN" 961 | | "teo" 962 | | "teo-KE" 963 | | "teo-UG" 964 | | "tg" 965 | | "tg-TJ" 966 | | "th" 967 | | "th-TH" 968 | | "ti" 969 | | "ti-ER" 970 | | "ti-ET" 971 | | "tk" 972 | | "tk-TM" 973 | | "to" 974 | | "to-TO" 975 | | "tr" 976 | | "tr-CY" 977 | | "tr-TR" 978 | | "tt" 979 | | "tt-RU" 980 | | "twq" 981 | | "twq-NE" 982 | | "tzm" 983 | | "tzm-MA" 984 | | "ug" 985 | | "ug-CN" 986 | | "uk" 987 | | "uk-UA" 988 | | "ur" 989 | | "ur-IN" 990 | | "ur-PK" 991 | | "uz" 992 | | "uz-Arab" 993 | | "uz-Arab-AF" 994 | | "uz-Cyrl" 995 | | "uz-Cyrl-UZ" 996 | | "uz-Latn" 997 | | "uz-Latn-UZ" 998 | | "vai" 999 | | "vai-Latn" 1000 | | "vai-Latn-LR" 1001 | | "vai-Vaii" 1002 | | "vai-Vaii-LR" 1003 | | "vi" 1004 | | "vi-VN" 1005 | | "vo" 1006 | | "vo-001" 1007 | | "vun" 1008 | | "vun-TZ" 1009 | | "wae" 1010 | | "wae-CH" 1011 | | "wo" 1012 | | "wo-SN" 1013 | | "xh" 1014 | | "xh-ZA" 1015 | | "xog" 1016 | | "xog-UG" 1017 | | "yav" 1018 | | "yav-CM" 1019 | | "yi" 1020 | | "yi-001" 1021 | | "yo" 1022 | | "yo-BJ" 1023 | | "yo-NG" 1024 | | "yue" 1025 | | "yue-Hans" 1026 | | "yue-Hans-CN" 1027 | | "yue-Hant" 1028 | | "yue-Hant-HK" 1029 | | "zgh" 1030 | | "zgh-MA" 1031 | | "zh" 1032 | | "zh-Hans" 1033 | | "zh-Hans-CN" 1034 | | "zh-Hans-HK" 1035 | | "zh-Hans-MO" 1036 | | "zh-Hans-SG" 1037 | | "zh-Hant" 1038 | | "zh-Hant-HK" 1039 | | "zh-Hant-MO" 1040 | | "zh-Hant-TW" 1041 | | "zu" 1042 | | string; 1043 | 1044 | /** 1045 | * URL of the user’s profile photo. The photo can be in `.jpeg` or `.svg` formats. 1046 | * 1047 | * Only returned for Web Apps launched from the attachment menu. 1048 | */ 1049 | photo_url?: string; 1050 | }; 1051 | } 1052 | --------------------------------------------------------------------------------