├── .commitlintrc.js ├── .cz-config.js ├── .eslintignore ├── .eslintrc.js ├── .flowconfig ├── .github └── ISSUE_TEMPLATE │ ├── Bug_report.md │ └── Feature_request.md ├── .gitignore ├── .travis.yml ├── README.md ├── bin └── telegram-typings ├── changelog.md ├── flow-typed └── npm │ ├── @babel │ ├── generator_vx.x.x.js │ └── types_v7.0.x.js │ ├── cheerio_v1.0.x.js │ ├── debug_v3.x.x.js │ ├── node-fetch_v1.x.x.js │ └── rust-keywords_v1.x.x.js ├── javascript ├── index.d.ts ├── index.js ├── index.js.flow ├── package.json └── readme.md ├── lib ├── builders │ ├── abstract-js.js │ ├── base.js │ ├── flow.js │ ├── rust.js │ └── typescript.js ├── main.js ├── native.js ├── parser.js └── store.js ├── license ├── package-lock.json ├── package.json ├── rust ├── .gitignore ├── Cargo.toml ├── README.md └── src │ └── lib.rs └── tt.code-workspace /.commitlintrc.js: -------------------------------------------------------------------------------- 1 | const czConfig = require('./.cz-config'); 2 | 3 | module.exports = { 4 | rules: { 5 | 'body-leading-blank': [2, 'always'], 6 | 'footer-leading-blank': [1, 'always'], 7 | 'header-max-length': [1, 'always', 100], 8 | 'scope-enum': [1, 'always', czConfig.scopes.map((scope) => scope.name)], 9 | 'scope-case': [2, 'always', 'lower-case'], 10 | 'subject-case': [0], 11 | 'subject-empty': [2, 'never'], 12 | 'subject-full-stop': [1, 'never', '.'], 13 | 'type-enum': [2, 'always', czConfig.types.map((type) => type.value)], 14 | 'type-case': [2, 'always', 'lower-case'], 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.cz-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | types: [ 3 | { value: 'feat', name: 'feat: A new feature' }, 4 | { value: 'fix', name: 'fix: A bug fix' }, 5 | { value: 'docs', name: 'docs: Documentation only changes' }, 6 | { value: 'style', name: 'style: Changes that do not affect the meaning of the code\n (white-space, formatting, missing semi-colons, etc)' }, 7 | { value: 'refactor', name: 'refactor: A code change that neither fixes a bug nor adds a feature' }, 8 | { value: 'perf', name: 'perf: A code change that improves performance' }, 9 | { value: 'build', name: 'build: Changes that affect the build system or external dependencies' }, 10 | { value: 'test', name: 'test: Adding missing tests' }, 11 | { value: 'chore', name: 'chore: Changes to the build process or auxiliary tools\n and libraries such as documentation generation' }, 12 | { value: 'revert', name: 'revert: Revert to a commit' }, 13 | { value: 'WIP', name: 'WIP: Work in progress' }, 14 | ], 15 | scopes: [ 16 | { name: 'main' }, 17 | { name: 'parser' }, 18 | { name: 'store' }, 19 | { name: 'builders' }, 20 | { name: 'builders/base' }, 21 | { name: 'builders/rust' }, 22 | { name: 'builders/typescript' }, 23 | { name: 'builders/flow' }, 24 | { name: '@rust' }, 25 | { name: '@js' }, 26 | { name: '@bin' }, 27 | ], 28 | allowCustomScopes: true, 29 | allowBreakingChanges: ['feat', 'fix', 'revert'], 30 | } 31 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | flow-typed 2 | .vscode 3 | javascript 4 | node_modules 5 | rust 6 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: "@atomix/eslint-config", 3 | rules: { 4 | "class-methods-use-this": "off", 5 | "import/no-extraneous-dependencies": ["error", { 6 | "devDependencies": true 7 | }], 8 | "spaced-comment": ["off", "always", { "block": { "balanced": true, "exceptions": [":"] } }], 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | .*/node_modules/.* 3 | .*/vscode/.* 4 | .*/javascript/.* 5 | .*/rust/.* 6 | ./.commitlintrc.js 7 | 8 | [include] 9 | ./lib 10 | ./bin/telegram-typings 11 | 12 | [libs] 13 | ./flow 14 | ./flow-typed 15 | 16 | [lints] 17 | 18 | [options] 19 | all=true 20 | traces=3 21 | emoji=true 22 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue 23 | suppress_comment=\\(.\\|\n\\)*\\$FlowDisable 24 | 25 | [strict] 26 | 27 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' (sandbox) 13 | 2. Open devtools/console 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Screenshots** 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | **Desktop (please complete the following information):** 24 | - OS: [e.g. iOS] 25 | - Browser [e.g. chrome, safari] 26 | - Typescript or Flow version 27 | - Telegram-typings version [e.g. 22] 28 | 29 | **Additional context** 30 | Add any other context about the problem here. 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/node,windows,macos,linux 3 | 4 | ### Linux ### 5 | *~ 6 | 7 | # temporary files which can be created if a process still has a handle open of a deleted file 8 | .fuse_hidden* 9 | 10 | # KDE directory preferences 11 | .directory 12 | 13 | # Linux trash folder which might appear on any partition or disk 14 | .Trash-* 15 | 16 | # .nfs files are created when an open file is removed but is still being accessed 17 | .nfs* 18 | 19 | ### macOS ### 20 | *.DS_Store 21 | .AppleDouble 22 | .LSOverride 23 | 24 | # Icon must end with two \r 25 | Icon 26 | 27 | # Thumbnails 28 | ._* 29 | 30 | # Files that might appear in the root of a volume 31 | .DocumentRevisions-V100 32 | .fseventsd 33 | .Spotlight-V100 34 | .TemporaryItems 35 | .Trashes 36 | .VolumeIcon.icns 37 | .com.apple.timemachine.donotpresent 38 | 39 | # Directories potentially created on remote AFP share 40 | .AppleDB 41 | .AppleDesktop 42 | Network Trash Folder 43 | Temporary Items 44 | .apdisk 45 | 46 | ### Node ### 47 | # Logs 48 | logs 49 | *.log 50 | npm-debug.log* 51 | yarn-debug.log* 52 | yarn-error.log* 53 | 54 | # Runtime data 55 | pids 56 | *.pid 57 | *.seed 58 | *.pid.lock 59 | 60 | # Directory for instrumented libs generated by jscoverage/JSCover 61 | lib-cov 62 | 63 | # Coverage directory used by tools like istanbul 64 | coverage 65 | 66 | # nyc test coverage 67 | .nyc_output 68 | 69 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 70 | .grunt 71 | 72 | # Bower dependency directory (https://bower.io/) 73 | bower_components 74 | 75 | # node-waf configuration 76 | .lock-wscript 77 | 78 | # Compiled binary addons (http://nodejs.org/api/addons.html) 79 | build/Release 80 | 81 | # Dependency directories 82 | node_modules/ 83 | jspm_packages/ 84 | 85 | # Typescript v1 declaration files 86 | typings/ 87 | 88 | # Optional npm cache directory 89 | .npm 90 | 91 | # Optional eslint cache 92 | .eslintcache 93 | 94 | # Optional REPL history 95 | .node_repl_history 96 | 97 | # Output of 'npm pack' 98 | *.tgz 99 | 100 | # Yarn Integrity file 101 | .yarn-integrity 102 | 103 | # dotenv environment variables file 104 | .env 105 | 106 | 107 | ### Windows ### 108 | # Windows thumbnail cache files 109 | Thumbs.db 110 | ehthumbs.db 111 | ehthumbs_vista.db 112 | 113 | # Folder config file 114 | Desktop.ini 115 | 116 | # Recycle Bin used on file shares 117 | $RECYCLE.BIN/ 118 | 119 | # Windows Installer files 120 | *.cab 121 | *.msi 122 | *.msm 123 | *.msp 124 | 125 | # Windows shortcuts 126 | *.lnk 127 | 128 | # End of https://www.gitignore.io/api/node,windows,macos,linux 129 | 130 | # Created by https://www.gitignore.io/api/rust 131 | 132 | ### Rust ### 133 | # Generated by Cargo 134 | # will have compiled files and executables 135 | /target/ 136 | 137 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 138 | # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock 139 | Cargo.lock 140 | 141 | # These are backup files generated by rustfmt 142 | **/*.rs.bk 143 | 144 | # End of https://www.gitignore.io/api/rust 145 | 146 | # Ignore personal .vscode configuration 147 | .vscode 148 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | 2 | language: node_js 3 | 4 | node_js: 5 | - 8 6 | 7 | sudo: false 8 | 9 | script: 10 | - npm test 11 | - npm run build 12 | 13 | # after_success: 14 | # - npm run coverage 15 | # - npm run report 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Telegram Bot API typings for Flow, TypeScript and Rust 2 | 3 | ![Travis (.org)](https://img.shields.io/travis/sergeysova/telegram-typings.svg?style=for-the-badge) ![npm](https://img.shields.io/npm/dt/telegram-typings.svg?style=for-the-badge) ![NPM](https://img.shields.io/npm/l/telegram-typings.svg?style=for-the-badge) ![npm](https://img.shields.io/npm/v/telegram-typings.svg?style=for-the-badge) 4 | 5 | This repository contains [Telegram Bot API](https://core.telegram.org/bots/api) typings for [Flow](https://flow.org/), [TypeScript](https://www.typescriptlang.org/) and [Rust](https://www.rust-lang.org/). 6 | 7 | The types are automatically generated for all supported languages from the Telegram Bot API website. 8 | 9 | ## Flow and TypeScript typings 10 | 11 | See [javascript/](javascript/) folder. 12 | 13 | ## Rust typings 14 | 15 | See [rust](rust/) folder. 16 | 17 | ## Contributing 18 | 19 | Source code for the type generation lives under [lib/](lib/) folder. 20 | 21 | ### Setting up local development environment 22 | 23 | To contribute to this project, you will need to have the following tools installed: 24 | 25 | * Rust 26 | * Node v8.x or higher 27 | * npm v5.7.1 or higher 28 | 29 | Once these tools are installed, you can install the required dependencies: 30 | 31 | ``` 32 | npm install 33 | cargo install rustfmt --version 0.9.0 34 | ``` 35 | 36 | ### Generating new typings 37 | 38 | To generate new types, run the following: 39 | 40 | ``` 41 | npm run build 42 | ``` 43 | 44 | If the [Telegram Bot API](https://core.telegram.org/bots/api) documentation has not changed, and you haven't done any changes to code, you should not get any diff. 45 | -------------------------------------------------------------------------------- /bin/telegram-typings: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const run = require('../lib/main') 3 | /* eslint-disable no-console */ 4 | 5 | run() 6 | .then(() => console.log('Build success')) 7 | .catch((error) => { 8 | console.error(error) 9 | process.exit(-1) 10 | }) 11 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | 2 | # [4.0.0-beta](https://github.com/sergeysova/telegram-typings/compare/v3.6.1...v4.0.0-beta) (2018-08-02) 3 | 4 | 5 | ### Bug Fixes 6 | 7 | * Bug in parser, breaking type generation ([ef317f1](https://github.com/sergeysova/telegram-typings/commit/ef317f1)) 8 | * Output correct Rust types by skipping method serialization for now ([c0f87e5](https://github.com/sergeysova/telegram-typings/commit/c0f87e5)) 9 | 10 | 11 | ### Features 12 | 13 | * Add InputFile manually ([c42fa60](https://github.com/sergeysova/telegram-typings/commit/c42fa60)) 14 | * Add missing union types manually ([90b7d82](https://github.com/sergeysova/telegram-typings/commit/90b7d82)) 15 | * Add raw support for parsing union types ([fa7cb8b](https://github.com/sergeysova/telegram-typings/commit/fa7cb8b)) 16 | * Parse methods as interfaces ([edb35b0](https://github.com/sergeysova/telegram-typings/commit/edb35b0)) 17 | * Write method payloads as type aliases for Flowtype ([3b64acf](https://github.com/sergeysova/telegram-typings/commit/3b64acf)) 18 | * Write out methods for Flow using function declaration types ([1fb3520](https://github.com/sergeysova/telegram-typings/commit/1fb3520)) 19 | * **main:** fetch new version ([756092a](https://github.com/sergeysova/telegram-typings/commit/756092a)) 20 | 21 | 22 | 23 | 24 | ## [3.6.1](https://github.com/sergeysova/telegram-typings/compare/v3.6.0...v3.6.1) (2018-05-04) 25 | 26 | 27 | ### Bug Fixes 28 | 29 | * install changelog generation ([e545cd5](https://github.com/sergeysova/telegram-typings/commit/e545cd5)) 30 | 31 | 32 | ### Features 33 | 34 | * **main:** upgrade dependencies ([8a2e40c](https://github.com/sergeysova/telegram-typings/commit/8a2e40c)) 35 | 36 | 37 | 38 | 39 | # [3.6.0](https://github.com/sergeysova/telegram-typings/compare/v0.3.5-4...v3.6.0) (2018-04-18) 40 | 41 | 42 | ### Features 43 | 44 | * rebuild ([4751295](https://github.com/sergeysova/telegram-typings/commit/4751295)) 45 | 46 | 47 | 48 | 49 | ## [0.3.5-4](https://github.com/sergeysova/telegram-typings/compare/v0.3.5-1...v0.3.5-4) (2018-01-26) 50 | 51 | 52 | ### Bug Fixes 53 | 54 | * **@rust:** ignore rust from eslint ([d2bd6d0](https://github.com/sergeysova/telegram-typings/commit/d2bd6d0)) 55 | * **builders:** Rust building with enums ([57299d0](https://github.com/sergeysova/telegram-typings/commit/57299d0)) 56 | * **builders/flow:** issues of new version of babel/types ([9fbe7a1](https://github.com/sergeysova/telegram-typings/commit/9fbe7a1)) 57 | * **builders/rust:** add stub for rust-keywords ([af986f7](https://github.com/sergeysova/telegram-typings/commit/af986f7)) 58 | * **builders/rust:** Refactor to fix flow ([4395f5a](https://github.com/sergeysova/telegram-typings/commit/4395f5a)) 59 | * **builders/rust:** Resolve rust keywords ([5e24d8c](https://github.com/sergeysova/telegram-typings/commit/5e24d8c)) 60 | 61 | 62 | ### Features 63 | 64 | * **builder/rust:** Add simple Rust builder ([c53e283](https://github.com/sergeysova/telegram-typings/commit/c53e283)) 65 | * **builders/rust:** Complete rust building ([004da7d](https://github.com/sergeysova/telegram-typings/commit/004da7d)) 66 | * **flow-builder:** Build flow types as declare modules ([c443055](https://github.com/sergeysova/telegram-typings/commit/c443055)) 67 | * **rust:** Bump version to 3.5.1 ([7d0182d](https://github.com/sergeysova/telegram-typings/commit/7d0182d)) 68 | 69 | 70 | 71 | 72 | ## [0.3.5-1](https://github.com/sergeysova/telegram-typings/compare/c42d8d8...v0.3.5-1) (2017-12-27) 73 | 74 | 75 | ### Features 76 | 77 | * Add flow types ([be8293e](https://github.com/sergeysova/telegram-typings/commit/be8293e)) 78 | * Build on travis. Ignore package-lock ([a941277](https://github.com/sergeysova/telegram-typings/commit/a941277)) 79 | * Parse fields ([c42d8d8](https://github.com/sergeysova/telegram-typings/commit/c42d8d8)) 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /flow-typed/npm/@babel/generator_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 24bd8756bfb5781af41decf57a1861bc 2 | // flow-typed version: <>/@babel/generator_v7.0.0-beta.35/flow_v0.61.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@babel/generator' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@babel/generator' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@babel/generator/lib/buffer' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module '@babel/generator/lib/generators/base' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module '@babel/generator/lib/generators/classes' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module '@babel/generator/lib/generators/expressions' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module '@babel/generator/lib/generators/flow' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module '@babel/generator/lib/generators/index' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module '@babel/generator/lib/generators/jsx' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module '@babel/generator/lib/generators/methods' { 54 | declare module.exports: any; 55 | } 56 | 57 | declare module '@babel/generator/lib/generators/modules' { 58 | declare module.exports: any; 59 | } 60 | 61 | declare module '@babel/generator/lib/generators/statements' { 62 | declare module.exports: any; 63 | } 64 | 65 | declare module '@babel/generator/lib/generators/template-literals' { 66 | declare module.exports: any; 67 | } 68 | 69 | declare module '@babel/generator/lib/generators/types' { 70 | declare module.exports: any; 71 | } 72 | 73 | declare module '@babel/generator/lib/generators/typescript' { 74 | declare module.exports: any; 75 | } 76 | 77 | declare module '@babel/generator/lib/index' { 78 | declare module.exports: any; 79 | } 80 | 81 | declare module '@babel/generator/lib/node/index' { 82 | declare module.exports: any; 83 | } 84 | 85 | declare module '@babel/generator/lib/node/parentheses' { 86 | declare module.exports: any; 87 | } 88 | 89 | declare module '@babel/generator/lib/node/whitespace' { 90 | declare module.exports: any; 91 | } 92 | 93 | declare module '@babel/generator/lib/printer' { 94 | declare module.exports: any; 95 | } 96 | 97 | declare module '@babel/generator/lib/source-map' { 98 | declare module.exports: any; 99 | } 100 | 101 | // Filename aliases 102 | declare module '@babel/generator/lib/buffer.js' { 103 | declare module.exports: $Exports<'@babel/generator/lib/buffer'>; 104 | } 105 | declare module '@babel/generator/lib/generators/base.js' { 106 | declare module.exports: $Exports<'@babel/generator/lib/generators/base'>; 107 | } 108 | declare module '@babel/generator/lib/generators/classes.js' { 109 | declare module.exports: $Exports<'@babel/generator/lib/generators/classes'>; 110 | } 111 | declare module '@babel/generator/lib/generators/expressions.js' { 112 | declare module.exports: $Exports<'@babel/generator/lib/generators/expressions'>; 113 | } 114 | declare module '@babel/generator/lib/generators/flow.js' { 115 | declare module.exports: $Exports<'@babel/generator/lib/generators/flow'>; 116 | } 117 | declare module '@babel/generator/lib/generators/index.js' { 118 | declare module.exports: $Exports<'@babel/generator/lib/generators/index'>; 119 | } 120 | declare module '@babel/generator/lib/generators/jsx.js' { 121 | declare module.exports: $Exports<'@babel/generator/lib/generators/jsx'>; 122 | } 123 | declare module '@babel/generator/lib/generators/methods.js' { 124 | declare module.exports: $Exports<'@babel/generator/lib/generators/methods'>; 125 | } 126 | declare module '@babel/generator/lib/generators/modules.js' { 127 | declare module.exports: $Exports<'@babel/generator/lib/generators/modules'>; 128 | } 129 | declare module '@babel/generator/lib/generators/statements.js' { 130 | declare module.exports: $Exports<'@babel/generator/lib/generators/statements'>; 131 | } 132 | declare module '@babel/generator/lib/generators/template-literals.js' { 133 | declare module.exports: $Exports<'@babel/generator/lib/generators/template-literals'>; 134 | } 135 | declare module '@babel/generator/lib/generators/types.js' { 136 | declare module.exports: $Exports<'@babel/generator/lib/generators/types'>; 137 | } 138 | declare module '@babel/generator/lib/generators/typescript.js' { 139 | declare module.exports: $Exports<'@babel/generator/lib/generators/typescript'>; 140 | } 141 | declare module '@babel/generator/lib/index.js' { 142 | declare module.exports: $Exports<'@babel/generator/lib/index'>; 143 | } 144 | declare module '@babel/generator/lib/node/index.js' { 145 | declare module.exports: $Exports<'@babel/generator/lib/node/index'>; 146 | } 147 | declare module '@babel/generator/lib/node/parentheses.js' { 148 | declare module.exports: $Exports<'@babel/generator/lib/node/parentheses'>; 149 | } 150 | declare module '@babel/generator/lib/node/whitespace.js' { 151 | declare module.exports: $Exports<'@babel/generator/lib/node/whitespace'>; 152 | } 153 | declare module '@babel/generator/lib/printer.js' { 154 | declare module.exports: $Exports<'@babel/generator/lib/printer'>; 155 | } 156 | declare module '@babel/generator/lib/source-map.js' { 157 | declare module.exports: $Exports<'@babel/generator/lib/source-map'>; 158 | } 159 | -------------------------------------------------------------------------------- /flow-typed/npm/@babel/types_v7.0.x.js: -------------------------------------------------------------------------------- 1 | // import { numberTypeAnnotation } from "@babel/types/lib/builders/generated"; 2 | 3 | // flow-typed signature: 29daf43d438bce142dd0df073cf3d87d 4 | // flow-typed version: <>/@babel/types_v7.0.0-beta.35/flow_v0.61.0 5 | 6 | /** 7 | * This is an autogenerated libdef stub for: 8 | * 9 | * '@babel/types' 10 | * 11 | * Fill this stub out by replacing all the `any` types. 12 | * 13 | * Once filled out, we encourage you to share your work with the 14 | * community by sending a pull request to: 15 | * https://github.com/flowtype/flow-typed 16 | */ 17 | 18 | declare module '@babel/types' { 19 | declare module.exports: any; 20 | } 21 | -------------------------------------------------------------------------------- /flow-typed/npm/cheerio_v1.0.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 5c7248937eba250b209acc675dabd4ac 2 | // flow-typed version: <>/cheerio_v1.0.0-rc.2/flow_v0.61.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'cheerio' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | type $Spread = /* ::{ 17 | ...$Exact, 18 | ...$Exact, 19 | } 20 | type noop1 = */ A & B 21 | 22 | declare module 'cheerio' { 23 | declare type Cheerio = {| 24 | [index: number]: CheerioElement, 25 | length: number, 26 | 27 | attr: (name: string) => string, 28 | 29 | data(name?: string, value?: any): any, 30 | 31 | val(value?: string): Cheerio, 32 | removeAttr(name: string): Cheerio, 33 | has(selector: string | CheerioElement): Cheerio, 34 | 35 | hasClass(className: string): boolean, 36 | addClass(classNames: string): Cheerio, 37 | 38 | removeClass(className?: string | (index: number, className: string) => string): Cheerio, 39 | 40 | toggleClass(className: string, toggleSwitch?: boolean): Cheerio, 41 | toggleClass(toggleSwitch?: boolean): Cheerio, 42 | toggleClass(func: (index: number, className: string, toggleSwitch: boolean) => string, toggleSwitch?: boolean): Cheerio, 43 | 44 | is(selector: string | CheerioElement | CheerioElement[] | Cheerio | (index: number, element: CheerioElement) => boolean): boolean, 45 | 46 | // Form 47 | serialize(): string, 48 | serializeArray(): { name: string, value: string }[], 49 | 50 | // Traversing 51 | 52 | find(selector: string | Cheerio): Cheerio, 53 | 54 | parent(selector?: string): Cheerio, 55 | parents(selector?: string): Cheerio, 56 | parentsUntil(selector?: string | CheerioElement | Cheerio, filter?: string): Cheerio, 57 | 58 | prop(name: string): any, 59 | prop(name: string, value: any): Cheerio, 60 | 61 | closest(): Cheerio, 62 | closest(selector: string): Cheerio, 63 | 64 | next(selector?: string): Cheerio, 65 | nextAll(selector?: string): Cheerio, 66 | 67 | nextUntil(selector?: string | CheerioElement | Cheerio, filter?: string): Cheerio, 68 | 69 | prev(selector?: string): Cheerio, 70 | prevAll(selector?: string): Cheerio, 71 | prevUntil(selector?: string | CheerioElement | Cheerio, filter?: string): Cheerio, 72 | slice(start: number, end?: number): Cheerio, 73 | siblings(selector?: string): Cheerio, 74 | 75 | children(selector?: string): Cheerio, 76 | contents(): Cheerio, 77 | 78 | each(func: (index: number, element: CheerioElement) => any): Cheerio, 79 | map(func: (index: number, element: CheerioElement) => any): Cheerio, 80 | 81 | filter(selector: string | Cheerio | CheerioElement | CheerioElement[]): Cheerio, 82 | filter(func: (index: number, element: CheerioElement) => boolean): Cheerio, 83 | 84 | not(selector: string | Cheerio | CheerioElement): Cheerio, 85 | not(func: (index: number, element: CheerioElement) => boolean): Cheerio, 86 | 87 | first(): Cheerio, 88 | last(): Cheerio, 89 | 90 | eq(index: number): Cheerio, 91 | get(index?: number): string[] | CheerioElement | CheerioElement[], 92 | index(selector?: string | Cheerio): number, 93 | end(): Cheerio, 94 | add(selectorOrHtml: string | CheerioElement | CheerioElement[] | Cheerio, context?: Document): Cheerio, 95 | addBack(filter?: string): Cheerio, 96 | 97 | // Manipulation 98 | appendTo(target: Cheerio): Cheerio, 99 | prependTo(target: Cheerio): Cheerio, 100 | append(content: string | Document | Document [] | Cheerio, ...contents: any[]): Cheerio, 101 | prepend(content: string | Document | Document[] | Cheerio, ...contents: any[]): Cheerio, 102 | after(content: string | Document | Document[] | Cheerio, ...contents: any[]): Cheerio, 103 | 104 | insertAfter(content: string | Document | Cheerio): Cheerio, 105 | before(content: string | Document | Document[] | Cheerio, ...contents: any[]): Cheerio, 106 | insertBefore(content: string | Document | Cheerio): Cheerio, 107 | remove(selector?: string): Cheerio, 108 | replaceWith(content: string | CheerioElement | CheerioElement[] | Cheerio | () => Cheerio): Cheerio, 109 | 110 | empty(): Cheerio, 111 | 112 | 113 | html: () => string | (html: string) => Cheerio, 114 | text: () => string | (text: string) => Cheerio, 115 | 116 | // See https://github.com/cheeriojs/cheerio/issues/731 117 | /*wrap(content: string): Cheerio, 118 | wrap(content: Document): Cheerio, 119 | wrap(content: Cheerio): Cheerio,*/ 120 | 121 | css(propertyName: string): string, 122 | css(propertyNames: string[]): string[], 123 | css(propertyName: string, value: string): Cheerio, 124 | css(propertyName: string, value: number): Cheerio, 125 | css(propertyName: string, func: (index: number, value: string) => string): Cheerio, 126 | css(propertyName: string, func: (index: number, value: string) => number): Cheerio, 127 | css(properties: Object): Cheerio, 128 | 129 | // Rendering 130 | 131 | // Miscellaneous 132 | 133 | clone(): Cheerio, 134 | 135 | // Not Documented 136 | 137 | toArray(): CheerioElement[], 138 | |} 139 | 140 | declare type CheerioElement = {| 141 | // Document References 142 | // Node Console 143 | tagName: string, 144 | type: string, 145 | name: string, 146 | attribs: { [attr: string]: string }, 147 | children: CheerioElement[], 148 | childNodes: CheerioElement[], 149 | lastChild: CheerioElement, 150 | firstChild: CheerioElement, 151 | next: CheerioElement, 152 | nextSibling: CheerioElement, 153 | prev: CheerioElement, 154 | previousSibling: CheerioElement, 155 | parent: CheerioElement, 156 | parentNode: CheerioElement, 157 | nodeValue: string, 158 | data?: string, 159 | |} 160 | 161 | declare type CheerioOptionsInterface = {| 162 | // Document References 163 | // Cheerio https://github.com/cheeriojs/cheerio 164 | // HTMLParser2 https://github.com/fb55/htmlparser2/wiki/Parser-options 165 | // DomHandler https://github.com/fb55/DomHandler 166 | 167 | xmlMode?: boolean, 168 | decodeEntities?: boolean, 169 | lowerCaseTags?: boolean, 170 | lowerCaseAttributeNames?: boolean, 171 | recognizeCDATA?: boolean, 172 | recognizeSelfClosing?: boolean, 173 | normalizeWhitespace?: boolean, 174 | |} 175 | 176 | declare type CheerioSelector = 177 | | (selector: string | Cheerio | CheerioElement) => Cheerio 178 | | (selector: string | Cheerio | CheerioElement, context: string | CheerioElement | CheerioElement[] | Cheerio, root: string) => Cheerio 179 | 180 | 181 | declare type CheerioStatic = {| 182 | (selector: string | Cheerio | CheerioElement): Cheerio, 183 | // Document References 184 | // Cheerio https://github.com/cheeriojs/cheerio 185 | // JQuery http://api.jquery.com 186 | xml(): string, 187 | root(): Cheerio, 188 | contains(container: CheerioElement, contained: CheerioElement): boolean, 189 | parseHTML(data: string, context?: Document, keepScripts?: boolean): Document[], 190 | 191 | html(options?: CheerioOptionsInterface): string, 192 | html(selector: string | Cheerio | CheerioElement, options?: CheerioOptionsInterface): string, 193 | |} 194 | 195 | declare type CheerioAPI = $Spread 199 | 200 | declare module.exports: CheerioAPI; 201 | } 202 | -------------------------------------------------------------------------------- /flow-typed/npm/debug_v3.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: da5374f88debab76c20fc67be7295ba7 2 | // flow-typed version: da30fe6876/debug_v3.x.x/flow_>=v0.28.x 3 | 4 | declare module "debug" { 5 | declare type Debugger = { 6 | (...args: Array): void, 7 | (formatter: string, ...args: Array): void, 8 | (err: Error, ...args: Array): void, 9 | enabled: boolean, 10 | log: () => {}, 11 | namespace: string 12 | }; 13 | 14 | declare module.exports: (namespace: string) => Debugger; 15 | 16 | declare var names: Array; 17 | declare var skips: Array; 18 | declare var colors: Array; 19 | 20 | declare function disable(): void; 21 | declare function enable(namespaces: string): void; 22 | declare function enabled(name: string): boolean; 23 | declare function humanize(): void; 24 | declare function useColors(): boolean; 25 | declare function log(): void; 26 | 27 | declare var formatters: { 28 | [formatter: string]: () => {} 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /flow-typed/npm/node-fetch_v1.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 284e255a331cbe00e3ddf88897c9452d 2 | // flow-typed version: 7e7beb7540/node-fetch_v1.x.x/flow_>=v0.44.x 3 | 4 | declare module 'node-fetch' { 5 | declare export class Request mixins Body { 6 | constructor(input: string | Request, init?: RequestInit): this; 7 | method: string; 8 | url: string; 9 | headers: Headers; 10 | context: RequestContext; 11 | referrer: string; 12 | redirect: RequestRedirect; 13 | 14 | // node-fetch extensions 15 | compress: boolean; 16 | agent: http$Agent; 17 | counter: number; 18 | follow: number; 19 | hostname: string; 20 | protocol: string; 21 | port: number; 22 | timeout: number; 23 | size: number 24 | } 25 | 26 | declare type HeaderObject = { 27 | [index: string]: string 28 | } 29 | 30 | declare interface RequestInit { 31 | method?: string, 32 | headers?: HeaderObject, 33 | body?: BodyInit, 34 | redirect?: RequestRedirect, 35 | 36 | // node-fetch extensions 37 | timeout?: number, 38 | compress?: boolean, 39 | size?: number, 40 | agent?: http$Agent, 41 | follow?: number 42 | } 43 | 44 | declare type RequestContext = 45 | 'audio' | 'beacon' | 'cspreport' | 'download' | 'embed' | 46 | 'eventsource' | 'favicon' | 'fetch' | 'font' | 'form' | 'frame' | 47 | 'hyperlink' | 'iframe' | 'image' | 'imageset' | 'import' | 48 | 'internal' | 'location' | 'manifest' | 'object' | 'ping' | 'plugin' | 49 | 'prefetch' | 'script' | 'serviceworker' | 'sharedworker' | 50 | 'subresource' | 'style' | 'track' | 'video' | 'worker' | 51 | 'xmlhttprequest' | 'xslt'; 52 | declare type RequestRedirect = 'follow' | 'error' | 'manual'; 53 | 54 | declare export class Headers { 55 | append(name: string, value: string): void; 56 | delete(name: string): void; 57 | get(name: string): string; 58 | getAll(name: string): Array; 59 | has(name: string): boolean; 60 | set(name: string, value: string): void; 61 | forEach(callback: (value: string, name: string) => void): void 62 | } 63 | 64 | declare export class Body { 65 | bodyUsed: boolean; 66 | body: stream$Readable; 67 | json(): Promise; 68 | json(): Promise; 69 | text(): Promise; 70 | buffer(): Promise 71 | } 72 | 73 | declare export class Response mixins Body { 74 | constructor(body?: BodyInit, init?: ResponseInit): this; 75 | error(): Response; 76 | redirect(url: string, status: number): Response; 77 | type: ResponseType; 78 | url: string; 79 | status: number; 80 | ok: boolean; 81 | size: number; 82 | statusText: string; 83 | timeout: number; 84 | headers: Headers; 85 | clone(): Response 86 | } 87 | 88 | declare type ResponseType = 89 | | 'basic' 90 | | 'cors' 91 | | 'default' 92 | | 'error' 93 | | 'opaque' 94 | | 'opaqueredirect'; 95 | 96 | declare interface ResponseInit { 97 | status: number, 98 | statusText?: string, 99 | headers?: HeaderInit 100 | } 101 | 102 | declare type HeaderInit = Headers | Array; 103 | declare type BodyInit = string; 104 | 105 | declare export default function fetch(url: string | Request, init?: RequestInit): Promise 106 | } 107 | -------------------------------------------------------------------------------- /flow-typed/npm/rust-keywords_v1.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 1932a49479a06ed0af538391abd190bc 2 | // flow-typed version: <>/rust-keywords_v1.0.1/flow_v0.61.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'rust-keywords' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'rust-keywords' { 17 | declare module.exports: Array; 18 | } 19 | -------------------------------------------------------------------------------- /javascript/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sergeysova/telegram-typings/840f78b12c77e2c935ddf0bf90da173e51cdc5ff/javascript/index.js -------------------------------------------------------------------------------- /javascript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "telegram-typings", 3 | "version": "5.0.0", 4 | "description": "Telegram typings for TypeScript and Flowtype to create bots", 5 | "main": "index.js", 6 | "typings": "telegram-typings.d.ts", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/sergeysova/telegram-typings.git" 10 | }, 11 | "keywords": [ 12 | "telegram", 13 | "bots", 14 | "typings", 15 | "types", 16 | "flow", 17 | "type", 18 | "typescript", 19 | "script", 20 | "build", 21 | "generate" 22 | ], 23 | "author": "Sergey Sova (https://sergeysova.com)", 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/sergeysova/telegram-typings/issues" 27 | }, 28 | "homepage": "https://github.com/sergeysova/telegram-typings#readme", 29 | "dependencies": {} 30 | } 31 | -------------------------------------------------------------------------------- /javascript/readme.md: -------------------------------------------------------------------------------- 1 | # telegram-typings 2 | 3 | Full types parsed from core.telegram.org/bots/api for TypeScript and Flowtype 4 | 5 | ## Installation 6 | 7 | Just install it as your dependency and use 8 | 9 | ```bash 10 | npm install --save telegram-typings 11 | ``` 12 | 13 | ```ts 14 | // typescript 15 | import { User, Chat, Voice } from 'telegram-typings' 16 | ``` 17 | 18 | ### Flow 19 | 20 | ```bash 21 | # Search in flow-typed 22 | flow-typed search telegram-typings 23 | 24 | # if not found, copy content of ./javascript/index.js.flow to your flow-typed 25 | wget https://raw.githubusercontent.com/sergeysova/telegram-typings/master/javascript/index.js.flow -O ./flow-typed/npm/telegram-typings_vx.x.x.js 26 | # next use as normal module 27 | ``` 28 | 29 | ```js 30 | // flow 31 | import type { User, Chat, Voice } from 'telegram-typings' 32 | ``` 33 | -------------------------------------------------------------------------------- /lib/builders/abstract-js.js: -------------------------------------------------------------------------------- 1 | const { BaseBuilder } = require('./base') 2 | /*:: const { Union, Field } = require('../store')*/ 3 | 4 | 5 | class AbstractJsBuilder extends BaseBuilder { 6 | buildFloat() { 7 | return this.buildInteger() 8 | } 9 | 10 | buildCommentBlock(lines/*: string[]*/) { 11 | return [{ 12 | type: 'CommentBlock', 13 | value: `*\n${lines.filter((e) => !!e).map((line) => ` * ${line}`).join('\n')}\n `, 14 | }] 15 | } 16 | 17 | buildCommentSeeLink(link/*: string*/) { 18 | return `@see ${link}` 19 | } 20 | } 21 | 22 | module.exports = { 23 | AbstractJsBuilder, 24 | } 25 | 26 | -------------------------------------------------------------------------------- /lib/builders/base.js: -------------------------------------------------------------------------------- 1 | const { Interface, Method, Union /*::, Store, */ } = require('../store') 2 | 3 | 4 | const ARRAY_OF_LITERAL = 'Array of ' 5 | const INTERSECTION_LITERAL = ' and' 6 | const UNION_LITERAL = ' or' 7 | 8 | /** 9 | * Class for creating base types. 10 | */ 11 | class BaseBuilder { 12 | /* :: store: Store */ 13 | 14 | /** 15 | * Creates a new BaseBuilder instance 16 | * @param {Store} store 17 | */ 18 | constructor(store/*: Store */) { 19 | this.store = store 20 | } 21 | 22 | /** 23 | * Converts an instance of a Type to the babel AST 24 | */ 25 | buildInterface(object/*: Interface*/) { // eslint-disable-line no-unused-vars 26 | throw new TypeError('The `buildInterface` method should be overriden') 27 | } 28 | 29 | /** 30 | * Converts an instance of a Type to the babel AST 31 | */ 32 | buildMethod(object/*: Method*/) { // eslint-disable-line no-unused-vars 33 | throw new TypeError('The `buildMethod` method should be overriden') 34 | } 35 | 36 | /** 37 | * Converts an instance of a Union to the babel AST 38 | */ 39 | buildUnion(object/*: Union*/) { // eslint-disable-line no-unused-vars 40 | throw new TypeError('The `buildUnion` method should be overriden') 41 | } 42 | 43 | /** 44 | * Wraps a type with the AST array node 45 | */ 46 | buildArrayOfType(type/*: string */) { // eslint-disable-line no-unused-vars 47 | throw new TypeError('The `buildArrayOfType` method should be overriden') 48 | } 49 | 50 | /** 51 | * Wraps a type with the AST union node 52 | */ 53 | buildUnionOfTypes(types/*: Array */) { // eslint-disable-line no-unused-vars 54 | throw new TypeError('The `buildUnionOfTypes` method should be overriden') 55 | } 56 | 57 | /** 58 | * Wraps a type with the AST union node 59 | */ 60 | // eslint-disable-next-line no-unused-vars 61 | buildUnionOfTypesFromLiteral(types/*: string */, separator/*: string */) { 62 | throw new TypeError('The `buildUnionOfTypesFromLiteral` method should be overriden') 63 | } 64 | 65 | /** 66 | * Create root ast for file 67 | */ 68 | buildProgram(body/*: mixed*/) { // eslint-disable-line no-unused-vars 69 | throw new TypeError('The `buildProgram` should be overriden') 70 | } 71 | 72 | /** 73 | * Wrap statements to a module 74 | */ 75 | buildModule(interfaces/*: any[]*/) { // eslint-disable-line no-unused-vars 76 | throw new TypeError('The `buildModule` method should be overriden') 77 | } 78 | 79 | /** 80 | * Convert lines of comments to code 81 | */ 82 | buildCommentBlock(lines/*: string[]*/) { // eslint-disable-line no-unused-vars 83 | throw new TypeError('The `buildCommentBlock` method should be overriden') 84 | } 85 | 86 | /** 87 | * Convert link to see comment 88 | */ 89 | buildCommentSeeLink(link/*: string*/) { // eslint-disable-line no-unused-vars 90 | throw new TypeError('The `buildCommentSeeLink` method should be overriden') 91 | } 92 | 93 | /** 94 | * Convert description and links to comment code 95 | */ 96 | buildComments(description/*: string*/ = '', links/*: string[]*/ = []) { 97 | const lines = description.replace(/(.{1,72}\s)\s*?/g, '\n$1').split('\n') 98 | 99 | return this.buildCommentBlock(lines.concat(links.map(this.buildCommentSeeLink))) 100 | } 101 | 102 | /** 103 | * Create source code from store of types 104 | */ 105 | build()/*: { code: string }*/ { 106 | const types = this.iterateOverTypes() 107 | 108 | return this.buildProgram(this.buildModule(types)) 109 | // return generate(bt.program(this.buildModule(types), [], 'module')) 110 | } 111 | 112 | /** 113 | * Convert list of types to list of AST nodes 114 | * Apply only non native types 115 | */ 116 | iterateOverTypes() { 117 | return [...this.store.iterate()] 118 | .filter((object) => !object.native) 119 | .map((object) => { 120 | if (object instanceof Interface) { 121 | return this.buildInterface(object) 122 | } 123 | if (object instanceof Method) { 124 | return this.buildMethod(object) 125 | } 126 | 127 | if (object instanceof Union) { 128 | const type = this.store.get(object.name) || { variants: [] } 129 | 130 | // $FlowDisable 131 | const callbackfn = (name) => !type.variants.includes(name) 132 | const unknown = object.variants.filter(callbackfn) 133 | 134 | if (unknown.length > 0) { 135 | throw new TypeError(`${unknown.join(', ')} not found in the store`) 136 | } 137 | 138 | return this.buildUnion(object) 139 | } 140 | 141 | throw new TypeError('Builder supports only Union and Interface objects') 142 | }) 143 | .filter((ast) => !!ast) 144 | } 145 | 146 | buildFloat() { 147 | return 'number' 148 | } 149 | 150 | buildInteger() { 151 | return 'integer' 152 | } 153 | 154 | buildString() { 155 | return 'string' 156 | } 157 | 158 | buildBoolean() { 159 | return 'boolean' 160 | } 161 | 162 | buildBooleanLiteral(value/*: boolean*/) { 163 | return value ? 'true' : 'false' 164 | } 165 | 166 | buildReference(type/*: any*/)/*: any*/ { 167 | return type 168 | } 169 | 170 | /** 171 | * Create AST node to set into property name 172 | * @param {string} name Name of type in Store. Can be recursive `Array of TYPE` 173 | */ 174 | buildNativeType(name/*: string | Array*/) { 175 | if (Array.isArray(name)) { 176 | return this.buildUnionOfTypes(name) 177 | } 178 | 179 | if (name.indexOf(ARRAY_OF_LITERAL) === 0) { 180 | return this.buildArrayOfType(name) 181 | } 182 | 183 | if (name.includes(INTERSECTION_LITERAL)) { 184 | return this.buildUnionOfTypesFromLiteral(name, INTERSECTION_LITERAL) 185 | } 186 | 187 | if (name.includes(UNION_LITERAL)) { 188 | return this.buildUnionOfTypesFromLiteral(name, UNION_LITERAL) 189 | } 190 | 191 | if (name.includes(',')) { 192 | return this.buildUnionOfTypes(name.split(',').map((s) => s.trim())) 193 | } 194 | 195 | const type = this.store.get(name) 196 | 197 | if (!type) { 198 | throw new TypeError(`${name} not found in store`) 199 | } 200 | 201 | if (type.native) { 202 | switch (type.name.toLowerCase()) { 203 | case 'integer': 204 | return this.buildInteger() 205 | 206 | case 'float': 207 | case 'float number': 208 | return this.buildFloat() 209 | 210 | case 'string': 211 | return this.buildString() 212 | 213 | case 'boolean': 214 | return this.buildBoolean() 215 | 216 | case 'true': 217 | return this.buildBooleanLiteral(true) 218 | 219 | default: 220 | return this.buildReference(type.name) 221 | } 222 | } 223 | 224 | return this.buildReference(type.build()) 225 | } 226 | 227 | static build(store/*: Store */) { 228 | return new this(store).build() 229 | } 230 | } 231 | 232 | /** 233 | * Create CommentBlock AST node 234 | */ 235 | function commentBlock(value/*: string*/) { 236 | return { 237 | type: 'CommentBlock', 238 | value, 239 | } 240 | } 241 | 242 | /** 243 | * Split description to lines add return AST node 244 | */ 245 | function smartComment(description/*:string*/ = '', links/*: string[]*/ = []) { 246 | const descriptionLines = description.replace(/(.{1,72}\s)\s*?/g, '\n * $1') 247 | const linksLines = links.reduce((acc, link) => ( 248 | `${acc} * @see ${link}\n` 249 | ), '') 250 | 251 | return commentBlock(`*${descriptionLines}\n${linksLines} `) 252 | } 253 | 254 | module.exports = { 255 | BaseBuilder, 256 | commentBlock, 257 | smartComment, 258 | ARRAY_OF_LITERAL, 259 | } 260 | -------------------------------------------------------------------------------- /lib/builders/flow.js: -------------------------------------------------------------------------------- 1 | const bt = require('@babel/types') 2 | const { default: generate } = require('@babel/generator') 3 | const { AbstractJsBuilder } = require('./abstract-js') 4 | const { ARRAY_OF_LITERAL } = require('./base') 5 | /*:: const { Union, Interface, Method, Field } = require('../store')*/ 6 | 7 | function methodNameToPayloadName(methodName) { 8 | return `${methodName[0].toUpperCase()}${methodName.slice(1)}Payload` 9 | } 10 | 11 | class FlowBuilder extends AbstractJsBuilder { 12 | buildUnion(object/*: Union*/) { 13 | const variants = object.variants.map((name) => bt.genericTypeAnnotation(bt.identifier(name))) 14 | const ast = bt.declareTypeAlias( 15 | bt.identifier(object.name), 16 | undefined, 17 | bt.unionTypeAnnotation(variants) 18 | ) 19 | 20 | ast.leadingComments = this.buildComments(object.description || '', object.links) 21 | return ast 22 | } 23 | 24 | buildUnionOfTypes(types/*: Array*/) { 25 | return bt.unionTypeAnnotation(types.map((name) => this.buildNativeType(name))) 26 | } 27 | 28 | buildUnionOfTypesFromLiteral(types/*: string*/, separator/*: string*/) { 29 | const reduced = types.split(separator).reduce((r, v) => [...r, v.trim()], []) 30 | 31 | return bt.arrayTypeAnnotation(this.buildNativeType(reduced)) 32 | } 33 | 34 | buildInterface(object/*: Interface*/) { 35 | const fields = Object.keys(object.fields) 36 | .map((fieldName) => this.buildField(object.fields[fieldName])) 37 | const ast = bt.declareTypeAlias( 38 | bt.identifier(object.name), 39 | undefined, 40 | bt.objectTypeAnnotation(fields), 41 | ) 42 | 43 | ast.leadingComments = this.buildComments(object.description || '', object.links) 44 | 45 | return ast 46 | } 47 | 48 | buildMethod(object/*: Method*/) { 49 | const args = Object.keys(object.fields) 50 | .map((fieldName) => this.buildField(object.fields[fieldName])) 51 | 52 | const ast = bt.declareTypeAlias( 53 | bt.identifier(methodNameToPayloadName(object.name)), 54 | undefined, 55 | bt.objectTypeAnnotation(args), 56 | ) 57 | 58 | ast.leadingComments = this.buildComments(object.description || '', object.links) 59 | 60 | return ast 61 | } 62 | 63 | buildField(object/*: Field*/) { 64 | const ast = bt.objectTypeProperty( 65 | bt.identifier(object.name), 66 | this.buildNativeType(object.type) 67 | ) 68 | 69 | ast.optional = object.optional 70 | ast.leadingComments = this.buildComments(object.description || '', object.links) 71 | 72 | return ast 73 | } 74 | 75 | buildArrayOfType(type/*: string*/) { 76 | return bt.arrayTypeAnnotation(this.buildNativeType(type.substr(ARRAY_OF_LITERAL.length))) 77 | } 78 | 79 | buildInteger() { 80 | return bt.numberTypeAnnotation() 81 | } 82 | 83 | buildString() { 84 | return bt.stringTypeAnnotation() 85 | } 86 | 87 | buildBoolean() { 88 | return bt.booleanTypeAnnotation() 89 | } 90 | 91 | buildBooleanLiteral(value/*: boolean*/) { 92 | const ast = bt.booleanLiteralTypeAnnotation(false) 93 | 94 | ast.value = value 95 | 96 | return ast 97 | } 98 | 99 | buildReference(type/*: any*/)/*: any*/ { 100 | return bt.genericTypeAnnotation(bt.identifier(type)) 101 | } 102 | 103 | buildModule(types/*: mixed[]*/)/*: mixed[]*/ { 104 | return [bt.declareModule(bt.stringLiteral('telegram-typings'), bt.blockStatement(types))] 105 | } 106 | 107 | buildProgram(body/*: any*/) { 108 | return generate(bt.program(body, [], 'module')) 109 | } 110 | } 111 | 112 | module.exports = { 113 | FlowBuilder, 114 | } 115 | -------------------------------------------------------------------------------- /lib/builders/rust.js: -------------------------------------------------------------------------------- 1 | const keywords = require('rust-keywords') 2 | const { BaseBuilder, ARRAY_OF_LITERAL } = require('./base') 3 | /*:: const { Union, Interface, Method, Field } = require('../store')*/ 4 | 5 | 6 | // const hasLifetime = (typeName) => !(['i64', 'bool', 'f64'].includes(typeName)) 7 | 8 | class RustBuilder extends BaseBuilder { 9 | buildFloat() { 10 | return 'f64' 11 | } 12 | 13 | buildInteger() { 14 | return 'i64' 15 | } 16 | 17 | buildString() { 18 | return 'String' 19 | } 20 | 21 | buildBoolean() { 22 | return 'bool' 23 | } 24 | 25 | buildBooleanLiteral(value/*: boolean*/) { // eslint-disable-line no-unused-vars 26 | // Rust don't have value types 27 | return 'bool' 28 | } 29 | 30 | buildReference(type/*: any*/)/*: any*/ { 31 | return `Box<${String(type)}>` 32 | } 33 | 34 | buildArrayOfType(type/*: string*/) { 35 | return `Vec<${this.buildNativeType(type.substr(ARRAY_OF_LITERAL.length))}>` 36 | } 37 | 38 | buildInterface(object/*: Interface*/) { 39 | const fields = Object.keys(object.fields) 40 | .map((fieldName) => this.buildField(object.fields[fieldName])) 41 | // Disabled because not used now, but can be used in future 42 | // const hasLifetimeIn = fields.some((def) => def.indexOf('\'a') !== -1) 43 | const lifetime = '' // !hasLifetimeIn ? '<\'a> ' : '' 44 | 45 | return `${this.buildComments(object.description || '', object.links).split('\n').map((e) => e.trim()).join('\n')} 46 | #[derive(Serialize, Deserialize, Debug, Clone)] 47 | pub struct ${object.name}${lifetime} { 48 | ${fields.join('\n\n ')} 49 | }` 50 | } 51 | 52 | // TODO: Implement method serialization for Rust 53 | buildMethod(object/*: Method*/) { // eslint-disable-line no-unused-vars 54 | return '' 55 | } 56 | 57 | buildUnion(object/*: Union*/) { 58 | return `${this.buildComments(object.description || '', object.links).split('\n').map((e) => e.trim()).join('\n')} 59 | #[derive(Serialize, Deserialize, Debug, Clone)] 60 | pub enum ${object.name} { 61 | ${object.variants.map((vari) => `${vari}(Box<${vari}>)`).join(',\n ')} 62 | }` 63 | } 64 | 65 | buildUnionOfTypes(types/*: Array*/) { // eslint-disable-line no-unused-vars 66 | throw new Error('Unions are not yet supported for Rust') 67 | } 68 | 69 | buildField(object/*: Field*/) { 70 | const type = object.optional 71 | ? `Option<${this.buildNativeType(object.type)}>` 72 | : this.buildNativeType(object.type) 73 | const name = keywords.indexOf(object.name) !== -1 74 | ? `${object.name}_tl` 75 | : object.name 76 | const rename = name !== object.name 77 | ? `#[serde(rename = "${object.name}")]` 78 | : '' 79 | const comments = this.buildComments(object.description || '', object.links) 80 | const lifetime = '' // hasLifetime(this.buildNativeType(object.type)) ? '&\'a ' : '' 81 | 82 | return rename 83 | ? `${comments}\n ${rename}\n pub ${name}: ${lifetime}${type},` 84 | : `${comments}\n pub ${name}: ${lifetime}${type},` 85 | } 86 | 87 | buildModule(types/*: string[]*/) { 88 | return types.join('\n\n') 89 | } 90 | 91 | buildProgram(body/*: any*/) { 92 | return { 93 | code: `#[macro_use] 94 | extern crate serde_derive; 95 | extern crate serde; 96 | 97 | ${body} 98 | `, 99 | } 100 | } 101 | 102 | buildCommentBlock(lines/*: string[]*/) { 103 | return lines.filter((e) => !!e) 104 | .map((line) => ` /// ${line}`).join('\n') 105 | } 106 | 107 | buildCommentSeeLink(link/*: string*/) { 108 | return `See ${link}` 109 | } 110 | } 111 | 112 | module.exports = { 113 | RustBuilder, 114 | } 115 | -------------------------------------------------------------------------------- /lib/builders/typescript.js: -------------------------------------------------------------------------------- 1 | const bt = require('@babel/types') 2 | const { default: generate } = require('@babel/generator') 3 | const { AbstractJsBuilder } = require('./abstract-js') 4 | const { ARRAY_OF_LITERAL } = require('./base') 5 | /*:: const { Union, Field, Interface, Method } = require('../store')*/ 6 | 7 | 8 | class TypeScriptBuilder extends AbstractJsBuilder { 9 | buildUnion(object/*: Union */) { 10 | const ast = bt.exportNamedDeclaration( 11 | bt.tSTypeAliasDeclaration( 12 | bt.identifier(object.name), 13 | undefined, 14 | bt.tSUnionType(object.variants.map((name) => ( 15 | bt.tSTypeReference(bt.identifier(name)) 16 | ))) 17 | ), 18 | [], 19 | ) 20 | 21 | ast.leadingComments = this.buildComments(object.description || '', object.links) 22 | 23 | return ast 24 | } 25 | 26 | buildUnionOfTypes(types/*: Array*/) { 27 | // TODO: Build unions with AST builders, not raw strings. 28 | // The architecture between Flow builder and TypeScript builder differs, and we need 29 | // to return a `string` type instead of an AST node from this method 30 | const map = types.map((type) => this.buildNativeType(type)).join(' | ') 31 | 32 | return types.length > 1 ? `(${map})` : map 33 | } 34 | 35 | buildUnionOfTypesFromLiteral(types/*: string*/, separator/*: string*/) { 36 | return this.buildNativeType(types.split(separator).reduce((r, v) => [...r, v.trim()], [])) 37 | } 38 | 39 | buildInterface(object/*: Interface*/) { 40 | const fields = Object.keys(object.fields) 41 | .map((fieldName) => this.buildField(object.fields[fieldName])) 42 | const ast = bt.exportNamedDeclaration( 43 | bt.tsInterfaceDeclaration( 44 | bt.identifier(object.name), 45 | undefined, 46 | null, 47 | bt.tsInterfaceBody(fields), 48 | ), 49 | [] 50 | ) 51 | 52 | ast.leadingComments = this.buildComments(object.description || '', object.links) 53 | 54 | return ast 55 | } 56 | 57 | buildMethod(object /*: Method*/) { 58 | const fields = Object.keys(object.fields) 59 | .map((fieldName) => this.buildField(object.fields[fieldName])) 60 | const ast = bt.exportNamedDeclaration( 61 | bt.tsInterfaceDeclaration( 62 | bt.identifier(object.name), 63 | undefined, 64 | null, 65 | bt.tsInterfaceBody(fields), 66 | ), 67 | [] 68 | ) 69 | 70 | ast.leadingComments = this.buildComments(object.description || '', object.links) 71 | 72 | return ast 73 | } 74 | 75 | buildField(object/*: Field*/) { 76 | const ast = bt.tsPropertySignature( 77 | bt.identifier(object.name), 78 | bt.tsTypeAnnotation(bt.tsTypeReference(bt.identifier(this.buildNativeType(object.type)))) 79 | ) 80 | 81 | ast.optional = object.optional 82 | ast.leadingComments = this.buildComments(object.description || '', object.links) 83 | 84 | return ast 85 | } 86 | 87 | buildArrayOfType(type/*: string*/) { 88 | return `${this.buildNativeType(type.substr(ARRAY_OF_LITERAL.length))}[]` 89 | } 90 | 91 | buildInteger() { 92 | return 'number' 93 | } 94 | 95 | buildString() { 96 | return 'string' 97 | } 98 | 99 | buildModule(types/*: mixed[]*/)/*: mixed[]*/ { 100 | return types 101 | } 102 | 103 | buildProgram(body/*: any*/) { 104 | return generate(bt.program(body, [], 'module')) 105 | } 106 | } 107 | 108 | module.exports = { 109 | TypeScriptBuilder, 110 | } 111 | -------------------------------------------------------------------------------- /lib/main.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const { writeFileSync } = require('fs') 3 | 4 | const { Store, Interface, Union, Field } = require('./store') 5 | const { addNatives } = require('./native') 6 | const { requestAndParse } = require('./parser') 7 | 8 | const { TypeScriptBuilder } = require('./builders/typescript') 9 | const { FlowBuilder } = require('./builders/flow') 10 | const { RustBuilder } = require('./builders/rust') 11 | 12 | 13 | /* eslint-disable no-console */ 14 | const libJavascript = path.resolve(__dirname, '..', 'javascript') 15 | const libRust = path.resolve(__dirname, '..', 'rust', 'src') 16 | 17 | function buildFlow(store/*: Store*/) { 18 | const { code } = FlowBuilder.build(store) 19 | 20 | writeFileSync(path.resolve(libJavascript, 'index.js.flow'), code, { encoding: 'utf8' }) 21 | } 22 | 23 | function buildTypeScript(store/*: Store*/) { 24 | const { code } = TypeScriptBuilder.build(store) 25 | 26 | writeFileSync(path.resolve(libJavascript, 'index.d.ts'), code, { encoding: 'utf8' }) 27 | } 28 | 29 | function buildRust(store/*: Store*/) { 30 | const { code } = RustBuilder.build(store) 31 | 32 | writeFileSync(path.resolve(libRust, 'lib.rs'), code, { encoding: 'utf8' }) 33 | } 34 | 35 | function addBuiltins(store) { 36 | store.add(new Interface('CallbackGame', { 37 | description: 'A placeholder, currently holds no information. Use BotFather to set up your game.', 38 | })) 39 | store.add(new Interface('InputFile', { 40 | description: 'This object represents the contents of a file to be uploaded. ' 41 | + 'Must be posted using multipart/form-data in the usual way that files are uploaded via the browser.', 42 | })) 43 | store.add(new Interface('PassportData', { 44 | description: 'Contains information about Telegram Passport data shared with the bot by the user.', 45 | }, { 46 | data: new Field('data', 'Array of EncryptedPassportElement'), 47 | credentials: new Field('credentials', 'EncryptedCredentials'), 48 | })) 49 | store.add(new Interface('EncryptedPassportElement', { 50 | desciption: 'Contains information about documents or other Telegram Passport elements shared with the bot by the user.', 51 | })) 52 | store.add(new Interface('EncryptedCredentials', { 53 | description: 'Contains data required for decrypting and authenticating EncryptedPassportElement.' 54 | + ' See the Telegram Passport Documentation for a complete description of the data decryption' 55 | + ' and authentication processes.', 56 | })) 57 | store.add(new Interface('VoiceChatStarted', { 58 | description: 'This object represents a service message about a voice chat started in the chat. Currently holds no information.', 59 | })) 60 | // TODO: remove after parse UNIONS 61 | store.add(new Union('InputMessageContent', { 62 | description: 'This object represents the content of a message to be sent as a result of an inline query.', 63 | }, [ 64 | 'InputTextMessageContent', 65 | 'InputLocationMessageContent', 66 | 'InputVenueMessageContent', 67 | 'InputContactMessageContent', 68 | ])) 69 | store.add(new Union('InputMedia', { 70 | description: 'This object represents the content of a media message to be sent.', 71 | }, [ 72 | 'InputMediaPhoto', 73 | 'InputMediaVideo', 74 | 'InputMediaAudio', 75 | 'InputMediaDocument', 76 | 'InputMediaAnimation', 77 | ])) 78 | store.add(new Union('InlineQueryResult', { 79 | description: 'This object represents one result of an inline query', 80 | }, [ 81 | 'InlineQueryResultCachedAudio', 82 | 'InlineQueryResultCachedDocument', 83 | 'InlineQueryResultCachedGif', 84 | 'InlineQueryResultCachedMpeg4Gif', 85 | 'InlineQueryResultCachedPhoto', 86 | 'InlineQueryResultCachedSticker', 87 | 'InlineQueryResultCachedVideo', 88 | 'InlineQueryResultCachedVoice', 89 | 'InlineQueryResultArticle', 90 | 'InlineQueryResultAudio', 91 | 'InlineQueryResultContact', 92 | 'InlineQueryResultGame', 93 | 'InlineQueryResultDocument', 94 | 'InlineQueryResultGif', 95 | 'InlineQueryResultLocation', 96 | 'InlineQueryResultMpeg4Gif', 97 | 'InlineQueryResultPhoto', 98 | 'InlineQueryResultVenue', 99 | 'InlineQueryResultVideo', 100 | 'InlineQueryResultVoice', 101 | ])) 102 | store.add(new Union('PassportElementError', { 103 | description: 'This object represents an error in the Telegram Passport element which was submitted that should be resolved by the user', 104 | }, [ 105 | 'PassportElementErrorDataField', 106 | 'PassportElementErrorFrontSide', 107 | 'PassportElementErrorReverseSide', 108 | 'PassportElementErrorSelfie', 109 | 'PassportElementErrorFile', 110 | 'PassportElementErrorFiles', 111 | 'PassportElementErrorTranslationFile', 112 | 'PassportElementErrorTranslationFiles', 113 | 'PassportElementErrorUnspecified', 114 | ])) 115 | store.add(new Union('ChatMember', { 116 | description: 'This object contains information about one member of a chat. Currently, the following 6 types of chat members are supported:', 117 | }, [ 118 | 'ChatMemberOwner', 119 | 'ChatMemberAdministrator', 120 | 'ChatMemberMember', 121 | 'ChatMemberRestricted', 122 | 'ChatMemberLeft', 123 | 'ChatMemberBanned', 124 | ])) 125 | store.add(new Union('BotCommandScope', { 126 | description: 'This object represents the scope to which bot commands are applied. Currently, the following 7 scopes are supported:', 127 | }, [ 128 | 'BotCommandScopeDefault', 129 | 'BotCommandScopeAllPrivateChats', 130 | 'BotCommandScopeAllGroupChats', 131 | 'BotCommandScopeAllChatAdministrators', 132 | 'BotCommandScopeChat', 133 | 'BotCommandScopeChatAdministrators', 134 | 'BotCommandScopeChatMember', 135 | ])) 136 | } 137 | 138 | async function main() { 139 | const store = new Store() 140 | 141 | addNatives(store) 142 | addBuiltins(store) 143 | 144 | await requestAndParse(store) 145 | 146 | buildFlow(store) 147 | buildTypeScript(store) 148 | // buildRust(store) 149 | } 150 | 151 | module.exports = main 152 | -------------------------------------------------------------------------------- /lib/native.js: -------------------------------------------------------------------------------- 1 | const { Interface/*::, Store*/ } = require('./store') 2 | 3 | 4 | class NativeBoolean extends Interface { 5 | constructor() { 6 | super('Boolean', { native: true }, {}) 7 | } 8 | } 9 | 10 | class NativeTrue extends Interface { 11 | constructor() { 12 | super('True', { native: true }, {}) 13 | } 14 | } 15 | 16 | class NativeInteger extends Interface { 17 | constructor() { 18 | super('Integer', { native: true }, {}) 19 | } 20 | } 21 | 22 | class NativeFloat extends Interface { 23 | constructor() { 24 | super('Float', { native: true }, {}) 25 | } 26 | } 27 | 28 | /** 29 | * @see https://core.telegram.org/bots/api#inlinequeryresultlocation 30 | */ 31 | class NativeFloatNumber extends Interface { 32 | constructor() { 33 | super('Float number', { native: true }, {}) 34 | } 35 | } 36 | 37 | class NativeString extends Interface { 38 | constructor() { 39 | super('String', { native: true }, {}) 40 | } 41 | } 42 | 43 | function addNatives(store/*: Store*/) { 44 | store.add(new NativeBoolean()) 45 | store.add(new NativeTrue()) 46 | store.add(new NativeInteger()) 47 | store.add(new NativeFloat()) 48 | store.add(new NativeFloatNumber()) 49 | store.add(new NativeString()) 50 | } 51 | 52 | module.exports = { 53 | NativeBoolean, 54 | NativeTrue, 55 | NativeInteger, 56 | NativeFloat, 57 | NativeFloatNumber, 58 | NativeString, 59 | 60 | addNatives, 61 | } 62 | -------------------------------------------------------------------------------- /lib/parser.js: -------------------------------------------------------------------------------- 1 | const cheerio = require('cheerio') 2 | /*:: import type { Cheerio, CheerioStatic, CheerioElement } from 'cheerio'*/ 3 | const { default: fetch } = require('node-fetch') 4 | const debug = require('debug')('tt:parser') 5 | 6 | // eslint-disable-next-line no-unused-vars 7 | const { Interface, Method, Field, Store } = require('./store') 8 | 9 | 10 | /* eslint-disable no-console, no-magic-numbers */ 11 | 12 | const API_URL = 'https://core.telegram.org/bots/api' 13 | 14 | /** 15 | * Find previous special typed element in siblings 16 | */ 17 | function findPrev(type/*: string*/, element/*: Cheerio*/) { 18 | let tries = 5 19 | let prev = element 20 | 21 | do { 22 | if (prev.is(type)) { 23 | return prev 24 | } 25 | 26 | prev = prev.prev() 27 | } 28 | while (--tries) 29 | 30 | return prev 31 | } 32 | 33 | /** 34 | * Find next special typed element in siblings 35 | * @param {string} type 36 | * @param {Cheerio} element 37 | */ 38 | function findNext(type, element) { 39 | let tries = 5 40 | let next = element 41 | 42 | do { 43 | if (next.is(type)) { 44 | return next 45 | } 46 | 47 | next = next.next() 48 | } 49 | while (--tries) 50 | 51 | return next 52 | } 53 | 54 | /** 55 | * Convert list with `.each()` and `.length` to classic array 56 | */ 57 | function toArray(target/*: Cheerio*/)/*: Promise*/ { 58 | return new Promise((resolve) => { 59 | const arr/*: Cheerio[]*/ = [] 60 | 61 | target.each((index, element/*: CheerioElement*/) => { 62 | arr.push(cheerio(element)) 63 | 64 | if (target.length - 1 === index) { 65 | resolve(arr) 66 | } 67 | }) 68 | }) 69 | } 70 | 71 | async function parseFields(table) { // eslint-disable-line no-unused-vars 72 | return undefined 73 | } 74 | 75 | /** 76 | * @param {Cheerio} description 77 | * @return {Promise>} 78 | */ 79 | function parseLinks(description/*: Cheerio*/) { 80 | const links = description.find('a').toArray() 81 | .map((element) => cheerio(element).attr('href')) 82 | .map((linkStr) => ( 83 | linkStr.startsWith('http') 84 | ? linkStr 85 | : `https://core.telegram.org/bots/api${linkStr}` 86 | )) 87 | 88 | return [...new Set(links)] 89 | } 90 | 91 | async function handleInterface({ name, description, rows }) { 92 | const fields = {} 93 | 94 | for (const row of rows) { 95 | const [flName, flType, flDescr] = await toArray(row.find('td')) 96 | let fieldDescription 97 | let optional = false 98 | 99 | fieldDescription = flDescr.text().trim() 100 | if (fieldDescription.includes('Optional.')) { 101 | optional = true 102 | fieldDescription = fieldDescription.replace('Optional.', '').trim() 103 | } 104 | const links = parseLinks(flDescr) 105 | 106 | const fieldName = flName.text().trim() 107 | let fieldType = flType.text().trim() 108 | 109 | if (['Field', 'Parameter'].includes(fieldName)) { 110 | continue // eslint-disable-line no-continue 111 | } 112 | 113 | if (fieldType.includes(' or ')) { 114 | fieldType = fieldType.split(' or ') 115 | } 116 | 117 | debug(`${name.text().trim()}.${fieldName}: ${Array.isArray(fieldType) ? fieldType.join(' | ') : fieldType} ::: ${fieldDescription}`) 118 | 119 | const field = new Field( 120 | fieldName, 121 | fieldType, 122 | { 123 | description: fieldDescription, 124 | links, 125 | optional, 126 | } 127 | ) 128 | 129 | fields[field.name] = field 130 | } 131 | 132 | const typeClass = new Interface( 133 | name.text().trim(), 134 | { description: description.text().trim(), links: parseLinks(description) }, 135 | fields 136 | ) 137 | 138 | debug(name.text(), ':::', description.text()) 139 | 140 | return typeClass 141 | } 142 | 143 | 144 | async function handleMethod({ name, description, rows }) { 145 | const fields = {} 146 | 147 | for (const row of rows) { 148 | const [flName, flType, flRequired, flDescr] = await toArray(row.find('td')) 149 | const fieldDescription = flDescr.text().trim() 150 | const optional = flRequired.text().trim() === 'Optional' 151 | 152 | const links = parseLinks(flDescr) 153 | 154 | const fieldName = flName.text().trim() 155 | let fieldType = flType.text().trim() 156 | 157 | // fieldName = fieldName.charAt(0).toUpperCase() + fieldName.slice(1) 158 | 159 | if (['Field', 'Parameter'].includes(fieldName)) { 160 | continue // eslint-disable-line no-continue 161 | } 162 | 163 | if (fieldType.includes(' or ')) { 164 | fieldType = fieldType.split(' or ') 165 | } 166 | 167 | debug(`${name.text().trim()}.${fieldName}: ${Array.isArray(fieldType) ? fieldType.join(' | ') : fieldType} ::: ${fieldDescription}`) 168 | 169 | const field = new Field( 170 | fieldName, 171 | fieldType, 172 | { 173 | description: fieldDescription, 174 | links, 175 | optional, 176 | } 177 | ) 178 | 179 | fields[field.name] = field 180 | } 181 | 182 | const trimmedName = name.text().trim() 183 | const startCasedName = trimmedName.charAt(0).toUpperCase() + trimmedName.slice(1) 184 | 185 | const typeClass = new Method( 186 | startCasedName, 187 | { description: description.text().trim(), links: parseLinks(description) }, 188 | fields 189 | ) 190 | 191 | debug(name.text(), ':::', description.text()) 192 | 193 | return typeClass 194 | } 195 | 196 | /** 197 | * 198 | * @param {Store} store 199 | */ 200 | async function requestAndParse(store/*: Store*/) { 201 | const result = await (await fetch(API_URL)).text() 202 | const body = cheerio.load(result) 203 | const tables/*: Cheerio*/ = body('body').find('table') 204 | 205 | /** @type {Array} */ 206 | const list = await toArray(tables) 207 | 208 | for (const table of list) { 209 | const type = table.find('thead tr:first-child th:first-child').text() 210 | 211 | let typeClass 212 | 213 | if (!['Field', 'Parameter'].includes(type)) { 214 | continue // eslint-disable-line no-continue 215 | } 216 | 217 | const name = findPrev('h4', table) 218 | const description = findNext('p', name) 219 | 220 | if (name.text().includes(' ')) { 221 | console.warn('WRONG NAME:', name.text()) 222 | continue // eslint-disable-line no-continue 223 | } 224 | 225 | const rows = await toArray(table.find('tbody tr')) 226 | 227 | if (type === 'Field') { 228 | typeClass = await handleInterface({ name, description, rows }) 229 | } 230 | else if (type === 'Parameter') { 231 | typeClass = await handleMethod({ name, description, rows }) 232 | } 233 | 234 | if (!typeClass) { 235 | continue // eslint-disable-line no-continue 236 | } 237 | 238 | store.add(typeClass) 239 | } 240 | 241 | return store 242 | } 243 | 244 | module.exports = { 245 | requestAndParse, 246 | } 247 | -------------------------------------------------------------------------------- /lib/store.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable class-methods-use-this */ 2 | 3 | /* :: type Attributes = { 4 | description?: string, 5 | links?: string[], 6 | native?: boolean, 7 | } */ 8 | 9 | /** 10 | * Item save only name, description, links, native flag 11 | */ 12 | class Item { 13 | /*:: name: string*/ 14 | /*:: description: ?string*/ 15 | /*:: links: string[]*/ 16 | /*:: native: boolean*/ 17 | 18 | constructor( 19 | name/*: string*/, 20 | { description, links = [], native = false }/*: Attributes*/ 21 | ) { 22 | this.name = name 23 | this.description = description 24 | this.links = links 25 | this.native = native 26 | } 27 | 28 | build() { 29 | return this.name 30 | } 31 | } 32 | 33 | /*:: type FieldAttributes = { ...Attributes, optional: boolean }*/ 34 | /** 35 | * Field represent field of object/interface 36 | */ 37 | class Field extends Item { 38 | /*:: type: string | Array*/ 39 | /*:: optional: boolean*/ 40 | 41 | constructor( 42 | name/*: string*/, 43 | type/*: string | Array*/, 44 | attributes/*: FieldAttributes*/ = { optional: false } 45 | ) { 46 | super(name, attributes) 47 | 48 | this.type = type 49 | this.optional = attributes.optional 50 | } 51 | } 52 | 53 | /** 54 | * Type is a some type and can be saved in Store 55 | */ 56 | class Type extends Item { } 57 | 58 | /*:: type FieldMap = { [name: string]: Field }*/ 59 | /** 60 | * Type is a interface/type object definition 61 | */ 62 | class Interface extends Type { 63 | /*:: fields: FieldMap*/ 64 | 65 | constructor(name/*: string*/, attributes/*: Attributes*/, fields/*: FieldMap*/ = {}) { 66 | super(name, attributes) 67 | 68 | this.fields = fields 69 | } 70 | } 71 | /** 72 | * Type is a method definition 73 | */ 74 | class Method extends Type { 75 | /*:: fields: FieldMap*/ 76 | 77 | constructor(name/*: string*/, attributes/*: Attributes*/, fields/*: FieldMap*/ = {}) { 78 | super(name, attributes) 79 | 80 | this.fields = fields 81 | } 82 | } 83 | 84 | /** 85 | * Union is a one of types 86 | * @example 87 | * type Foo = A | B | C 88 | */ 89 | class Union extends Type { 90 | /*:: variants: string[]*/ 91 | 92 | constructor(name/*: string*/, attributes/*: Attributes*/, variants/*: string[]*/ = []) { 93 | super(name, attributes) 94 | 95 | this.variants = variants 96 | } 97 | } 98 | 99 | /** 100 | * Store saves Types 101 | */ 102 | class Store { 103 | /*:: types: Map*/ 104 | 105 | constructor() { 106 | this.types = new Map() 107 | } 108 | 109 | add(target/*: Type*/) { 110 | this.types.set(target.name, target) 111 | } 112 | 113 | get(targetName/*: string*/)/*: ?Type*/ { 114 | return this.types.get(targetName) 115 | } 116 | 117 | has(targetName/*: string*/)/*: boolean*/ { 118 | return this.types.has(targetName) 119 | } 120 | 121 | * iterate()/*: Iterable*/ { 122 | yield* this.types.values() 123 | } 124 | 125 | serialize() { 126 | return [...this.types.values()] 127 | .reduce((acc, type) => { 128 | if (type instanceof Interface || type instanceof Method) { 129 | acc.types[type.name] = type 130 | } 131 | else if (type instanceof Union) { 132 | acc.unions[type.name] = type 133 | } 134 | 135 | return acc 136 | }, { types: {}, unions: {} }) 137 | } 138 | } 139 | 140 | module.exports = { 141 | Interface, 142 | Method, 143 | Union, 144 | Field, 145 | Store, 146 | } 147 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Sergey Sova 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. 22 | 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "telegram-typings-generator", 3 | "version": "5.0.0", 4 | "private": true, 5 | "description": "Telegram typings generator", 6 | "main": "index.js", 7 | "typings": "telegram-typings.d.ts", 8 | "scripts": { 9 | "test": "npm run test:lint && npm run test:flow", 10 | "test:flow": "flow status", 11 | "test:lint": "eslint .", 12 | "dev": "DEBUG=tt:* nodemon -w lib -w bin/telegram-typings ./bin/telegram-typings", 13 | "build": "node ./bin/telegram-typings && rustfmt rust/src/lib.rs || true", 14 | "make:changelog": "conventional-changelog -p angular -i changelog.md -r 0 -s && true", 15 | "changelog": "npm test && npm run make:changelog && git add changelog.md && git commit -m 'chore: changelog'", 16 | "publish": "pushd javascript && npm publish && popd", 17 | "postpublish": "pushd rust && cargo publish && popd", 18 | "precommit": "npm run test:lint", 19 | "prepush": "npm test", 20 | "commitmsg": "commitlint -e $GIT_PARAMS" 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/sergeysova/telegram-typings.git" 25 | }, 26 | "keywords": [ 27 | "telegram", 28 | "bots", 29 | "typings", 30 | "types", 31 | "flow", 32 | "type", 33 | "typescript", 34 | "script", 35 | "build", 36 | "generate" 37 | ], 38 | "author": "Sergey Sova (https://lestad.top)", 39 | "license": "MIT", 40 | "bugs": { 41 | "url": "https://github.com/sergeysova/telegram-typings/issues" 42 | }, 43 | "homepage": "https://github.com/sergeysova/telegram-typings#readme", 44 | "dependencies": {}, 45 | "devDependencies": { 46 | "@atomix/eslint-config": "^6.4.0", 47 | "@babel/generator": "^7.0.0-beta.36", 48 | "@babel/types": "^7.0.0-beta.36", 49 | "@commitlint/cli": "^6.2.0", 50 | "cheerio": "^1.0.0-rc.2", 51 | "conventional-changelog-cli": "^1.3.22", 52 | "cz-customizable": "^5.2.0", 53 | "debug": "^3.1.0", 54 | "eslint": "^4.19.1", 55 | "flow-bin": "^0.71.0", 56 | "husky": "^0.14.3", 57 | "node-fetch": "^2.6.1", 58 | "nodemon": "^1.17.3", 59 | "rust-keywords": "^1.0.1" 60 | }, 61 | "config": { 62 | "commitizen": { 63 | "path": "node_modules/cz-customizable" 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /rust/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/rust 3 | 4 | ### Rust ### 5 | # Generated by Cargo 6 | # will have compiled files and executables 7 | /target/ 8 | 9 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 10 | # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock 11 | Cargo.lock 12 | 13 | # These are backup files generated by rustfmt 14 | **/*.rs.bk 15 | 16 | # End of https://www.gitignore.io/api/rust 17 | -------------------------------------------------------------------------------- /rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "telegram-typings" 3 | version = "3.6.1" 4 | authors = ["Sergey Sova "] 5 | license = "MIT" 6 | description = "Structs represents telegram bot typings" 7 | repository = "https://github.com/sergeysova/telegram-typings.git" 8 | documentation = "https://docs.rs/telegram-typings" 9 | categories = ["data-structures"] 10 | 11 | [dependencies] 12 | serde_derive = "1.0.26" 13 | serde = "1.0.26" 14 | -------------------------------------------------------------------------------- /rust/README.md: -------------------------------------------------------------------------------- 1 | # Telegram Typings 2 | [![Crates.io](https://img.shields.io/crates/v/telegram-typings.svg)](https://crates.io/crates/telegram-typings) 3 | [![docs.rs](https://docs.rs/telegram-typings/badge.svg)](https://docs.rs/telegram-typings) 4 | 5 | 6 | 7 | This library has structs to parse Telegram Bot Answer with serde. 8 | 9 | ## Usage 10 | Add this to your `Cargo.toml` 11 | ``` toml 12 | [dependencies] 13 | telegram-typings = "3.5.2" 14 | ``` 15 | 16 | -------------------------------------------------------------------------------- /rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate serde_derive; 3 | extern crate serde; 4 | 5 | /// A placeholder, currently holds no information. Use BotFather to set up 6 | /// your game. 7 | #[derive(Serialize, Deserialize, Debug, Clone)] 8 | pub struct CallbackGame {} 9 | 10 | /// This object represents the contents of a file to be uploaded. Must be 11 | /// posted using multipart/form-data in the usual way that files are 12 | /// uploaded via the browser. 13 | #[derive(Serialize, Deserialize, Debug, Clone)] 14 | pub struct InputFile {} 15 | 16 | /// This object represents the content of a message to be sent as a result 17 | /// of an inline query. 18 | #[derive(Serialize, Deserialize, Debug, Clone)] 19 | pub enum InputMessageContent { 20 | InputTextMessageContent(Box), 21 | InputLocationMessageContent(Box), 22 | InputVenueMessageContent(Box), 23 | InputContactMessageContent(Box), 24 | } 25 | 26 | /// This object represents the content of a media message to be sent. 27 | #[derive(Serialize, Deserialize, Debug, Clone)] 28 | pub enum InputMedia { 29 | InputMediaPhoto(Box), 30 | InputMediaVideo(Box), 31 | } 32 | 33 | /// This object represents one result of an inline query 34 | #[derive(Serialize, Deserialize, Debug, Clone)] 35 | pub enum InlineQueryResult { 36 | InlineQueryResultCachedAudio(Box), 37 | InlineQueryResultCachedDocument(Box), 38 | InlineQueryResultCachedGif(Box), 39 | InlineQueryResultCachedMpeg4Gif(Box), 40 | InlineQueryResultCachedPhoto(Box), 41 | InlineQueryResultCachedSticker(Box), 42 | InlineQueryResultCachedVideo(Box), 43 | InlineQueryResultCachedVoice(Box), 44 | InlineQueryResultArticle(Box), 45 | InlineQueryResultAudio(Box), 46 | InlineQueryResultContact(Box), 47 | InlineQueryResultGame(Box), 48 | InlineQueryResultDocument(Box), 49 | InlineQueryResultGif(Box), 50 | InlineQueryResultLocation(Box), 51 | InlineQueryResultMpeg4Gif(Box), 52 | InlineQueryResultPhoto(Box), 53 | InlineQueryResultVenue(Box), 54 | InlineQueryResultVideo(Box), 55 | InlineQueryResultVoice(Box), 56 | } 57 | 58 | /// This object represents an incoming update.At most one of the optional 59 | /// parameters can be present in any given update. 60 | /// See https://core.telegram.org/bots/api#available-types 61 | #[derive(Serialize, Deserialize, Debug, Clone)] 62 | pub struct Update { 63 | /// The update‘s unique identifier. Update identifiers start from a certain 64 | /// positive number and increase sequentially. This ID becomes especially 65 | /// handy if you’re using Webhooks, since it allows you to ignore repeated 66 | /// updates or to restore the correct update sequence, should they get out 67 | /// of order. If there are no new updates for at least a week, then 68 | /// identifier of the next update will be chosen randomly instead of sequentially. 69 | /// See https://core.telegram.org/bots/api#setwebhook 70 | pub update_id: i64, 71 | 72 | /// New incoming message of any kind — text, photo, sticker, etc. 73 | pub message: Option>, 74 | 75 | /// New version of a message that is known to the bot and was edited 76 | pub edited_message: Option>, 77 | 78 | /// New incoming channel post of any kind — text, photo, sticker, etc. 79 | pub channel_post: Option>, 80 | 81 | /// New version of a channel post that is known to the bot and was edited 82 | pub edited_channel_post: Option>, 83 | 84 | /// New incoming inline query 85 | /// See https://core.telegram.org/bots/api#inline-mode 86 | pub inline_query: Option>, 87 | 88 | /// The result of an inline query that was chosen by a user and sent to 89 | /// their chat partner. Please see our documentation on the feedback 90 | /// collecting for details on how to enable these updates for your bot. 91 | /// See https://core.telegram.org/bots/api#inline-mode 92 | /// See https://core.telegram.org/bots/api/bots/inline#collecting-feedback 93 | pub chosen_inline_result: Option>, 94 | 95 | /// New incoming callback query 96 | pub callback_query: Option>, 97 | 98 | /// New incoming shipping query. Only for invoices with flexible price 99 | pub shipping_query: Option>, 100 | 101 | /// New incoming pre-checkout query. Contains full information about checkout 102 | pub pre_checkout_query: Option>, 103 | } 104 | 105 | /// Contains information about the current status of a webhook. 106 | #[derive(Serialize, Deserialize, Debug, Clone)] 107 | pub struct WebhookInfo { 108 | /// Webhook URL, may be empty if webhook is not set up 109 | pub url: String, 110 | 111 | /// True, if a custom certificate was provided for webhook certificate checks 112 | pub has_custom_certificate: bool, 113 | 114 | /// Number of updates awaiting delivery 115 | pub pending_update_count: i64, 116 | 117 | /// Unix time for the most recent error that happened when trying to deliver 118 | /// an update via webhook 119 | pub last_error_date: Option, 120 | 121 | /// Error message in human-readable format for the most recent error that 122 | /// happened when trying to deliver an update via webhook 123 | pub last_error_message: Option, 124 | 125 | /// Maximum allowed number of simultaneous HTTPS connections to the webhook 126 | /// for update delivery 127 | pub max_connections: Option, 128 | 129 | /// A list of update types the bot is subscribed to. Defaults to all update types 130 | pub allowed_updates: Option>, 131 | } 132 | 133 | /// This object represents a Telegram user or bot. 134 | #[derive(Serialize, Deserialize, Debug, Clone)] 135 | pub struct User { 136 | /// Unique identifier for this user or bot 137 | pub id: i64, 138 | 139 | /// True, if this user is a bot 140 | pub is_bot: bool, 141 | 142 | /// User‘s or bot’s first name 143 | pub first_name: String, 144 | 145 | /// User‘s or bot’s last name 146 | pub last_name: Option, 147 | 148 | /// User‘s or bot’s username 149 | pub username: Option, 150 | 151 | /// IETF language tag of the user's language 152 | /// See https://en.wikipedia.org/wiki/IETF_language_tag 153 | pub language_code: Option, 154 | } 155 | 156 | /// This object represents a chat. 157 | #[derive(Serialize, Deserialize, Debug, Clone)] 158 | pub struct Chat { 159 | /// Unique identifier for this chat. This number may be greater than 32 bits 160 | /// and some programming languages may have difficulty/silent defects in 161 | /// interpreting it. But it is smaller than 52 bits, so a signed 64 bit 162 | /// integer or double-precision float type are safe for storing this identifier. 163 | pub id: i64, 164 | 165 | /// Type of chat, can be either “private”, “group”, “supergroup” or “channel” 166 | #[serde(rename = "type")] 167 | pub type_tl: String, 168 | 169 | /// Title, for supergroups, channels and group chats 170 | pub title: Option, 171 | 172 | /// Username, for private chats, supergroups and channels if available 173 | pub username: Option, 174 | 175 | /// First name of the other party in a private chat 176 | pub first_name: Option, 177 | 178 | /// Last name of the other party in a private chat 179 | pub last_name: Option, 180 | 181 | /// True if a group has ‘All Members Are Admins’ enabled. 182 | pub all_members_are_administrators: Option, 183 | 184 | /// Chat photo. Returned only in getChat. 185 | /// See https://core.telegram.org/bots/api#getchat 186 | pub photo: Option>, 187 | 188 | /// Description, for supergroups and channel chats. Returned only in getChat. 189 | /// See https://core.telegram.org/bots/api#getchat 190 | pub description: Option, 191 | 192 | /// Chat invite link, for supergroups and channel chats. Returned only in getChat. 193 | /// See https://core.telegram.org/bots/api#getchat 194 | pub invite_link: Option, 195 | 196 | /// Pinned message, for supergroups and channel chats. Returned only in getChat. 197 | /// See https://core.telegram.org/bots/api#getchat 198 | pub pinned_message: Option>, 199 | 200 | /// For supergroups, name of group sticker set. Returned only in getChat. 201 | /// See https://core.telegram.org/bots/api#getchat 202 | pub sticker_set_name: Option, 203 | 204 | /// True, if the bot can change the group sticker set. Returned only in getChat. 205 | /// See https://core.telegram.org/bots/api#getchat 206 | pub can_set_sticker_set: Option, 207 | } 208 | 209 | /// This object represents a message. 210 | #[derive(Serialize, Deserialize, Debug, Clone)] 211 | pub struct Message { 212 | /// Unique message identifier inside this chat 213 | pub message_id: i64, 214 | 215 | /// Sender, empty for messages sent to channels 216 | pub from: Option>, 217 | 218 | /// Date the message was sent in Unix time 219 | pub date: i64, 220 | 221 | /// Conversation the message belongs to 222 | pub chat: Box, 223 | 224 | /// For forwarded messages, sender of the original message 225 | pub forward_from: Option>, 226 | 227 | /// For messages forwarded from channels, information about the original channel 228 | pub forward_from_chat: Option>, 229 | 230 | /// For messages forwarded from channels, identifier of the original message 231 | /// in the channel 232 | pub forward_from_message_id: Option, 233 | 234 | /// For messages forwarded from channels, signature of the post author if present 235 | pub forward_signature: Option, 236 | 237 | /// For forwarded messages, date the original message was sent in Unix time 238 | pub forward_date: Option, 239 | 240 | /// For replies, the original message. Note that the Message object in this 241 | /// field will not contain further reply_to_message fields even if it itself 242 | /// is a reply. 243 | pub reply_to_message: Option>, 244 | 245 | /// Date the message was last edited in Unix time 246 | pub edit_date: Option, 247 | 248 | /// The unique identifier of a media message group this message belongs to 249 | pub media_group_id: Option, 250 | 251 | /// Signature of the post author for messages in channels 252 | pub author_signature: Option, 253 | 254 | /// For text messages, the actual UTF-8 text of the message, 0-4096 characters. 255 | pub text: Option, 256 | 257 | /// For text messages, special entities like usernames, URLs, bot commands, 258 | /// etc. that appear in the text 259 | pub entities: Option>>, 260 | 261 | /// For messages with a caption, special entities like usernames, URLs, bot 262 | /// commands, etc. that appear in the caption 263 | pub caption_entities: Option>>, 264 | 265 | /// Message is an audio file, information about the file 266 | pub audio: Option>, 267 | 268 | /// Message is a general file, information about the file 269 | pub document: Option>, 270 | 271 | /// Message is a game, information about the game. More about games » 272 | /// See https://core.telegram.org/bots/api#games 273 | pub game: Option>, 274 | 275 | /// Message is a photo, available sizes of the photo 276 | pub photo: Option>>, 277 | 278 | /// Message is a sticker, information about the sticker 279 | pub sticker: Option>, 280 | 281 | /// Message is a video, information about the video 282 | pub video: Option>, 283 | 284 | /// Message is a voice message, information about the file 285 | pub voice: Option>, 286 | 287 | /// Message is a video note, information about the video message 288 | /// See https://telegram.org/blog/video-messages-and-telescope 289 | pub video_note: Option>, 290 | 291 | /// Caption for the audio, document, photo, video or voice, 0-200 characters 292 | pub caption: Option, 293 | 294 | /// Message is a shared contact, information about the contact 295 | pub contact: Option>, 296 | 297 | /// Message is a shared location, information about the location 298 | pub location: Option>, 299 | 300 | /// Message is a venue, information about the venue 301 | pub venue: Option>, 302 | 303 | /// New members that were added to the group or supergroup and information 304 | /// about them (the bot itself may be one of these members) 305 | pub new_chat_members: Option>>, 306 | 307 | /// A member was removed from the group, information about them (this member 308 | /// may be the bot itself) 309 | pub left_chat_member: Option>, 310 | 311 | /// A chat title was changed to this value 312 | pub new_chat_title: Option, 313 | 314 | /// A chat photo was change to this value 315 | pub new_chat_photo: Option>>, 316 | 317 | /// Service message: the chat photo was deleted 318 | pub delete_chat_photo: Option, 319 | 320 | /// Service message: the group has been created 321 | pub group_chat_created: Option, 322 | 323 | /// Service message: the supergroup has been created. This field can‘t be 324 | /// received in a message coming through updates, because bot can’t be a 325 | /// member of a supergroup when it is created. It can only be found in 326 | /// reply_to_message if someone replies to a very first message in a 327 | /// directly created supergroup. 328 | pub supergroup_chat_created: Option, 329 | 330 | /// Service message: the channel has been created. This field can‘t be 331 | /// received in a message coming through updates, because bot can’t be a 332 | /// member of a channel when it is created. It can only be found in 333 | /// reply_to_message if someone replies to a very first message in a channel. 334 | pub channel_chat_created: Option, 335 | 336 | /// The group has been migrated to a supergroup with the specified 337 | /// identifier. This number may be greater than 32 bits and some programming 338 | /// languages may have difficulty/silent defects in interpreting it. But it 339 | /// is smaller than 52 bits, so a signed 64 bit integer or double-precision 340 | /// float type are safe for storing this identifier. 341 | pub migrate_to_chat_id: Option, 342 | 343 | /// The supergroup has been migrated from a group with the specified 344 | /// identifier. This number may be greater than 32 bits and some programming 345 | /// languages may have difficulty/silent defects in interpreting it. But it 346 | /// is smaller than 52 bits, so a signed 64 bit integer or double-precision 347 | /// float type are safe for storing this identifier. 348 | pub migrate_from_chat_id: Option, 349 | 350 | /// Specified message was pinned. Note that the Message object in this field 351 | /// will not contain further reply_to_message fields even if it is itself a reply. 352 | pub pinned_message: Option>, 353 | 354 | /// Message is an invoice for a payment, information about the invoice. More 355 | /// about payments » 356 | /// See https://core.telegram.org/bots/api#payments 357 | pub invoice: Option>, 358 | 359 | /// Message is a service message about a successful payment, information 360 | /// about the payment. More about payments » 361 | /// See https://core.telegram.org/bots/api#payments 362 | pub successful_payment: Option>, 363 | 364 | /// The domain name of the website on which the user has logged in. More 365 | /// about Telegram Login » 366 | /// See https://core.telegram.org/bots/api/widgets/login 367 | pub connected_website: Option, 368 | } 369 | 370 | /// This object represents one special entity in a text message. For 371 | /// example, hashtags, usernames, URLs, etc. 372 | #[derive(Serialize, Deserialize, Debug, Clone)] 373 | pub struct MessageEntity { 374 | /// Type of the entity. Can be mention (@username), hashtag, bot_command, 375 | /// url, email, bold (bold text), italic (italic text), code (monowidth 376 | /// string), pre (monowidth block), text_link (for clickable text URLs), 377 | /// text_mention (for users without usernames) 378 | /// See https://telegram.org/blog/edit#new-mentions 379 | #[serde(rename = "type")] 380 | pub type_tl: String, 381 | 382 | /// Offset in UTF-16 code units to the start of the entity 383 | pub offset: i64, 384 | 385 | /// Length of the entity in UTF-16 code units 386 | pub length: i64, 387 | 388 | /// For “text_link” only, url that will be opened after user taps on the text 389 | pub url: Option, 390 | 391 | /// For “text_mention” only, the mentioned user 392 | pub user: Option>, 393 | } 394 | 395 | /// This object represents one size of a photo or a file / sticker thumbnail. 396 | /// See https://core.telegram.org/bots/api#document 397 | /// See https://core.telegram.org/bots/api#sticker 398 | #[derive(Serialize, Deserialize, Debug, Clone)] 399 | pub struct PhotoSize { 400 | /// Unique identifier for this file 401 | pub file_id: String, 402 | 403 | /// Photo width 404 | pub width: i64, 405 | 406 | /// Photo height 407 | pub height: i64, 408 | 409 | /// File size 410 | pub file_size: Option, 411 | } 412 | 413 | /// This object represents an audio file to be treated as music by the 414 | /// Telegram clients. 415 | #[derive(Serialize, Deserialize, Debug, Clone)] 416 | pub struct Audio { 417 | /// Unique identifier for this file 418 | pub file_id: String, 419 | 420 | /// Duration of the audio in seconds as defined by sender 421 | pub duration: i64, 422 | 423 | /// Performer of the audio as defined by sender or by audio tags 424 | pub performer: Option, 425 | 426 | /// Title of the audio as defined by sender or by audio tags 427 | pub title: Option, 428 | 429 | /// MIME type of the file as defined by sender 430 | pub mime_type: Option, 431 | 432 | /// File size 433 | pub file_size: Option, 434 | } 435 | 436 | /// This object represents a general file (as opposed to photos, voice 437 | /// messages and audio files). 438 | /// See https://core.telegram.org/bots/api#photosize 439 | /// See https://core.telegram.org/bots/api#voice 440 | /// See https://core.telegram.org/bots/api#audio 441 | #[derive(Serialize, Deserialize, Debug, Clone)] 442 | pub struct Document { 443 | /// Unique file identifier 444 | pub file_id: String, 445 | 446 | /// Document thumbnail as defined by sender 447 | pub thumb: Option>, 448 | 449 | /// Original filename as defined by sender 450 | pub file_name: Option, 451 | 452 | /// MIME type of the file as defined by sender 453 | pub mime_type: Option, 454 | 455 | /// File size 456 | pub file_size: Option, 457 | } 458 | 459 | /// This object represents a video file. 460 | #[derive(Serialize, Deserialize, Debug, Clone)] 461 | pub struct Video { 462 | /// Unique identifier for this file 463 | pub file_id: String, 464 | 465 | /// Video width as defined by sender 466 | pub width: i64, 467 | 468 | /// Video height as defined by sender 469 | pub height: i64, 470 | 471 | /// Duration of the video in seconds as defined by sender 472 | pub duration: i64, 473 | 474 | /// Video thumbnail 475 | pub thumb: Option>, 476 | 477 | /// Mime type of a file as defined by sender 478 | pub mime_type: Option, 479 | 480 | /// File size 481 | pub file_size: Option, 482 | } 483 | 484 | /// This object represents a voice note. 485 | #[derive(Serialize, Deserialize, Debug, Clone)] 486 | pub struct Voice { 487 | /// Unique identifier for this file 488 | pub file_id: String, 489 | 490 | /// Duration of the audio in seconds as defined by sender 491 | pub duration: i64, 492 | 493 | /// MIME type of the file as defined by sender 494 | pub mime_type: Option, 495 | 496 | /// File size 497 | pub file_size: Option, 498 | } 499 | 500 | /// This object represents a video message (available in Telegram apps as of v.4.0). 501 | /// See https://telegram.org/blog/video-messages-and-telescope 502 | #[derive(Serialize, Deserialize, Debug, Clone)] 503 | pub struct VideoNote { 504 | /// Unique identifier for this file 505 | pub file_id: String, 506 | 507 | /// Video width and height as defined by sender 508 | pub length: i64, 509 | 510 | /// Duration of the video in seconds as defined by sender 511 | pub duration: i64, 512 | 513 | /// Video thumbnail 514 | pub thumb: Option>, 515 | 516 | /// File size 517 | pub file_size: Option, 518 | } 519 | 520 | /// This object represents a phone contact. 521 | #[derive(Serialize, Deserialize, Debug, Clone)] 522 | pub struct Contact { 523 | /// Contact's phone number 524 | pub phone_number: String, 525 | 526 | /// Contact's first name 527 | pub first_name: String, 528 | 529 | /// Contact's last name 530 | pub last_name: Option, 531 | 532 | /// Contact's user identifier in Telegram 533 | pub user_id: Option, 534 | } 535 | 536 | /// This object represents a point on the map. 537 | #[derive(Serialize, Deserialize, Debug, Clone)] 538 | pub struct Location { 539 | /// Longitude as defined by sender 540 | pub longitude: f64, 541 | 542 | /// Latitude as defined by sender 543 | pub latitude: f64, 544 | } 545 | 546 | /// This object represents a venue. 547 | #[derive(Serialize, Deserialize, Debug, Clone)] 548 | pub struct Venue { 549 | /// Venue location 550 | pub location: Box, 551 | 552 | /// Name of the venue 553 | pub title: String, 554 | 555 | /// Address of the venue 556 | pub address: String, 557 | 558 | /// Foursquare identifier of the venue 559 | pub foursquare_id: Option, 560 | } 561 | 562 | /// This object represent a user's profile pictures. 563 | #[derive(Serialize, Deserialize, Debug, Clone)] 564 | pub struct UserProfilePhotos { 565 | /// Total number of profile pictures the target user has 566 | pub total_count: i64, 567 | 568 | /// Requested profile pictures (in up to 4 sizes each) 569 | pub photos: Vec>>, 570 | } 571 | 572 | /// This object represents a file ready to be downloaded. The file can be 573 | /// downloaded via the link 574 | /// https://api.telegram.org/file/bot/. It is guaranteed 575 | /// that the link will be valid for at least 1 hour. When the link expires, 576 | /// a new one can be requested by calling getFile. 577 | /// See https://core.telegram.org/bots/api#getfile 578 | #[derive(Serialize, Deserialize, Debug, Clone)] 579 | pub struct File { 580 | /// Unique identifier for this file 581 | pub file_id: String, 582 | 583 | /// File size, if known 584 | pub file_size: Option, 585 | 586 | /// File path. Use https://api.telegram.org/file/bot/ to 587 | /// get the file. 588 | pub file_path: Option, 589 | } 590 | 591 | /// This object represents a custom keyboard with reply options (see 592 | /// Introduction to bots for details and examples). 593 | /// See https://core.telegram.org/bots#keyboards 594 | #[derive(Serialize, Deserialize, Debug, Clone)] 595 | pub struct ReplyKeyboardMarkup { 596 | /// Array of button rows, each represented by an Array of KeyboardButton objects 597 | /// See https://core.telegram.org/bots/api#keyboardbutton 598 | pub keyboard: Vec>>, 599 | 600 | /// Requests clients to resize the keyboard vertically for optimal fit 601 | /// (e.g., make the keyboard smaller if there are just two rows of buttons). 602 | /// Defaults to false, in which case the custom keyboard is always of the 603 | /// same height as the app's standard keyboard. 604 | pub resize_keyboard: Option, 605 | 606 | /// Requests clients to hide the keyboard as soon as it's been used. The 607 | /// keyboard will still be available, but clients will automatically display 608 | /// the usual letter-keyboard in the chat – the user can press a special 609 | /// button in the input field to see the custom keyboard again. Defaults to false. 610 | pub one_time_keyboard: Option, 611 | 612 | /// Use this parameter if you want to show the keyboard to specific users 613 | /// only. Targets: 1) users that are @mentioned in the text of the Message 614 | /// object; 2) if the bot's message is a reply (has reply_to_message_id), 615 | /// sender of the original message.Example: A user requests to change the 616 | /// bot‘s language, bot replies to the request with a keyboard to select the 617 | /// new language. Other users in the group don’t see the keyboard. 618 | /// See https://core.telegram.org/bots/api#message 619 | pub selective: Option, 620 | } 621 | 622 | /// This object represents one button of the reply keyboard. For simple text 623 | /// buttons String can be used instead of this object to specify text of the 624 | /// button. Optional fields are mutually exclusive. 625 | #[derive(Serialize, Deserialize, Debug, Clone)] 626 | pub struct KeyboardButton { 627 | /// Text of the button. If none of the optional fields are used, it will be 628 | /// sent as a message when the button is pressed 629 | pub text: String, 630 | 631 | /// If True, the user's phone number will be sent as a contact when the 632 | /// button is pressed. Available in private chats only 633 | pub request_contact: Option, 634 | 635 | /// If True, the user's current location will be sent when the button is 636 | /// pressed. Available in private chats only 637 | pub request_location: Option, 638 | } 639 | 640 | /// Upon receiving a message with this object, Telegram clients will remove 641 | /// the current custom keyboard and display the default letter-keyboard. By 642 | /// default, custom keyboards are displayed until a new keyboard is sent by 643 | /// a bot. An exception is made for one-time keyboards that are hidden 644 | /// immediately after the user presses a button (see ReplyKeyboardMarkup). 645 | /// See https://core.telegram.org/bots/api#replykeyboardmarkup 646 | #[derive(Serialize, Deserialize, Debug, Clone)] 647 | pub struct ReplyKeyboardRemove { 648 | /// Requests clients to remove the custom keyboard (user will not be able to 649 | /// summon this keyboard; if you want to hide the keyboard from sight but 650 | /// keep it accessible, use one_time_keyboard in ReplyKeyboardMarkup) 651 | /// See https://core.telegram.org/bots/api#replykeyboardmarkup 652 | pub remove_keyboard: bool, 653 | 654 | /// Use this parameter if you want to remove the keyboard for specific users 655 | /// only. Targets: 1) users that are @mentioned in the text of the Message 656 | /// object; 2) if the bot's message is a reply (has reply_to_message_id), 657 | /// sender of the original message.Example: A user votes in a poll, bot 658 | /// returns confirmation message in reply to the vote and removes the 659 | /// keyboard for that user, while still showing the keyboard with poll 660 | /// options to users who haven't voted yet. 661 | /// See https://core.telegram.org/bots/api#message 662 | pub selective: Option, 663 | } 664 | 665 | /// This object represents an inline keyboard that appears right next to the 666 | /// message it belongs to. 667 | /// See https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating 668 | #[derive(Serialize, Deserialize, Debug, Clone)] 669 | pub struct InlineKeyboardMarkup { 670 | /// Array of button rows, each represented by an Array of 671 | /// InlineKeyboardButton objects 672 | /// See https://core.telegram.org/bots/api#inlinekeyboardbutton 673 | pub inline_keyboard: Vec>>, 674 | } 675 | 676 | /// This object represents one button of an inline keyboard. You must use 677 | /// exactly one of the optional fields. 678 | #[derive(Serialize, Deserialize, Debug, Clone)] 679 | pub struct InlineKeyboardButton { 680 | /// Label text on the button 681 | pub text: String, 682 | 683 | /// HTTP url to be opened when button is pressed 684 | pub url: Option, 685 | 686 | /// Data to be sent in a callback query to the bot when button is pressed, 687 | /// 1-64 bytes 688 | /// See https://core.telegram.org/bots/api#callbackquery 689 | pub callback_data: Option, 690 | 691 | /// If set, pressing the button will prompt the user to select one of their 692 | /// chats, open that chat and insert the bot‘s username and the specified 693 | /// inline query in the input field. Can be empty, in which case just the 694 | /// bot’s username will be inserted.Note: This offers an easy way for users 695 | /// to start using your bot in inline mode when they are currently in a 696 | /// private chat with it. Especially useful when combined with switch_pm… 697 | /// actions – in this case the user will be automatically returned to the 698 | /// chat they switched from, skipping the chat selection screen. 699 | /// See https://core.telegram.org/bots/api/bots/inline 700 | /// See https://core.telegram.org/bots/api#answerinlinequery 701 | pub switch_inline_query: Option, 702 | 703 | /// If set, pressing the button will insert the bot‘s username and the 704 | /// specified inline query in the current chat's input field. Can be empty, 705 | /// in which case only the bot’s username will be inserted.This offers a 706 | /// quick way for the user to open your bot in inline mode in the same chat 707 | /// – good for selecting something from multiple options. 708 | pub switch_inline_query_current_chat: Option, 709 | 710 | /// Description of the game that will be launched when the user presses the 711 | /// button.NOTE: This type of button must always be the first button in the 712 | /// first row. 713 | pub callback_game: Option>, 714 | 715 | /// Specify True, to send a Pay button.NOTE: This type of button must always 716 | /// be the first button in the first row. 717 | /// See https://core.telegram.org/bots/api#payments 718 | pub pay: Option, 719 | } 720 | 721 | /// This object represents an incoming callback query from a callback button 722 | /// in an inline keyboard. If the button that originated the query was 723 | /// attached to a message sent by the bot, the field message will be 724 | /// present. If the button was attached to a message sent via the bot (in 725 | /// inline mode), the field inline_message_id will be present. Exactly one 726 | /// of the fields data or game_short_name will be present. 727 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 728 | /// See https://core.telegram.org/bots/api#inline-mode 729 | #[derive(Serialize, Deserialize, Debug, Clone)] 730 | pub struct CallbackQuery { 731 | /// Unique identifier for this query 732 | pub id: String, 733 | 734 | /// Sender 735 | pub from: Box, 736 | 737 | /// Message with the callback button that originated the query. Note that 738 | /// message content and message date will not be available if the message is 739 | /// too old 740 | pub message: Option>, 741 | 742 | /// Identifier of the message sent via the bot in inline mode, that 743 | /// originated the query. 744 | pub inline_message_id: Option, 745 | 746 | /// Global identifier, uniquely corresponding to the chat to which the 747 | /// message with the callback button was sent. Useful for high scores in games. 748 | /// See https://core.telegram.org/bots/api#games 749 | pub chat_instance: String, 750 | 751 | /// Data associated with the callback button. Be aware that a bad client can 752 | /// send arbitrary data in this field. 753 | pub data: Option, 754 | 755 | /// Short name of a Game to be returned, serves as the unique identifier for 756 | /// the game 757 | /// See https://core.telegram.org/bots/api#games 758 | pub game_short_name: Option, 759 | } 760 | 761 | /// Upon receiving a message with this object, Telegram clients will display 762 | /// a reply interface to the user (act as if the user has selected the bot‘s 763 | /// message and tapped ’Reply'). This can be extremely useful if you want to 764 | /// create user-friendly step-by-step interfaces without having to sacrifice 765 | /// privacy mode. 766 | /// See https://core.telegram.org/bots/api/bots#privacy-mode 767 | #[derive(Serialize, Deserialize, Debug, Clone)] 768 | pub struct ForceReply { 769 | /// Shows reply interface to the user, as if they manually selected the 770 | /// bot‘s message and tapped ’Reply' 771 | pub force_reply: bool, 772 | 773 | /// Use this parameter if you want to force reply from specific users only. 774 | /// Targets: 1) users that are @mentioned in the text of the Message object; 775 | /// 2) if the bot's message is a reply (has reply_to_message_id), sender of 776 | /// the original message. 777 | /// See https://core.telegram.org/bots/api#message 778 | pub selective: Option, 779 | } 780 | 781 | /// This object represents a chat photo. 782 | #[derive(Serialize, Deserialize, Debug, Clone)] 783 | pub struct ChatPhoto { 784 | /// Unique file identifier of small (160x160) chat photo. This file_id can 785 | /// be used only for photo download. 786 | pub small_file_id: String, 787 | 788 | /// Unique file identifier of big (640x640) chat photo. This file_id can be 789 | /// used only for photo download. 790 | pub big_file_id: String, 791 | } 792 | 793 | /// This object contains information about one member of a chat. 794 | #[derive(Serialize, Deserialize, Debug, Clone)] 795 | pub struct ChatMember { 796 | /// Information about the user 797 | pub user: Box, 798 | 799 | /// The member's status in the chat. Can be “creator”, “administrator”, 800 | /// “member”, “restricted”, “left” or “kicked” 801 | pub status: String, 802 | 803 | /// Restricted and kicked only. Date when restrictions will be lifted for 804 | /// this user, unix time 805 | pub until_date: Option, 806 | 807 | /// Administrators only. True, if the bot is allowed to edit administrator 808 | /// privileges of that user 809 | pub can_be_edited: Option, 810 | 811 | /// Administrators only. True, if the administrator can change the chat 812 | /// title, photo and other settings 813 | pub can_change_info: Option, 814 | 815 | /// Administrators only. True, if the administrator can post in the channel, 816 | /// channels only 817 | pub can_post_messages: Option, 818 | 819 | /// Administrators only. True, if the administrator can edit messages of 820 | /// other users and can pin messages, channels only 821 | pub can_edit_messages: Option, 822 | 823 | /// Administrators only. True, if the administrator can delete messages of 824 | /// other users 825 | pub can_delete_messages: Option, 826 | 827 | /// Administrators only. True, if the administrator can invite new users to 828 | /// the chat 829 | pub can_invite_users: Option, 830 | 831 | /// Administrators only. True, if the administrator can restrict, ban or 832 | /// unban chat members 833 | pub can_restrict_members: Option, 834 | 835 | /// Administrators only. True, if the administrator can pin messages, 836 | /// supergroups only 837 | pub can_pin_messages: Option, 838 | 839 | /// Administrators only. True, if the administrator can add new 840 | /// administrators with a subset of his own privileges or demote 841 | /// administrators that he has promoted, directly or indirectly (promoted by 842 | /// administrators that were appointed by the user) 843 | pub can_promote_members: Option, 844 | 845 | /// Restricted only. True, if the user can send text messages, contacts, 846 | /// locations and venues 847 | pub can_send_messages: Option, 848 | 849 | /// Restricted only. True, if the user can send audios, documents, photos, 850 | /// videos, video notes and voice notes, implies can_send_messages 851 | pub can_send_media_messages: Option, 852 | 853 | /// Restricted only. True, if the user can send animations, games, stickers 854 | /// and use inline bots, implies can_send_media_messages 855 | pub can_send_other_messages: Option, 856 | 857 | /// Restricted only. True, if user may add web page previews to his 858 | /// messages, implies can_send_media_messages 859 | pub can_add_web_page_previews: Option, 860 | } 861 | 862 | /// Contains information about why a request was unsuccessful. 863 | #[derive(Serialize, Deserialize, Debug, Clone)] 864 | pub struct ResponseParameters { 865 | /// The group has been migrated to a supergroup with the specified 866 | /// identifier. This number may be greater than 32 bits and some programming 867 | /// languages may have difficulty/silent defects in interpreting it. But it 868 | /// is smaller than 52 bits, so a signed 64 bit integer or double-precision 869 | /// float type are safe for storing this identifier. 870 | pub migrate_to_chat_id: Option, 871 | 872 | /// In case of exceeding flood control, the number of seconds left to wait 873 | /// before the request can be repeated 874 | pub retry_after: Option, 875 | } 876 | 877 | /// Represents a photo to be sent. 878 | #[derive(Serialize, Deserialize, Debug, Clone)] 879 | pub struct InputMediaPhoto { 880 | /// Type of the result, must be photo 881 | #[serde(rename = "type")] 882 | pub type_tl: String, 883 | 884 | /// File to send. Pass a file_id to send a file that exists on the Telegram 885 | /// servers (recommended), pass an HTTP URL for Telegram to get a file from 886 | /// the Internet, or pass "attach://" to upload a new one 887 | /// using multipart/form-data under name. More info on 888 | /// Sending Files » 889 | /// See https://core.telegram.org/bots/api#sending-files 890 | pub media: String, 891 | 892 | /// Caption of the photo to be sent, 0-200 characters 893 | pub caption: Option, 894 | 895 | /// Send Markdown or HTML, if you want Telegram apps to show bold, italic, 896 | /// fixed-width text or inline URLs in the media caption. 897 | /// See https://core.telegram.org/bots/api#markdown-style 898 | /// See https://core.telegram.org/bots/api#html-style 899 | /// See https://core.telegram.org/bots/api#formatting-options 900 | pub parse_mode: Option, 901 | } 902 | 903 | /// Represents a video to be sent. 904 | #[derive(Serialize, Deserialize, Debug, Clone)] 905 | pub struct InputMediaVideo { 906 | /// Type of the result, must be video 907 | #[serde(rename = "type")] 908 | pub type_tl: String, 909 | 910 | /// File to send. Pass a file_id to send a file that exists on the Telegram 911 | /// servers (recommended), pass an HTTP URL for Telegram to get a file from 912 | /// the Internet, or pass "attach://" to upload a new one 913 | /// using multipart/form-data under name. More info on 914 | /// Sending Files » 915 | /// See https://core.telegram.org/bots/api#sending-files 916 | pub media: String, 917 | 918 | /// Caption of the video to be sent, 0-200 characters 919 | pub caption: Option, 920 | 921 | /// Send Markdown or HTML, if you want Telegram apps to show bold, italic, 922 | /// fixed-width text or inline URLs in the media caption. 923 | /// See https://core.telegram.org/bots/api#markdown-style 924 | /// See https://core.telegram.org/bots/api#html-style 925 | /// See https://core.telegram.org/bots/api#formatting-options 926 | pub parse_mode: Option, 927 | 928 | /// Video width 929 | pub width: Option, 930 | 931 | /// Video height 932 | pub height: Option, 933 | 934 | /// Video duration 935 | pub duration: Option, 936 | 937 | /// Pass True, if the uploaded video is suitable for streaming 938 | pub supports_streaming: Option, 939 | } 940 | 941 | /// This object represents a sticker. 942 | #[derive(Serialize, Deserialize, Debug, Clone)] 943 | pub struct Sticker { 944 | /// Unique identifier for this file 945 | pub file_id: String, 946 | 947 | /// Sticker width 948 | pub width: i64, 949 | 950 | /// Sticker height 951 | pub height: i64, 952 | 953 | /// Sticker thumbnail in the .webp or .jpg format 954 | pub thumb: Option>, 955 | 956 | /// Emoji associated with the sticker 957 | pub emoji: Option, 958 | 959 | /// Name of the sticker set to which the sticker belongs 960 | pub set_name: Option, 961 | 962 | /// For mask stickers, the position where the mask should be placed 963 | pub mask_position: Option>, 964 | 965 | /// File size 966 | pub file_size: Option, 967 | } 968 | 969 | /// This object represents a sticker set. 970 | #[derive(Serialize, Deserialize, Debug, Clone)] 971 | pub struct StickerSet { 972 | /// Sticker set name 973 | pub name: String, 974 | 975 | /// Sticker set title 976 | pub title: String, 977 | 978 | /// True, if the sticker set contains masks 979 | pub contains_masks: bool, 980 | 981 | /// List of all set stickers 982 | pub stickers: Vec>, 983 | } 984 | 985 | /// This object describes the position on faces where a mask should be 986 | /// placed by default. 987 | #[derive(Serialize, Deserialize, Debug, Clone)] 988 | pub struct MaskPosition { 989 | /// The part of the face relative to which the mask should be placed. One of 990 | /// “forehead”, “eyes”, “mouth”, or “chin”. 991 | pub point: String, 992 | 993 | /// Shift by X-axis measured in widths of the mask scaled to the face size, 994 | /// from left to right. For example, choosing -1.0 will place mask just to 995 | /// the left of the default mask position. 996 | pub x_shift: f64, 997 | 998 | /// Shift by Y-axis measured in heights of the mask scaled to the face size, 999 | /// from top to bottom. For example, 1.0 will place the mask just below the 1000 | /// default mask position. 1001 | pub y_shift: f64, 1002 | 1003 | /// Mask scaling coefficient. For example, 2.0 means double size. 1004 | pub scale: f64, 1005 | } 1006 | 1007 | /// This object represents an incoming inline query. When the user sends an 1008 | /// empty query, your bot could return some default or trending results. 1009 | #[derive(Serialize, Deserialize, Debug, Clone)] 1010 | pub struct InlineQuery { 1011 | /// Unique identifier for this query 1012 | pub id: String, 1013 | 1014 | /// Sender 1015 | pub from: Box, 1016 | 1017 | /// Sender location, only for bots that request user location 1018 | pub location: Option>, 1019 | 1020 | /// Text of the query (up to 512 characters) 1021 | pub query: String, 1022 | 1023 | /// Offset of the results to be returned, can be controlled by the bot 1024 | pub offset: String, 1025 | } 1026 | 1027 | /// Represents a link to an article or web page. 1028 | #[derive(Serialize, Deserialize, Debug, Clone)] 1029 | pub struct InlineQueryResultArticle { 1030 | /// Type of the result, must be article 1031 | #[serde(rename = "type")] 1032 | pub type_tl: String, 1033 | 1034 | /// Unique identifier for this result, 1-64 Bytes 1035 | pub id: String, 1036 | 1037 | /// Title of the result 1038 | pub title: String, 1039 | 1040 | /// Content of the message to be sent 1041 | pub input_message_content: Box, 1042 | 1043 | /// Inline keyboard attached to the message 1044 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1045 | pub reply_markup: Option>, 1046 | 1047 | /// URL of the result 1048 | pub url: Option, 1049 | 1050 | /// Pass True, if you don't want the URL to be shown in the message 1051 | pub hide_url: Option, 1052 | 1053 | /// Short description of the result 1054 | pub description: Option, 1055 | 1056 | /// Url of the thumbnail for the result 1057 | pub thumb_url: Option, 1058 | 1059 | /// Thumbnail width 1060 | pub thumb_width: Option, 1061 | 1062 | /// Thumbnail height 1063 | pub thumb_height: Option, 1064 | } 1065 | 1066 | /// Represents a link to a photo. By default, this photo will be sent by the 1067 | /// user with optional caption. Alternatively, you can use 1068 | /// input_message_content to send a message with the specified content 1069 | /// instead of the photo. 1070 | #[derive(Serialize, Deserialize, Debug, Clone)] 1071 | pub struct InlineQueryResultPhoto { 1072 | /// Type of the result, must be photo 1073 | #[serde(rename = "type")] 1074 | pub type_tl: String, 1075 | 1076 | /// Unique identifier for this result, 1-64 bytes 1077 | pub id: String, 1078 | 1079 | /// A valid URL of the photo. Photo must be in jpeg format. Photo size must 1080 | /// not exceed 5MB 1081 | pub photo_url: String, 1082 | 1083 | /// URL of the thumbnail for the photo 1084 | pub thumb_url: String, 1085 | 1086 | /// Width of the photo 1087 | pub photo_width: Option, 1088 | 1089 | /// Height of the photo 1090 | pub photo_height: Option, 1091 | 1092 | /// Title for the result 1093 | pub title: Option, 1094 | 1095 | /// Short description of the result 1096 | pub description: Option, 1097 | 1098 | /// Caption of the photo to be sent, 0-200 characters 1099 | pub caption: Option, 1100 | 1101 | /// Send Markdown or HTML, if you want Telegram apps to show bold, italic, 1102 | /// fixed-width text or inline URLs in the media caption. 1103 | /// See https://core.telegram.org/bots/api#markdown-style 1104 | /// See https://core.telegram.org/bots/api#html-style 1105 | /// See https://core.telegram.org/bots/api#formatting-options 1106 | pub parse_mode: Option, 1107 | 1108 | /// Inline keyboard attached to the message 1109 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1110 | pub reply_markup: Option>, 1111 | 1112 | /// Content of the message to be sent instead of the photo 1113 | pub input_message_content: Option>, 1114 | } 1115 | 1116 | /// Represents a link to an animated GIF file. By default, this animated GIF 1117 | /// file will be sent by the user with optional caption. Alternatively, you 1118 | /// can use input_message_content to send a message with the specified 1119 | /// content instead of the animation. 1120 | #[derive(Serialize, Deserialize, Debug, Clone)] 1121 | pub struct InlineQueryResultGif { 1122 | /// Type of the result, must be gif 1123 | #[serde(rename = "type")] 1124 | pub type_tl: String, 1125 | 1126 | /// Unique identifier for this result, 1-64 bytes 1127 | pub id: String, 1128 | 1129 | /// A valid URL for the GIF file. File size must not exceed 1MB 1130 | pub gif_url: String, 1131 | 1132 | /// Width of the GIF 1133 | pub gif_width: Option, 1134 | 1135 | /// Height of the GIF 1136 | pub gif_height: Option, 1137 | 1138 | /// Duration of the GIF 1139 | pub gif_duration: Option, 1140 | 1141 | /// URL of the static thumbnail for the result (jpeg or gif) 1142 | pub thumb_url: String, 1143 | 1144 | /// Title for the result 1145 | pub title: Option, 1146 | 1147 | /// Caption of the GIF file to be sent, 0-200 characters 1148 | pub caption: Option, 1149 | 1150 | /// Send Markdown or HTML, if you want Telegram apps to show bold, italic, 1151 | /// fixed-width text or inline URLs in the media caption. 1152 | /// See https://core.telegram.org/bots/api#markdown-style 1153 | /// See https://core.telegram.org/bots/api#html-style 1154 | /// See https://core.telegram.org/bots/api#formatting-options 1155 | pub parse_mode: Option, 1156 | 1157 | /// Inline keyboard attached to the message 1158 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1159 | pub reply_markup: Option>, 1160 | 1161 | /// Content of the message to be sent instead of the GIF animation 1162 | pub input_message_content: Option>, 1163 | } 1164 | 1165 | /// Represents a link to a video animation (H.264/MPEG-4 AVC video without 1166 | /// sound). By default, this animated MPEG-4 file will be sent by the user 1167 | /// with optional caption. Alternatively, you can use input_message_content 1168 | /// to send a message with the specified content instead of the animation. 1169 | #[derive(Serialize, Deserialize, Debug, Clone)] 1170 | pub struct InlineQueryResultMpeg4Gif { 1171 | /// Type of the result, must be mpeg4_gif 1172 | #[serde(rename = "type")] 1173 | pub type_tl: String, 1174 | 1175 | /// Unique identifier for this result, 1-64 bytes 1176 | pub id: String, 1177 | 1178 | /// A valid URL for the MP4 file. File size must not exceed 1MB 1179 | pub mpeg4_url: String, 1180 | 1181 | /// Video width 1182 | pub mpeg4_width: Option, 1183 | 1184 | /// Video height 1185 | pub mpeg4_height: Option, 1186 | 1187 | /// Video duration 1188 | pub mpeg4_duration: Option, 1189 | 1190 | /// URL of the static thumbnail (jpeg or gif) for the result 1191 | pub thumb_url: String, 1192 | 1193 | /// Title for the result 1194 | pub title: Option, 1195 | 1196 | /// Caption of the MPEG-4 file to be sent, 0-200 characters 1197 | pub caption: Option, 1198 | 1199 | /// Send Markdown or HTML, if you want Telegram apps to show bold, italic, 1200 | /// fixed-width text or inline URLs in the media caption. 1201 | /// See https://core.telegram.org/bots/api#markdown-style 1202 | /// See https://core.telegram.org/bots/api#html-style 1203 | /// See https://core.telegram.org/bots/api#formatting-options 1204 | pub parse_mode: Option, 1205 | 1206 | /// Inline keyboard attached to the message 1207 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1208 | pub reply_markup: Option>, 1209 | 1210 | /// Content of the message to be sent instead of the video animation 1211 | pub input_message_content: Option>, 1212 | } 1213 | 1214 | /// Represents a link to a page containing an embedded video player or a 1215 | /// video file. By default, this video file will be sent by the user with an 1216 | /// optional caption. Alternatively, you can use input_message_content to 1217 | /// send a message with the specified content instead of the video. 1218 | #[derive(Serialize, Deserialize, Debug, Clone)] 1219 | pub struct InlineQueryResultVideo { 1220 | /// Type of the result, must be video 1221 | #[serde(rename = "type")] 1222 | pub type_tl: String, 1223 | 1224 | /// Unique identifier for this result, 1-64 bytes 1225 | pub id: String, 1226 | 1227 | /// A valid URL for the embedded video player or video file 1228 | pub video_url: String, 1229 | 1230 | /// Mime type of the content of video url, “text/html” or “video/mp4” 1231 | pub mime_type: String, 1232 | 1233 | /// URL of the thumbnail (jpeg only) for the video 1234 | pub thumb_url: String, 1235 | 1236 | /// Title for the result 1237 | pub title: String, 1238 | 1239 | /// Caption of the video to be sent, 0-200 characters 1240 | pub caption: Option, 1241 | 1242 | /// Send Markdown or HTML, if you want Telegram apps to show bold, italic, 1243 | /// fixed-width text or inline URLs in the media caption. 1244 | /// See https://core.telegram.org/bots/api#markdown-style 1245 | /// See https://core.telegram.org/bots/api#html-style 1246 | /// See https://core.telegram.org/bots/api#formatting-options 1247 | pub parse_mode: Option, 1248 | 1249 | /// Video width 1250 | pub video_width: Option, 1251 | 1252 | /// Video height 1253 | pub video_height: Option, 1254 | 1255 | /// Video duration in seconds 1256 | pub video_duration: Option, 1257 | 1258 | /// Short description of the result 1259 | pub description: Option, 1260 | 1261 | /// Inline keyboard attached to the message 1262 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1263 | pub reply_markup: Option>, 1264 | 1265 | /// Content of the message to be sent instead of the video. This field is 1266 | /// required if InlineQueryResultVideo is used to send an HTML-page as a 1267 | /// result (e.g., a YouTube video). 1268 | pub input_message_content: Option>, 1269 | } 1270 | 1271 | /// Represents a link to an mp3 audio file. By default, this audio file will 1272 | /// be sent by the user. Alternatively, you can use input_message_content to 1273 | /// send a message with the specified content instead of the audio. 1274 | #[derive(Serialize, Deserialize, Debug, Clone)] 1275 | pub struct InlineQueryResultAudio { 1276 | /// Type of the result, must be audio 1277 | #[serde(rename = "type")] 1278 | pub type_tl: String, 1279 | 1280 | /// Unique identifier for this result, 1-64 bytes 1281 | pub id: String, 1282 | 1283 | /// A valid URL for the audio file 1284 | pub audio_url: String, 1285 | 1286 | /// Title 1287 | pub title: String, 1288 | 1289 | /// Caption, 0-200 characters 1290 | pub caption: Option, 1291 | 1292 | /// Send Markdown or HTML, if you want Telegram apps to show bold, italic, 1293 | /// fixed-width text or inline URLs in the media caption. 1294 | /// See https://core.telegram.org/bots/api#markdown-style 1295 | /// See https://core.telegram.org/bots/api#html-style 1296 | /// See https://core.telegram.org/bots/api#formatting-options 1297 | pub parse_mode: Option, 1298 | 1299 | /// Performer 1300 | pub performer: Option, 1301 | 1302 | /// Audio duration in seconds 1303 | pub audio_duration: Option, 1304 | 1305 | /// Inline keyboard attached to the message 1306 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1307 | pub reply_markup: Option>, 1308 | 1309 | /// Content of the message to be sent instead of the audio 1310 | pub input_message_content: Option>, 1311 | } 1312 | 1313 | /// Represents a link to a voice recording in an .ogg container encoded with 1314 | /// OPUS. By default, this voice recording will be sent by the user. 1315 | /// Alternatively, you can use input_message_content to send a message with 1316 | /// the specified content instead of the the voice message. 1317 | #[derive(Serialize, Deserialize, Debug, Clone)] 1318 | pub struct InlineQueryResultVoice { 1319 | /// Type of the result, must be voice 1320 | #[serde(rename = "type")] 1321 | pub type_tl: String, 1322 | 1323 | /// Unique identifier for this result, 1-64 bytes 1324 | pub id: String, 1325 | 1326 | /// A valid URL for the voice recording 1327 | pub voice_url: String, 1328 | 1329 | /// Recording title 1330 | pub title: String, 1331 | 1332 | /// Caption, 0-200 characters 1333 | pub caption: Option, 1334 | 1335 | /// Send Markdown or HTML, if you want Telegram apps to show bold, italic, 1336 | /// fixed-width text or inline URLs in the media caption. 1337 | /// See https://core.telegram.org/bots/api#markdown-style 1338 | /// See https://core.telegram.org/bots/api#html-style 1339 | /// See https://core.telegram.org/bots/api#formatting-options 1340 | pub parse_mode: Option, 1341 | 1342 | /// Recording duration in seconds 1343 | pub voice_duration: Option, 1344 | 1345 | /// Inline keyboard attached to the message 1346 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1347 | pub reply_markup: Option>, 1348 | 1349 | /// Content of the message to be sent instead of the voice recording 1350 | pub input_message_content: Option>, 1351 | } 1352 | 1353 | /// Represents a link to a file. By default, this file will be sent by the 1354 | /// user with an optional caption. Alternatively, you can use 1355 | /// input_message_content to send a message with the specified content 1356 | /// instead of the file. Currently, only .PDF and .ZIP files can be sent 1357 | /// using this method. 1358 | #[derive(Serialize, Deserialize, Debug, Clone)] 1359 | pub struct InlineQueryResultDocument { 1360 | /// Type of the result, must be document 1361 | #[serde(rename = "type")] 1362 | pub type_tl: String, 1363 | 1364 | /// Unique identifier for this result, 1-64 bytes 1365 | pub id: String, 1366 | 1367 | /// Title for the result 1368 | pub title: String, 1369 | 1370 | /// Caption of the document to be sent, 0-200 characters 1371 | pub caption: Option, 1372 | 1373 | /// Send Markdown or HTML, if you want Telegram apps to show bold, italic, 1374 | /// fixed-width text or inline URLs in the media caption. 1375 | /// See https://core.telegram.org/bots/api#markdown-style 1376 | /// See https://core.telegram.org/bots/api#html-style 1377 | /// See https://core.telegram.org/bots/api#formatting-options 1378 | pub parse_mode: Option, 1379 | 1380 | /// A valid URL for the file 1381 | pub document_url: String, 1382 | 1383 | /// Mime type of the content of the file, either “application/pdf” or “application/zip” 1384 | pub mime_type: String, 1385 | 1386 | /// Short description of the result 1387 | pub description: Option, 1388 | 1389 | /// Inline keyboard attached to the message 1390 | pub reply_markup: Option>, 1391 | 1392 | /// Content of the message to be sent instead of the file 1393 | pub input_message_content: Option>, 1394 | 1395 | /// URL of the thumbnail (jpeg only) for the file 1396 | pub thumb_url: Option, 1397 | 1398 | /// Thumbnail width 1399 | pub thumb_width: Option, 1400 | 1401 | /// Thumbnail height 1402 | pub thumb_height: Option, 1403 | } 1404 | 1405 | /// Represents a location on a map. By default, the location will be sent by 1406 | /// the user. Alternatively, you can use input_message_content to send a 1407 | /// message with the specified content instead of the location. 1408 | #[derive(Serialize, Deserialize, Debug, Clone)] 1409 | pub struct InlineQueryResultLocation { 1410 | /// Type of the result, must be location 1411 | #[serde(rename = "type")] 1412 | pub type_tl: String, 1413 | 1414 | /// Unique identifier for this result, 1-64 Bytes 1415 | pub id: String, 1416 | 1417 | /// Location latitude in degrees 1418 | pub latitude: f64, 1419 | 1420 | /// Location longitude in degrees 1421 | pub longitude: f64, 1422 | 1423 | /// Location title 1424 | pub title: String, 1425 | 1426 | /// Period in seconds for which the location can be updated, should be 1427 | /// between 60 and 86400. 1428 | pub live_period: Option, 1429 | 1430 | /// Inline keyboard attached to the message 1431 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1432 | pub reply_markup: Option>, 1433 | 1434 | /// Content of the message to be sent instead of the location 1435 | pub input_message_content: Option>, 1436 | 1437 | /// Url of the thumbnail for the result 1438 | pub thumb_url: Option, 1439 | 1440 | /// Thumbnail width 1441 | pub thumb_width: Option, 1442 | 1443 | /// Thumbnail height 1444 | pub thumb_height: Option, 1445 | } 1446 | 1447 | /// Represents a venue. By default, the venue will be sent by the user. 1448 | /// Alternatively, you can use input_message_content to send a message with 1449 | /// the specified content instead of the venue. 1450 | #[derive(Serialize, Deserialize, Debug, Clone)] 1451 | pub struct InlineQueryResultVenue { 1452 | /// Type of the result, must be venue 1453 | #[serde(rename = "type")] 1454 | pub type_tl: String, 1455 | 1456 | /// Unique identifier for this result, 1-64 Bytes 1457 | pub id: String, 1458 | 1459 | /// Latitude of the venue location in degrees 1460 | pub latitude: f64, 1461 | 1462 | /// Longitude of the venue location in degrees 1463 | pub longitude: f64, 1464 | 1465 | /// Title of the venue 1466 | pub title: String, 1467 | 1468 | /// Address of the venue 1469 | pub address: String, 1470 | 1471 | /// Foursquare identifier of the venue if known 1472 | pub foursquare_id: Option, 1473 | 1474 | /// Inline keyboard attached to the message 1475 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1476 | pub reply_markup: Option>, 1477 | 1478 | /// Content of the message to be sent instead of the venue 1479 | pub input_message_content: Option>, 1480 | 1481 | /// Url of the thumbnail for the result 1482 | pub thumb_url: Option, 1483 | 1484 | /// Thumbnail width 1485 | pub thumb_width: Option, 1486 | 1487 | /// Thumbnail height 1488 | pub thumb_height: Option, 1489 | } 1490 | 1491 | /// Represents a contact with a phone number. By default, this contact will 1492 | /// be sent by the user. Alternatively, you can use input_message_content to 1493 | /// send a message with the specified content instead of the contact. 1494 | #[derive(Serialize, Deserialize, Debug, Clone)] 1495 | pub struct InlineQueryResultContact { 1496 | /// Type of the result, must be contact 1497 | #[serde(rename = "type")] 1498 | pub type_tl: String, 1499 | 1500 | /// Unique identifier for this result, 1-64 Bytes 1501 | pub id: String, 1502 | 1503 | /// Contact's phone number 1504 | pub phone_number: String, 1505 | 1506 | /// Contact's first name 1507 | pub first_name: String, 1508 | 1509 | /// Contact's last name 1510 | pub last_name: Option, 1511 | 1512 | /// Inline keyboard attached to the message 1513 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1514 | pub reply_markup: Option>, 1515 | 1516 | /// Content of the message to be sent instead of the contact 1517 | pub input_message_content: Option>, 1518 | 1519 | /// Url of the thumbnail for the result 1520 | pub thumb_url: Option, 1521 | 1522 | /// Thumbnail width 1523 | pub thumb_width: Option, 1524 | 1525 | /// Thumbnail height 1526 | pub thumb_height: Option, 1527 | } 1528 | 1529 | /// Represents a Game. 1530 | /// See https://core.telegram.org/bots/api#games 1531 | #[derive(Serialize, Deserialize, Debug, Clone)] 1532 | pub struct InlineQueryResultGame { 1533 | /// Type of the result, must be game 1534 | #[serde(rename = "type")] 1535 | pub type_tl: String, 1536 | 1537 | /// Unique identifier for this result, 1-64 bytes 1538 | pub id: String, 1539 | 1540 | /// Short name of the game 1541 | pub game_short_name: String, 1542 | 1543 | /// Inline keyboard attached to the message 1544 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1545 | pub reply_markup: Option>, 1546 | } 1547 | 1548 | /// Represents a link to a photo stored on the Telegram servers. By default, 1549 | /// this photo will be sent by the user with an optional caption. 1550 | /// Alternatively, you can use input_message_content to send a message with 1551 | /// the specified content instead of the photo. 1552 | #[derive(Serialize, Deserialize, Debug, Clone)] 1553 | pub struct InlineQueryResultCachedPhoto { 1554 | /// Type of the result, must be photo 1555 | #[serde(rename = "type")] 1556 | pub type_tl: String, 1557 | 1558 | /// Unique identifier for this result, 1-64 bytes 1559 | pub id: String, 1560 | 1561 | /// A valid file identifier of the photo 1562 | pub photo_file_id: String, 1563 | 1564 | /// Title for the result 1565 | pub title: Option, 1566 | 1567 | /// Short description of the result 1568 | pub description: Option, 1569 | 1570 | /// Caption of the photo to be sent, 0-200 characters 1571 | pub caption: Option, 1572 | 1573 | /// Send Markdown or HTML, if you want Telegram apps to show bold, italic, 1574 | /// fixed-width text or inline URLs in the media caption. 1575 | /// See https://core.telegram.org/bots/api#markdown-style 1576 | /// See https://core.telegram.org/bots/api#html-style 1577 | /// See https://core.telegram.org/bots/api#formatting-options 1578 | pub parse_mode: Option, 1579 | 1580 | /// Inline keyboard attached to the message 1581 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1582 | pub reply_markup: Option>, 1583 | 1584 | /// Content of the message to be sent instead of the photo 1585 | pub input_message_content: Option>, 1586 | } 1587 | 1588 | /// Represents a link to an animated GIF file stored on the Telegram 1589 | /// servers. By default, this animated GIF file will be sent by the user 1590 | /// with an optional caption. Alternatively, you can use 1591 | /// input_message_content to send a message with specified content instead 1592 | /// of the animation. 1593 | #[derive(Serialize, Deserialize, Debug, Clone)] 1594 | pub struct InlineQueryResultCachedGif { 1595 | /// Type of the result, must be gif 1596 | #[serde(rename = "type")] 1597 | pub type_tl: String, 1598 | 1599 | /// Unique identifier for this result, 1-64 bytes 1600 | pub id: String, 1601 | 1602 | /// A valid file identifier for the GIF file 1603 | pub gif_file_id: String, 1604 | 1605 | /// Title for the result 1606 | pub title: Option, 1607 | 1608 | /// Caption of the GIF file to be sent, 0-200 characters 1609 | pub caption: Option, 1610 | 1611 | /// Send Markdown or HTML, if you want Telegram apps to show bold, italic, 1612 | /// fixed-width text or inline URLs in the media caption. 1613 | /// See https://core.telegram.org/bots/api#markdown-style 1614 | /// See https://core.telegram.org/bots/api#html-style 1615 | /// See https://core.telegram.org/bots/api#formatting-options 1616 | pub parse_mode: Option, 1617 | 1618 | /// Inline keyboard attached to the message 1619 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1620 | pub reply_markup: Option>, 1621 | 1622 | /// Content of the message to be sent instead of the GIF animation 1623 | pub input_message_content: Option>, 1624 | } 1625 | 1626 | /// Represents a link to a video animation (H.264/MPEG-4 AVC video without 1627 | /// sound) stored on the Telegram servers. By default, this animated MPEG-4 1628 | /// file will be sent by the user with an optional caption. Alternatively, 1629 | /// you can use input_message_content to send a message with the specified 1630 | /// content instead of the animation. 1631 | #[derive(Serialize, Deserialize, Debug, Clone)] 1632 | pub struct InlineQueryResultCachedMpeg4Gif { 1633 | /// Type of the result, must be mpeg4_gif 1634 | #[serde(rename = "type")] 1635 | pub type_tl: String, 1636 | 1637 | /// Unique identifier for this result, 1-64 bytes 1638 | pub id: String, 1639 | 1640 | /// A valid file identifier for the MP4 file 1641 | pub mpeg4_file_id: String, 1642 | 1643 | /// Title for the result 1644 | pub title: Option, 1645 | 1646 | /// Caption of the MPEG-4 file to be sent, 0-200 characters 1647 | pub caption: Option, 1648 | 1649 | /// Send Markdown or HTML, if you want Telegram apps to show bold, italic, 1650 | /// fixed-width text or inline URLs in the media caption. 1651 | /// See https://core.telegram.org/bots/api#markdown-style 1652 | /// See https://core.telegram.org/bots/api#html-style 1653 | /// See https://core.telegram.org/bots/api#formatting-options 1654 | pub parse_mode: Option, 1655 | 1656 | /// Inline keyboard attached to the message 1657 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1658 | pub reply_markup: Option>, 1659 | 1660 | /// Content of the message to be sent instead of the video animation 1661 | pub input_message_content: Option>, 1662 | } 1663 | 1664 | /// Represents a link to a sticker stored on the Telegram servers. By 1665 | /// default, this sticker will be sent by the user. Alternatively, you can 1666 | /// use input_message_content to send a message with the specified content 1667 | /// instead of the sticker. 1668 | #[derive(Serialize, Deserialize, Debug, Clone)] 1669 | pub struct InlineQueryResultCachedSticker { 1670 | /// Type of the result, must be sticker 1671 | #[serde(rename = "type")] 1672 | pub type_tl: String, 1673 | 1674 | /// Unique identifier for this result, 1-64 bytes 1675 | pub id: String, 1676 | 1677 | /// A valid file identifier of the sticker 1678 | pub sticker_file_id: String, 1679 | 1680 | /// Inline keyboard attached to the message 1681 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1682 | pub reply_markup: Option>, 1683 | 1684 | /// Content of the message to be sent instead of the sticker 1685 | pub input_message_content: Option>, 1686 | } 1687 | 1688 | /// Represents a link to a file stored on the Telegram servers. By default, 1689 | /// this file will be sent by the user with an optional caption. 1690 | /// Alternatively, you can use input_message_content to send a message with 1691 | /// the specified content instead of the file. 1692 | #[derive(Serialize, Deserialize, Debug, Clone)] 1693 | pub struct InlineQueryResultCachedDocument { 1694 | /// Type of the result, must be document 1695 | #[serde(rename = "type")] 1696 | pub type_tl: String, 1697 | 1698 | /// Unique identifier for this result, 1-64 bytes 1699 | pub id: String, 1700 | 1701 | /// Title for the result 1702 | pub title: String, 1703 | 1704 | /// A valid file identifier for the file 1705 | pub document_file_id: String, 1706 | 1707 | /// Short description of the result 1708 | pub description: Option, 1709 | 1710 | /// Caption of the document to be sent, 0-200 characters 1711 | pub caption: Option, 1712 | 1713 | /// Send Markdown or HTML, if you want Telegram apps to show bold, italic, 1714 | /// fixed-width text or inline URLs in the media caption. 1715 | /// See https://core.telegram.org/bots/api#markdown-style 1716 | /// See https://core.telegram.org/bots/api#html-style 1717 | /// See https://core.telegram.org/bots/api#formatting-options 1718 | pub parse_mode: Option, 1719 | 1720 | /// Inline keyboard attached to the message 1721 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1722 | pub reply_markup: Option>, 1723 | 1724 | /// Content of the message to be sent instead of the file 1725 | pub input_message_content: Option>, 1726 | } 1727 | 1728 | /// Represents a link to a video file stored on the Telegram servers. By 1729 | /// default, this video file will be sent by the user with an optional 1730 | /// caption. Alternatively, you can use input_message_content to send a 1731 | /// message with the specified content instead of the video. 1732 | #[derive(Serialize, Deserialize, Debug, Clone)] 1733 | pub struct InlineQueryResultCachedVideo { 1734 | /// Type of the result, must be video 1735 | #[serde(rename = "type")] 1736 | pub type_tl: String, 1737 | 1738 | /// Unique identifier for this result, 1-64 bytes 1739 | pub id: String, 1740 | 1741 | /// A valid file identifier for the video file 1742 | pub video_file_id: String, 1743 | 1744 | /// Title for the result 1745 | pub title: String, 1746 | 1747 | /// Short description of the result 1748 | pub description: Option, 1749 | 1750 | /// Caption of the video to be sent, 0-200 characters 1751 | pub caption: Option, 1752 | 1753 | /// Send Markdown or HTML, if you want Telegram apps to show bold, italic, 1754 | /// fixed-width text or inline URLs in the media caption. 1755 | /// See https://core.telegram.org/bots/api#markdown-style 1756 | /// See https://core.telegram.org/bots/api#html-style 1757 | /// See https://core.telegram.org/bots/api#formatting-options 1758 | pub parse_mode: Option, 1759 | 1760 | /// Inline keyboard attached to the message 1761 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1762 | pub reply_markup: Option>, 1763 | 1764 | /// Content of the message to be sent instead of the video 1765 | pub input_message_content: Option>, 1766 | } 1767 | 1768 | /// Represents a link to a voice message stored on the Telegram servers. By 1769 | /// default, this voice message will be sent by the user. Alternatively, you 1770 | /// can use input_message_content to send a message with the specified 1771 | /// content instead of the voice message. 1772 | #[derive(Serialize, Deserialize, Debug, Clone)] 1773 | pub struct InlineQueryResultCachedVoice { 1774 | /// Type of the result, must be voice 1775 | #[serde(rename = "type")] 1776 | pub type_tl: String, 1777 | 1778 | /// Unique identifier for this result, 1-64 bytes 1779 | pub id: String, 1780 | 1781 | /// A valid file identifier for the voice message 1782 | pub voice_file_id: String, 1783 | 1784 | /// Voice message title 1785 | pub title: String, 1786 | 1787 | /// Caption, 0-200 characters 1788 | pub caption: Option, 1789 | 1790 | /// Send Markdown or HTML, if you want Telegram apps to show bold, italic, 1791 | /// fixed-width text or inline URLs in the media caption. 1792 | /// See https://core.telegram.org/bots/api#markdown-style 1793 | /// See https://core.telegram.org/bots/api#html-style 1794 | /// See https://core.telegram.org/bots/api#formatting-options 1795 | pub parse_mode: Option, 1796 | 1797 | /// Inline keyboard attached to the message 1798 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1799 | pub reply_markup: Option>, 1800 | 1801 | /// Content of the message to be sent instead of the voice message 1802 | pub input_message_content: Option>, 1803 | } 1804 | 1805 | /// Represents a link to an mp3 audio file stored on the Telegram servers. 1806 | /// By default, this audio file will be sent by the user. Alternatively, you 1807 | /// can use input_message_content to send a message with the specified 1808 | /// content instead of the audio. 1809 | #[derive(Serialize, Deserialize, Debug, Clone)] 1810 | pub struct InlineQueryResultCachedAudio { 1811 | /// Type of the result, must be audio 1812 | #[serde(rename = "type")] 1813 | pub type_tl: String, 1814 | 1815 | /// Unique identifier for this result, 1-64 bytes 1816 | pub id: String, 1817 | 1818 | /// A valid file identifier for the audio file 1819 | pub audio_file_id: String, 1820 | 1821 | /// Caption, 0-200 characters 1822 | pub caption: Option, 1823 | 1824 | /// Send Markdown or HTML, if you want Telegram apps to show bold, italic, 1825 | /// fixed-width text or inline URLs in the media caption. 1826 | /// See https://core.telegram.org/bots/api#markdown-style 1827 | /// See https://core.telegram.org/bots/api#html-style 1828 | /// See https://core.telegram.org/bots/api#formatting-options 1829 | pub parse_mode: Option, 1830 | 1831 | /// Inline keyboard attached to the message 1832 | /// See https://core.telegram.org/bots/api/bots#inline-keyboards-and-on-the-fly-updating 1833 | pub reply_markup: Option>, 1834 | 1835 | /// Content of the message to be sent instead of the audio 1836 | pub input_message_content: Option>, 1837 | } 1838 | 1839 | /// Represents the content of a text message to be sent as the result of an 1840 | /// inline query. 1841 | /// See https://core.telegram.org/bots/api#inputmessagecontent 1842 | #[derive(Serialize, Deserialize, Debug, Clone)] 1843 | pub struct InputTextMessageContent { 1844 | /// Text of the message to be sent, 1-4096 characters 1845 | pub message_text: String, 1846 | 1847 | /// Send Markdown or HTML, if you want Telegram apps to show bold, italic, 1848 | /// fixed-width text or inline URLs in your bot's message. 1849 | /// See https://core.telegram.org/bots/api#markdown-style 1850 | /// See https://core.telegram.org/bots/api#html-style 1851 | /// See https://core.telegram.org/bots/api#formatting-options 1852 | pub parse_mode: Option, 1853 | 1854 | /// Disables link previews for links in the sent message 1855 | pub disable_web_page_preview: Option, 1856 | } 1857 | 1858 | /// Represents the content of a location message to be sent as the result of 1859 | /// an inline query. 1860 | /// See https://core.telegram.org/bots/api#inputmessagecontent 1861 | #[derive(Serialize, Deserialize, Debug, Clone)] 1862 | pub struct InputLocationMessageContent { 1863 | /// Latitude of the location in degrees 1864 | pub latitude: f64, 1865 | 1866 | /// Longitude of the location in degrees 1867 | pub longitude: f64, 1868 | 1869 | /// Period in seconds for which the location can be updated, should be 1870 | /// between 60 and 86400. 1871 | pub live_period: Option, 1872 | } 1873 | 1874 | /// Represents the content of a venue message to be sent as the result of an 1875 | /// inline query. 1876 | /// See https://core.telegram.org/bots/api#inputmessagecontent 1877 | #[derive(Serialize, Deserialize, Debug, Clone)] 1878 | pub struct InputVenueMessageContent { 1879 | /// Latitude of the venue in degrees 1880 | pub latitude: f64, 1881 | 1882 | /// Longitude of the venue in degrees 1883 | pub longitude: f64, 1884 | 1885 | /// Name of the venue 1886 | pub title: String, 1887 | 1888 | /// Address of the venue 1889 | pub address: String, 1890 | 1891 | /// Foursquare identifier of the venue, if known 1892 | pub foursquare_id: Option, 1893 | } 1894 | 1895 | /// Represents the content of a contact message to be sent as the result of 1896 | /// an inline query. 1897 | /// See https://core.telegram.org/bots/api#inputmessagecontent 1898 | #[derive(Serialize, Deserialize, Debug, Clone)] 1899 | pub struct InputContactMessageContent { 1900 | /// Contact's phone number 1901 | pub phone_number: String, 1902 | 1903 | /// Contact's first name 1904 | pub first_name: String, 1905 | 1906 | /// Contact's last name 1907 | pub last_name: Option, 1908 | } 1909 | 1910 | /// Represents a result of an inline query that was chosen by the user and 1911 | /// sent to their chat partner. 1912 | /// See https://core.telegram.org/bots/api#inlinequeryresult 1913 | #[derive(Serialize, Deserialize, Debug, Clone)] 1914 | pub struct ChosenInlineResult { 1915 | /// The unique identifier for the result that was chosen 1916 | pub result_id: String, 1917 | 1918 | /// The user that chose the result 1919 | pub from: Box, 1920 | 1921 | /// Sender location, only for bots that require user location 1922 | pub location: Option>, 1923 | 1924 | /// Identifier of the sent inline message. Available only if there is an 1925 | /// inline keyboard attached to the message. Will be also received in 1926 | /// callback queries and can be used to edit the message. 1927 | /// See https://core.telegram.org/bots/api#inlinekeyboardmarkup 1928 | /// See https://core.telegram.org/bots/api#callbackquery 1929 | /// See https://core.telegram.org/bots/api#updating-messages 1930 | pub inline_message_id: Option, 1931 | 1932 | /// The query that was used to obtain the result 1933 | pub query: String, 1934 | } 1935 | 1936 | /// This object represents a portion of the price for goods or services. 1937 | #[derive(Serialize, Deserialize, Debug, Clone)] 1938 | pub struct LabeledPrice { 1939 | /// Portion label 1940 | pub label: String, 1941 | 1942 | /// Price of the product in the smallest units of the currency (integer, not 1943 | /// float/double). For example, for a price of US$ 1.45 pass amount = 145. 1944 | /// See the exp parameter in currencies.json, it shows the number of digits 1945 | /// past the decimal point for each currency (2 for the majority of currencies). 1946 | /// See https://core.telegram.org/bots/api/bots/payments#supported-currencies 1947 | /// See https://core.telegram.org/bots/payments/currencies.json 1948 | pub amount: i64, 1949 | } 1950 | 1951 | /// This object contains basic information about an invoice. 1952 | #[derive(Serialize, Deserialize, Debug, Clone)] 1953 | pub struct Invoice { 1954 | /// Product name 1955 | pub title: String, 1956 | 1957 | /// Product description 1958 | pub description: String, 1959 | 1960 | /// Unique bot deep-linking parameter that can be used to generate this invoice 1961 | pub start_parameter: String, 1962 | 1963 | /// Three-letter ISO 4217 currency code 1964 | /// See https://core.telegram.org/bots/api/bots/payments#supported-currencies 1965 | pub currency: String, 1966 | 1967 | /// Total price in the smallest units of the currency (integer, not 1968 | /// float/double). For example, for a price of US$ 1.45 pass amount = 145. 1969 | /// See the exp parameter in currencies.json, it shows the number of digits 1970 | /// past the decimal point for each currency (2 for the majority of currencies). 1971 | /// See https://core.telegram.org/bots/payments/currencies.json 1972 | pub total_amount: i64, 1973 | } 1974 | 1975 | /// This object represents a shipping address. 1976 | #[derive(Serialize, Deserialize, Debug, Clone)] 1977 | pub struct ShippingAddress { 1978 | /// ISO 3166-1 alpha-2 country code 1979 | pub country_code: String, 1980 | 1981 | /// State, if applicable 1982 | pub state: String, 1983 | 1984 | /// City 1985 | pub city: String, 1986 | 1987 | /// First line for the address 1988 | pub street_line1: String, 1989 | 1990 | /// Second line for the address 1991 | pub street_line2: String, 1992 | 1993 | /// Address post code 1994 | pub post_code: String, 1995 | } 1996 | 1997 | /// This object represents information about an order. 1998 | #[derive(Serialize, Deserialize, Debug, Clone)] 1999 | pub struct OrderInfo { 2000 | /// User name 2001 | pub name: Option, 2002 | 2003 | /// User's phone number 2004 | pub phone_number: Option, 2005 | 2006 | /// User email 2007 | pub email: Option, 2008 | 2009 | /// User shipping address 2010 | pub shipping_address: Option>, 2011 | } 2012 | 2013 | /// This object represents one shipping option. 2014 | #[derive(Serialize, Deserialize, Debug, Clone)] 2015 | pub struct ShippingOption { 2016 | /// Shipping option identifier 2017 | pub id: String, 2018 | 2019 | /// Option title 2020 | pub title: String, 2021 | 2022 | /// List of price portions 2023 | pub prices: Vec>, 2024 | } 2025 | 2026 | /// This object contains basic information about a successful payment. 2027 | #[derive(Serialize, Deserialize, Debug, Clone)] 2028 | pub struct SuccessfulPayment { 2029 | /// Three-letter ISO 4217 currency code 2030 | /// See https://core.telegram.org/bots/api/bots/payments#supported-currencies 2031 | pub currency: String, 2032 | 2033 | /// Total price in the smallest units of the currency (integer, not 2034 | /// float/double). For example, for a price of US$ 1.45 pass amount = 145. 2035 | /// See the exp parameter in currencies.json, it shows the number of digits 2036 | /// past the decimal point for each currency (2 for the majority of currencies). 2037 | /// See https://core.telegram.org/bots/payments/currencies.json 2038 | pub total_amount: i64, 2039 | 2040 | /// Bot specified invoice payload 2041 | pub invoice_payload: String, 2042 | 2043 | /// Identifier of the shipping option chosen by the user 2044 | pub shipping_option_id: Option, 2045 | 2046 | /// Order info provided by the user 2047 | pub order_info: Option>, 2048 | 2049 | /// Telegram payment identifier 2050 | pub telegram_payment_charge_id: String, 2051 | 2052 | /// Provider payment identifier 2053 | pub provider_payment_charge_id: String, 2054 | } 2055 | 2056 | /// This object contains information about an incoming shipping query. 2057 | #[derive(Serialize, Deserialize, Debug, Clone)] 2058 | pub struct ShippingQuery { 2059 | /// Unique query identifier 2060 | pub id: String, 2061 | 2062 | /// User who sent the query 2063 | pub from: Box, 2064 | 2065 | /// Bot specified invoice payload 2066 | pub invoice_payload: String, 2067 | 2068 | /// User specified shipping address 2069 | pub shipping_address: Box, 2070 | } 2071 | 2072 | /// This object contains information about an incoming pre-checkout query. 2073 | #[derive(Serialize, Deserialize, Debug, Clone)] 2074 | pub struct PreCheckoutQuery { 2075 | /// Unique query identifier 2076 | pub id: String, 2077 | 2078 | /// User who sent the query 2079 | pub from: Box, 2080 | 2081 | /// Three-letter ISO 4217 currency code 2082 | /// See https://core.telegram.org/bots/api/bots/payments#supported-currencies 2083 | pub currency: String, 2084 | 2085 | /// Total price in the smallest units of the currency (integer, not 2086 | /// float/double). For example, for a price of US$ 1.45 pass amount = 145. 2087 | /// See the exp parameter in currencies.json, it shows the number of digits 2088 | /// past the decimal point for each currency (2 for the majority of currencies). 2089 | /// See https://core.telegram.org/bots/payments/currencies.json 2090 | pub total_amount: i64, 2091 | 2092 | /// Bot specified invoice payload 2093 | pub invoice_payload: String, 2094 | 2095 | /// Identifier of the shipping option chosen by the user 2096 | pub shipping_option_id: Option, 2097 | 2098 | /// Order info provided by the user 2099 | pub order_info: Option>, 2100 | } 2101 | 2102 | /// This object represents a game. Use BotFather to create and edit games, 2103 | /// their short names will act as unique identifiers. 2104 | #[derive(Serialize, Deserialize, Debug, Clone)] 2105 | pub struct Game { 2106 | /// Title of the game 2107 | pub title: String, 2108 | 2109 | /// Description of the game 2110 | pub description: String, 2111 | 2112 | /// Photo that will be displayed in the game message in chats. 2113 | pub photo: Vec>, 2114 | 2115 | /// Brief description of the game or high scores included in the game 2116 | /// message. Can be automatically edited to include current high scores for 2117 | /// the game when the bot calls setGameScore, or manually edited using 2118 | /// editMessageText. 0-4096 characters. 2119 | /// See https://core.telegram.org/bots/api#setgamescore 2120 | /// See https://core.telegram.org/bots/api#editmessagetext 2121 | pub text: Option, 2122 | 2123 | /// Special entities that appear in text, such as usernames, URLs, bot 2124 | /// commands, etc. 2125 | pub text_entities: Option>>, 2126 | 2127 | /// Animation that will be displayed in the game message in chats. Upload 2128 | /// via BotFather 2129 | /// See https://t.me/botfather 2130 | pub animation: Option>, 2131 | } 2132 | 2133 | /// You can provide an animation for your game so that it looks stylish in 2134 | /// chats (check out Lumberjack for an example). This object represents an 2135 | /// animation file to be displayed in the message containing a game. 2136 | /// See https://core.telegram.org/bots/api#game 2137 | /// See https://t.me/gamebot 2138 | /// See https://core.telegram.org/bots/api#games 2139 | #[derive(Serialize, Deserialize, Debug, Clone)] 2140 | pub struct Animation { 2141 | /// Unique file identifier 2142 | pub file_id: String, 2143 | 2144 | /// Animation thumbnail as defined by sender 2145 | pub thumb: Option>, 2146 | 2147 | /// Original animation filename as defined by sender 2148 | pub file_name: Option, 2149 | 2150 | /// MIME type of the file as defined by sender 2151 | pub mime_type: Option, 2152 | 2153 | /// File size 2154 | pub file_size: Option, 2155 | } 2156 | 2157 | /// This object represents one row of the high scores table for a game. 2158 | #[derive(Serialize, Deserialize, Debug, Clone)] 2159 | pub struct GameHighScore { 2160 | /// Position in high score table for the game 2161 | pub position: i64, 2162 | 2163 | /// User 2164 | pub user: Box, 2165 | 2166 | /// Score 2167 | pub score: i64, 2168 | } 2169 | -------------------------------------------------------------------------------- /tt.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": ".", 5 | "name": "Generator" 6 | }, 7 | { 8 | "path": "rust", 9 | "name": "Rust" 10 | }, 11 | { 12 | "path": "javascript", 13 | "name": "JavaScript" 14 | } 15 | ], 16 | "settings": { 17 | "javascript.validate.enable": false, 18 | "typescript.validate.enable": false, 19 | "workbench.colorTheme": "Atom One Dark" 20 | } 21 | } 22 | --------------------------------------------------------------------------------