├── .gitignore ├── .idea ├── .gitignore ├── handbook.iml ├── inspectionProfiles │ └── profiles_settings.xml ├── misc.xml ├── modules.xml └── vcs.xml ├── .vitepress ├── config │ ├── head.ts │ ├── index.mts │ ├── ru │ │ ├── index.ts │ │ └── sidebar.ts │ └── sidebar.ts └── theme │ ├── Layout.vue │ ├── SidebarButton.vue │ ├── custom.css │ ├── index.ts │ └── vars.css ├── en ├── chats │ ├── channels.md │ ├── forums.md │ ├── groups.md │ ├── id.md │ ├── pm.md │ └── supergroups.md ├── dev │ ├── api.md │ ├── basics.md │ ├── botfather.md │ ├── host.md │ ├── libraries.md │ ├── updates.md │ └── usernames.md ├── index.md ├── interaction │ ├── html-games.md │ ├── inline.md │ ├── join-requests.md │ ├── links.md │ ├── login-widget.md │ ├── mini-apps.md │ ├── payments.md │ └── stickers.md ├── messages │ ├── buttons.md │ ├── commands.md │ ├── id.md │ ├── markup.md │ └── sending.md └── unlisted │ └── official-bots.md ├── index.md ├── netlify.toml ├── package.json ├── public ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon.png ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── logo-dark.svg ├── logo.svg ├── pictures │ ├── other │ │ └── syntax.mp4 │ └── ru │ │ ├── admin-rights.png │ │ ├── bot-profile.png │ │ ├── botfather.png │ │ ├── callback-buttons.webm │ │ ├── channel-buttons.png │ │ ├── commands-autocomplete.png │ │ ├── commands.png │ │ ├── customization.png │ │ ├── forum.png │ │ ├── friedrich.png │ │ ├── highlighter.png │ │ ├── inline-both-types.png │ │ ├── inline-feedback.png │ │ ├── inline-type-1.png │ │ ├── inline-type-2.png │ │ ├── inline.webm │ │ ├── keyboard-buttons.webm │ │ ├── privacy.png │ │ ├── spoiler.png │ │ ├── start.gif │ │ ├── start.webm │ │ ├── switch-inline-button.webm │ │ ├── url-button.png │ │ └── wide-buttons.png ├── screenshot.png └── site.webmanifest ├── readme.md ├── ru ├── chats │ ├── channels.md │ ├── forums.md │ ├── groups.md │ ├── id.md │ ├── pm.md │ └── supergroups.md ├── dev │ ├── api.md │ ├── basics.md │ ├── botfather.md │ ├── host.md │ ├── libraries.md │ ├── updates.md │ └── usernames.md ├── index.md ├── interaction │ ├── html-games.md │ ├── inline.md │ ├── join-requests.md │ ├── links.md │ ├── login-widget.md │ ├── mini-apps.md │ ├── payments.md │ └── stickers.md ├── messages │ ├── buttons.md │ ├── commands.md │ ├── id.md │ ├── markup.md │ └── sending.md └── unlisted │ └── official-bots.md └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | .idea/ 4 | 5 | # Vitepress 6 | .vitepress/cache/ 7 | .vitepress/dist/ 8 | *.mts.timestamp-* 9 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/handbook.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.vitepress/config/head.ts: -------------------------------------------------------------------------------- 1 | import {HeadConfig} from 'vitepress/types/shared' 2 | 3 | const metrikaScript = `(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)}; m[i].l=1*new Date(); for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }} k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)}) (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym"); ym(95150339, "init", { defer:true, clickmap:true, trackLinks:true, accurateTrackBounce:true, webvisor:true });` 4 | const metrikaNoscript = `
` 5 | 6 | const head: HeadConfig[] = [ 7 | ['script', {type: 'text/javascript'}, metrikaScript], 8 | ['noscript', {}, metrikaNoscript], 9 | 10 | ['link', {rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png'}], 11 | ['link', {rel: 'icon', type: 'image/png', sizes: '32x32', href: '/favicon-32x32.png'}], 12 | ['link', {rel: 'icon', type: 'image/png', sizes: '16x16', href: '/favicon-16x16.png'}], 13 | ['link', {rel: 'manifest', href: '/site.webmanifest'}], 14 | ] 15 | 16 | export default head 17 | -------------------------------------------------------------------------------- /.vitepress/config/index.mts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vitepress' 2 | import head from './head' 3 | import ruConfig from './ru' 4 | import sidebar from './sidebar' 5 | 6 | // https://vitepress.dev/reference/site-config 7 | export default defineConfig({ 8 | title: 'Telegram Bot Handbook', 9 | titleTemplate: 'Handbook', 10 | 11 | appearance: 'dark', 12 | cleanUrls: true, 13 | description: 'Explore Telegram features, bot limitations, and API tricks.', 14 | head: head, 15 | lastUpdated: true, 16 | locales: { 17 | root: { 18 | label: 'English', 19 | lang: 'en', 20 | link: '/en/', 21 | }, 22 | ru: { 23 | label: 'Русский', 24 | lang: 'ru', 25 | ...ruConfig, 26 | }, 27 | }, 28 | sitemap: { 29 | hostname: 'https://handbook.tmat.me', 30 | }, 31 | srcExclude: ['readme.md'], 32 | markdown: { 33 | config: (md) => { 34 | md.disable('emoji') 35 | } 36 | }, 37 | themeConfig: { 38 | editLink: { 39 | pattern: 'https://github.com/tm-a-t/handbook/edit/main/:path' 40 | }, 41 | lastUpdated: { 42 | formatOptions: { 43 | // @ts-ignore 44 | dateStyle: 'long', 45 | forceLocale: true, 46 | }, 47 | }, 48 | logo: {dark: '/logo.svg', light: '/logo-dark.svg', alt: 'Handbook'}, 49 | nav: [ 50 | {text: 'Share', link: 'https://t.me/share?url=handbook.tmat.me/en/'}, 51 | ], 52 | outline: 'deep', 53 | search: { 54 | provider: 'algolia', 55 | options: { 56 | appId: 'XWCAXSO1PW', 57 | apiKey: 'baac738133a1f9099fb1aa9fce51603b', 58 | indexName: 'handbook-tmat', 59 | } 60 | }, 61 | sidebar: sidebar, 62 | socialLinks: [ 63 | {icon: 'github', link: 'https://github.com/tm-a-t/handbook'}, 64 | ], 65 | }, 66 | }) 67 | -------------------------------------------------------------------------------- /.vitepress/config/ru/index.ts: -------------------------------------------------------------------------------- 1 | import {LocaleSpecificConfig} from 'vitepress/types/shared' 2 | import {DefaultTheme} from 'vitepress/types/default-theme' 3 | import sidebar from './sidebar' 4 | 5 | const ruConfig: LocaleSpecificConfig = { 6 | titleTemplate: ':title — хендбук', 7 | description: 'Карманное руководство разработчика Телеграм-ботов. Фичи и приёмы', 8 | head: [ 9 | 10 | ], 11 | themeConfig: { 12 | sidebarMenuLabel: 'Меню', 13 | returnToTopLabel: 'Наверх', 14 | darkModeSwitchLabel: 'Тёмная тема', 15 | outline: { 16 | level: 'deep', 17 | label: 'На этой странице' 18 | }, 19 | docFooter: { 20 | prev: 'Назад', 21 | next: 'Вперёд', 22 | }, 23 | nav: [ 24 | {text: 'Поделиться', link: 'https://t.me/share?url=handbook.tmat.me/ru/'}, 25 | ], 26 | editLink: { 27 | pattern: 'https://github.com/tm-a-t/handbook/edit/main/:path', 28 | text: 'Изменить', 29 | }, 30 | lastUpdated: { 31 | text: 'Обновлено', 32 | formatOptions: { 33 | // @ts-ignore 34 | dateStyle: 'long', 35 | forceLocale: true, 36 | }, 37 | }, 38 | sidebar: sidebar, 39 | }, 40 | } 41 | 42 | export default ruConfig 43 | -------------------------------------------------------------------------------- /.vitepress/config/ru/sidebar.ts: -------------------------------------------------------------------------------- 1 | import {DefaultTheme} from 'vitepress' 2 | 3 | const sidebar: DefaultTheme.Sidebar = [ 4 | {text: 'Начало', link: '/ru/index.md'}, 5 | { 6 | text: 'Разработка', 7 | items: [ 8 | {text: 'Введение', link: '/ru/dev/basics.md'}, 9 | {text: 'Telegram API', link: '/ru/dev/api.md'}, 10 | {text: 'Библиотеки', link: '/ru/dev/libraries.md'}, 11 | {text: 'Юзернеймы', link: '/ru/dev/usernames.md'}, 12 | {text: 'Настройка', link: '/ru/dev/botfather.md'}, 13 | {text: 'Апдейты', link: '/ru/dev/updates.md'}, 14 | {text: 'Хостинг', link: '/ru/dev/host.md'}, 15 | ], 16 | }, 17 | { 18 | text: 'Сообщения', items: [ 19 | {text: 'Отправка', link: '/ru/messages/sending.md'}, 20 | {text: 'Разметка', link: '/ru/messages/markup.md'}, 21 | {text: 'Команды', link: '/ru/messages/commands.md'}, 22 | {text: 'Кнопки', link: '/ru/messages/buttons.md'}, 23 | {text: 'ID сообщений', link: '/ru/messages/id.md'}, 24 | ], 25 | }, 26 | { 27 | text: 'Чаты', items: [ 28 | {text: 'Пользователи', link: '/ru/chats/pm.md'}, 29 | {text: 'Группы', link: '/ru/chats/groups.md'}, 30 | {text: 'Каналы', link: '/ru/chats/channels.md'}, 31 | {text: 'Форумы', link: '/ru/chats/forums.md'}, 32 | {text: 'О супергруппах', link: '/ru/chats/supergroups.md'}, 33 | {text: 'ID чатов', link: '/ru/chats/id.md'}, 34 | ], 35 | }, 36 | { 37 | text: 'Интерактивность', items: [ 38 | {text: 'Заявки', link: '/ru/interaction/join-requests.md'}, 39 | {text: 'Ссылки на бота', link: '/ru/interaction/links.md'}, 40 | {text: 'Инлайн-режим', link: '/ru/interaction/inline.md'}, 41 | {text: 'Стикеры', link: '/ru/interaction/stickers.md'}, 42 | {text: 'Платежи', link: '/ru/interaction/payments.md'}, 43 | {text: 'Авторизация на сайте', link: '/ru/interaction/login-widget.md'}, 44 | {text: 'HTML-игры', link: '/ru/interaction/html-games.md'}, 45 | {text: 'Мини-приложения', link: '/ru/interaction/mini-apps.md'}, 46 | ], 47 | }, 48 | ] 49 | 50 | export default sidebar 51 | -------------------------------------------------------------------------------- /.vitepress/config/sidebar.ts: -------------------------------------------------------------------------------- 1 | import {DefaultTheme} from 'vitepress' 2 | 3 | const sidebar: DefaultTheme.Sidebar = [ 4 | {text: 'Home', link: '/en/index.md'}, 5 | { 6 | text: 'Development', 7 | items: [ 8 | {text: 'Intro', link: '/en/dev/basics.md'}, 9 | {text: 'Telegram API', link: '/en/dev/api.md'}, 10 | {text: 'Libraries', link: '/en/dev/libraries.md'}, 11 | {text: 'Usernames', link: '/en/dev/usernames.md'}, 12 | {text: 'Settings', link: '/en/dev/botfather.md'}, 13 | {text: 'Updates', link: '/en/dev/updates.md'}, 14 | {text: 'Host', link: '/en/dev/host.md'}, 15 | ], 16 | }, 17 | { 18 | text: 'Messages', items: [ 19 | {text: 'Sending', link: '/en/messages/sending.md'}, 20 | {text: 'Markup', link: '/en/messages/markup.md'}, 21 | {text: 'Commands', link: '/en/messages/commands.md'}, 22 | {text: 'Buttons', link: '/en/messages/buttons.md'}, 23 | {text: 'Message IDs', link: '/en/messages/id.md'}, 24 | ], 25 | }, 26 | { 27 | text: 'Chats', items: [ 28 | {text: 'Users', link: '/en/chats/pm.md'}, 29 | {text: 'Groups', link: '/en/chats/groups.md'}, 30 | {text: 'Channels', link: '/en/chats/channels.md'}, 31 | {text: 'Forums', link: '/en/chats/forums.md'}, 32 | {text: 'Supergroups', link: '/en/chats/supergroups.md'}, 33 | {text: 'Chat IDs', link: '/en/chats/id.md'}, 34 | ], 35 | }, 36 | { 37 | text: 'Interaction', items: [ 38 | {text: 'Join Requests', link: '/en/interaction/join-requests.md'}, 39 | {text: 'Bot Links', link: '/en/interaction/links.md'}, 40 | {text: 'Inline Mode', link: '/en/interaction/inline.md'}, 41 | {text: 'Stickers', link: '/en/interaction/stickers.md'}, 42 | {text: 'Payments', link: '/en/interaction/payments.md'}, 43 | {text: 'Web Login', link: '/en/interaction/login-widget.md'}, 44 | {text: 'HTML Games', link: '/en/interaction/html-games.md'}, 45 | {text: 'Mini Apps', link: '/en/interaction/mini-apps.md'}, 46 | ], 47 | }, 48 | ] 49 | 50 | export default sidebar 51 | -------------------------------------------------------------------------------- /.vitepress/theme/Layout.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 20 | 21 | 29 | -------------------------------------------------------------------------------- /.vitepress/theme/SidebarButton.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 27 | 28 | -------------------------------------------------------------------------------- /.vitepress/theme/custom.css: -------------------------------------------------------------------------------- 1 | ::selection { 2 | background-color: var(--vp-c-brand-2); 3 | color: var(--vp-c-neutral-inverse); 4 | } 5 | 6 | .vp-doc img { 7 | border-radius: 8px; 8 | } 9 | 10 | .logo { 11 | transform: translateY(-2.5px); 12 | } 13 | 14 | .vp-doc details tr:nth-child(2n) { 15 | background: inherit; 16 | } 17 | 18 | .vp-doc details td { 19 | border: none; 20 | } 21 | -------------------------------------------------------------------------------- /.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | // https://vitepress.dev/guide/custom-theme 2 | import Theme from 'vitepress/theme' 3 | import './vars.css' 4 | import './custom.css' 5 | // @ts-ignore 6 | import Layout from './Layout.vue' 7 | 8 | export default { 9 | extends: Theme, 10 | Layout: Layout, 11 | enhanceApp({ app, router, siteData }) { 12 | // ... 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.vitepress/theme/vars.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Customize default theme styling by overriding CSS variables: 3 | * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css 4 | */ 5 | 6 | :root { 7 | --vp-sidebar-width: 288px; 8 | } 9 | 10 | 11 | /** 12 | * Colors 13 | * 14 | * Each colors have exact same color scale system with 3 levels of solid 15 | * colors with different brightness, and 1 soft color. 16 | * 17 | * - `XXX-1`: The most solid color used mainly for colored text. It must 18 | * satisfy the contrast ratio against when used on top of `XXX-soft`. 19 | * 20 | * - `XXX-2`: The color used mainly for hover state of the button. 21 | * 22 | * - `XXX-3`: The color for solid background, such as bg color of the button. 23 | * It must satisfy the contrast ratio with pure white (#ffffff) text on 24 | * top of it. 25 | * 26 | * - `XXX-soft`: The color used for subtle background such as custom container 27 | * or badges. It must satisfy the contrast ratio when putting `XXX-1` colors 28 | * on top of it. 29 | * 30 | * The soft color must be semi transparent alpha channel. This is crucial 31 | * because it allows adding multiple "soft" colors on top of each other 32 | * to create a accent, such as when having inline code block inside 33 | * custom containers. 34 | * 35 | * - `default`: The color used purely for subtle indication without any 36 | * special meanings attached to it such as bg color for menu hover state. 37 | * 38 | * - `brand`: Used for primary brand colors, such as link text, button with 39 | * brand theme, etc. 40 | * 41 | * - `tip`: Used to indicate useful information. The default theme uses the 42 | * brand color for this by default. 43 | * 44 | * - `warning`: Used to indicate warning to the users. Used in custom 45 | * container, badges, etc. 46 | * 47 | * - `danger`: Used to show error, or dangerous message to the users. Used 48 | * in custom container, badges, etc. 49 | * -------------------------------------------------------------------------- */ 50 | 51 | :root { 52 | --vp-c-default-1: var(--vp-c-gray-1); 53 | --vp-c-default-2: var(--vp-c-gray-2); 54 | --vp-c-default-3: var(--vp-c-gray-3); 55 | --vp-c-default-soft: var(--vp-c-gray-soft); 56 | 57 | --vp-c-brand-1: var(--vp-c-indigo-1); 58 | --vp-c-brand-2: var(--vp-c-indigo-2); 59 | --vp-c-brand-3: var(--vp-c-indigo-3); 60 | --vp-c-brand-soft: var(--vp-c-indigo-soft); 61 | 62 | --vp-c-tip-1: var(--vp-c-brand-1); 63 | --vp-c-tip-2: var(--vp-c-brand-2); 64 | --vp-c-tip-3: var(--vp-c-brand-3); 65 | --vp-c-tip-soft: var(--vp-c-brand-soft); 66 | 67 | --vp-c-warning-1: var(--vp-c-yellow-1); 68 | --vp-c-warning-2: var(--vp-c-yellow-2); 69 | --vp-c-warning-3: var(--vp-c-yellow-3); 70 | --vp-c-warning-soft: var(--vp-c-yellow-soft); 71 | 72 | --vp-c-danger-1: var(--vp-c-red-1); 73 | --vp-c-danger-2: var(--vp-c-red-2); 74 | --vp-c-danger-3: var(--vp-c-red-3); 75 | --vp-c-danger-soft: var(--vp-c-red-soft); 76 | } 77 | 78 | /** 79 | * Component: Button 80 | * -------------------------------------------------------------------------- */ 81 | 82 | :root { 83 | --vp-button-brand-border: transparent; 84 | --vp-button-brand-text: var(--vp-c-white); 85 | --vp-button-brand-bg: var(--vp-c-brand-3); 86 | --vp-button-brand-hover-border: transparent; 87 | --vp-button-brand-hover-text: var(--vp-c-white); 88 | --vp-button-brand-hover-bg: var(--vp-c-brand-2); 89 | --vp-button-brand-active-border: transparent; 90 | --vp-button-brand-active-text: var(--vp-c-white); 91 | --vp-button-brand-active-bg: var(--vp-c-brand-1); 92 | } 93 | 94 | /** 95 | * Component: Home 96 | * -------------------------------------------------------------------------- */ 97 | 98 | :root { 99 | --vp-home-hero-name-color: transparent; 100 | --vp-home-hero-name-background: -webkit-linear-gradient( 101 | 120deg, 102 | #bd34fe 30%, 103 | #41d1ff 104 | ); 105 | 106 | --vp-home-hero-image-background-image: linear-gradient( 107 | -45deg, 108 | #bd34fe 50%, 109 | #47caff 50% 110 | ); 111 | --vp-home-hero-image-filter: blur(40px); 112 | } 113 | 114 | @media (min-width: 640px) { 115 | :root { 116 | --vp-home-hero-image-filter: blur(56px); 117 | } 118 | } 119 | 120 | @media (min-width: 960px) { 121 | :root { 122 | --vp-home-hero-image-filter: blur(72px); 123 | } 124 | } 125 | 126 | /** 127 | * Component: Custom Block 128 | * -------------------------------------------------------------------------- */ 129 | 130 | :root { 131 | --vp-custom-block-tip-border: transparent; 132 | --vp-custom-block-tip-text: var(--vp-c-text-1); 133 | --vp-custom-block-tip-bg: var(--vp-c-brand-soft); 134 | --vp-custom-block-tip-code-bg: var(--vp-c-brand-soft); 135 | } 136 | 137 | /** 138 | * Component: Algolia 139 | * -------------------------------------------------------------------------- */ 140 | 141 | .DocSearch { 142 | --docsearch-primary-color: var(--vp-c-brand-1) !important; 143 | } 144 | 145 | -------------------------------------------------------------------------------- /en/chats/channels.md: -------------------------------------------------------------------------------- 1 | # How Telegram Bots Can Be Useful in Channels 2 | 3 | Bots can participate in channels only as admins. Admin rights allow bots sending and editing posts, renaming channels, 4 | and so on. 5 | 6 | ## Admin rights 7 | 8 | Just like in groups, channel admins can select bot admin rights where the default options can be configured in BotFather. 9 | 10 | ## Adding buttons to posts 11 | 12 | The most common use case for bots in channels is adding buttons: likes, links, and other. 13 | 14 | This works with use of the "Edit messages of others" admin right: a bot may add buttons when editing messages. 15 | 16 | Like this: 17 | 18 | ![Post with buttons](/pictures/ru/channel-buttons.png) 19 | -------------------------------------------------------------------------------- /en/chats/forums.md: -------------------------------------------------------------------------------- 1 | # Developing Telegram Bots for Forums 2 | 3 | Forums are groups splitted into multiple topics. 4 | 5 |
6 | 7 |
8 | 9 | ![Форум](/pictures/ru/forum.png) 10 | 11 |
In the picture, forum topics are listed and other chats have shrunk into a small column.
12 |
13 | 14 | ## How topics work 15 | 16 | Forum is simply a group with a special user interface. You can view a forum as a regular chat in the official apps 17 | using forum menu. (This mode indicates a topic of every message.) 18 | 19 | Technically, topics work as following. 20 | 21 | When a topic is created, a system message "Topic created" appears. Replies to this message fall into the topic. 22 | 23 | Topic ID is the system message ID. 24 | 25 | The #general topic is the topic where all other messages go. It has ID 1. 26 | 27 | ## Usage 28 | 29 | If your bot works in groups, then you probably should consider the case when the group is the forum. 30 | For example, if a user sends a command, the bot should answer in the same topic 31 | (otherwise the response will appear in #general.) 32 | 33 | ## Managing topics 34 | 35 | Bots can open, edit, and close topics just like users. Depending on the forum settings this may require an admin right. 36 | -------------------------------------------------------------------------------- /en/chats/groups.md: -------------------------------------------------------------------------------- 1 | # Developing Telegram Bots for Groups 2 | 3 | Users can add bots to groups, but bots cannot join groups by their own. Bot developer can forbid adding to groups 4 | [in BotFather settings](../dev/botfather). 5 | 6 | In public groups, which means groups with usernames, bots can only be added by admins. 7 | Group admins can grant the bot admin rights to allow deleting group members and doing other admin actions. 8 | 9 | A group may contain up to 20 bots. 10 | 11 | ![Bot highlight example](/pictures/ru/highlighter.png) 12 | 13 | ## Privacy mode: message visibility { #privacy } 14 | 15 | Many bots should react only [to commands](../messages/commands.md). 16 | This is why by default Telegram doesn't notify bots about non-command messages (protecting the group's privacy). 17 | 18 | However, you can make your bot see all chat messages by turning off privacy mode. 19 | 20 | Privacy mode is a BotFather setting which is activated by default. In this mode, the bot only sees group messages that 21 | address the bot: 22 | - [Commands](../messages/commands) 23 | - Replies on bot messages, replies to replies and so on 24 | - Messages [mentioning](../messages/markup#упоминание-пользователя) the bot 25 | - System messages 26 | 27 | When the privacy mode is off, the bot can see all messages in groups except for ones from other bots. 28 | 29 | If a bot is a group admin, it sees all messages as well regardless of the privacy mode setting. 30 | 31 | ![A bot that doesn't see some messages](/pictures/ru/friedrich.png) 32 | 33 | ::: tip Troubles turning off privacy mode? 34 | When you turned off the privacy mode, you should delete the bot from the group and add it back 35 | in order to apply changes. 36 | ::: 37 | 38 | Mobile and desktop Telegram apps indicate whether the privacy mode is on in group member lists: 39 | 40 | ![Пример бота](/pictures/ru/privacy.png){ style="margin: 0 auto" } 41 | 42 | ::: info Force reply {#force-reply} 43 | If a bot has the privacy mode enabled and asks a group member a question, the user's answer clearly 44 | should be a message reply so that the bot can see it. 45 | 46 | Rather than ask the user to choose to "reply", a bot can send a "force reply" message which automatically makes 47 | the user start replying. 48 | 49 | However, I don't recommend using force reply because automatic replies confuse users. 50 | ::: 51 | 52 | ## Admin rights 53 | 54 | When a user makes a bot a chat admin, they can select admin rights. There is a BotFather setting for specifying 55 | the admin rights suggested by default. 56 | 57 | The right to remain anonymous, which allows users to send messages on behalf of the group, has no effect on bots. 58 | 59 | ![Choosing rights](/pictures/ru/admin-rights.png) 60 | 61 | ## Sending messages to group members 62 | 63 | Group messages are visible to all members. There is no way for a bot to show a message to one person only. 64 | For example, if a bot greets new members, all members will receive the message. 65 | 66 | To keep the chat clean, the bot can delete auxiliary messages in some time. If your bot is to write personal messages 67 | to users, [join requests](../interaction/join-requests) may be useful to get PM permission. 68 | 69 | ## Messages on behalf of groups and channels 70 | 71 | Note that your program should handle the cases when the message senders in groups are not users: 72 | 73 | - Messages from a linked channel in a discussion group (API treats them as forwarded) 74 | - Messages from a group by anonymous group admins 75 | - Messages from public channels by premium users 76 | 77 | ## Related links 78 | 79 | - [Telegram docs. Privacy mode](https://core.telegram.org/bots/features#privacy-mode) 80 | -------------------------------------------------------------------------------- /en/chats/id.md: -------------------------------------------------------------------------------- 1 | # How IDs of Users and Chats Work 2 | 3 | Each user, bot, group, or channel has an invariable ID. 4 | 5 | Official Telegram apps don't show IDs. Use unofficial apps or bots [like this](https://t.me/getmyid_bot) when you need 6 | to manually learn specific user or chat IDs. 7 | 8 | ::: warning 9 | Don't store user and chat IDs in 32-bit integers: they may be too large. 10 | Double-precision floats (such as `number` in JS) or 64-bit integers are OK. 11 | ::: 12 | 13 | ## In Bot API { #bot-api } 14 | 15 | In Bot API, regular group IDs start with `-` and supergroup IDs start with `-100`. 16 | Thus, a channel with an actual ID `1356415630` has ID `-1001356415630` in Bot API. 17 | 18 | ## Bot ID in its token 19 | 20 | The first part of a bot token is the bot ID. For example, the token `110201874:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw` 21 | belongs to the bot with ID `110201874`. 22 | -------------------------------------------------------------------------------- /en/chats/pm.md: -------------------------------------------------------------------------------- 1 | # Personal Messages With Your Bot and Profiles of Users 2 | 3 | ## How a personal dialog starts 4 | 5 | A bot may send messages to the user only after they allowed it. Once the dialog is started, the bot can send messages 6 | any time. 7 | 8 | Bots may not send messages to other bots. 9 | 10 | ### 1. Starting a bot directly 11 | 12 | Normally, PM start when the user opens the bot and clicks "Start". 13 | 14 | The can open the bot with a link or through the app search, for example. 15 | Then they see ["What this bot can do?" description](../dev/botfather#customization) and the "Start" button. 16 | 17 | A click sends `/start` command. 18 | The bot should reply on this command with a greeting or a usage instruction. 19 | 20 | Just like any other chat, after a person started a dialog with a bot, they see it in the recent chat list. 21 | 22 | ![](/pictures/ru/start.gif) 23 | 24 | ::: warning 25 | `/start` command doesn't imply that this the user has no dialog with the bot. It may be a good idea to make sure your 26 | bot doesn't get broken when the user sends `/start` manually after the dialog started. 27 | 28 | Furthermore, technically the first message from a user may contain other text then `/start`. Users may use Telegram API 29 | to start dialog with any other message. It is unlikely that you will face such crazy users, but still... 30 | ::: 31 | 32 | ::: tip 33 | You can use [deep links](../interaction/links) so that the `/start` message contains additional information. 34 | ::: 35 | 36 | ### 2. Other ways to start a dialog 37 | 38 | A bot may send messages to a user, if one of the following: 39 | 40 | - The user [requested to join](../interaction/join-requests) a group or channel. 41 | - The user [authorized on a site with Telegram Login Widget](../interaction/login-widget) through the bot. 42 | 43 | User sees the reason in the beginning of the dialog. 44 | 45 | ## Stopping the dialog { #block } 46 | 47 | A user can stop the dialog by blocking the bot. The bot will not be able to send personal messages to the user 48 | until they unblock it. 49 | 50 | ::: tip Checking if the bot may text to a user 51 | Try showing a "Bot is typing..." status in the dialog. If Telegram servers returned an error, the bot may not 52 | send messages to the user. 53 | 54 | This means the user has blocked the bot or the dialog has never started. 55 | ::: 56 | 57 | ## User profile 58 | 59 | While keeping user profile data, keep in mind that users may have no username or no last name. In addition, all such 60 | profile data except for [user ID](../chats/id) can change over time. 61 | 62 | ## User languages 63 | 64 | Bots know the language that a person has set in their Telegram app. 65 | This allows your bot to speak user's native language. 66 | 67 | Still, user language is not always included in the updates. Therefore, if your bot adjusts to user languages, 68 | Telegram recommends to use the last known language in cases the update misses this information. 69 | 70 | ## Seen users { #seen-users } 71 | 72 | Bot must have seen a user to make actions related to this user (mention them, etc.) The bot sees a user, for example, 73 | when the bot receives a message from the user or fetches them by the username. 74 | 75 | Technically speaking, this means API requests must include not only [user ID](./id) but also a relevant 76 | access hash. API gives access hashes together with other user info in updates. Access hashes are cached by Bot API 77 | and good Telegram API libraries, so you should not worry about it. 78 | -------------------------------------------------------------------------------- /en/chats/supergroups.md: -------------------------------------------------------------------------------- 1 | # What Telegram Supergroups Are 2 | 3 | A long time ago, Telegram developers introduced two types of groups: regular ones and supergroups. 4 | Supergroups had public links, larger limit for the number of members, and other features designed for big communities. 5 | 6 | Apparently, this idea has later been considered rather confusing. Telegram app interface no longer mentions 7 | "supergroups" and all groups look the same there, although on the technical level two types remain distinguish. 8 | In fact, most of the groups you participate in are probably supergroups. 9 | 10 | The main trait of supergroups is that API considers them a special case of channels. 11 | 12 | I use the term "groups" both for regular groups and supergroups in the handbook. I've explained developing 13 | group bots [on the page about groups](../chats/groups). 14 | 15 | ## Creating supergroup 16 | 17 | A regular group turns into a supergroup while certain settings are changed. As technically the group is replaced with 18 | a supegroup-channel, [chat ID](../chats/id) changes. A supergroup cannot become a regular group again. 19 | 20 | ## Message and group IDs 21 | 22 | [Message IDs work differently in regular groups and supergroups](../messages/id). 23 | In addition, in Bot API regular group IDs start with `-` prefix while supergroup IDs start with `-100`. 24 | 25 | ## Gigagroups (broadcast groups) 26 | 27 | A maximal number of supergroup members is 200 000. When it's close to the limit, Telegram app suggests admins 28 | turn the supergroup into the gigagroup. Gigagroups may contain an unlimited number of members, 29 | but only admins can send messages there. 30 | 31 | I have no idea why they exist. 32 | 33 | ## Related links 34 | 35 | - (Russian) [Features of different types of groups. Cases when a regular group turns into a supergroup](https://tginfo.me/groups_vs_supergroups/) 36 | - [Telegram API. Differences between regular groups, supergroups, and gigagroups](https://core.telegram.org/api/channel) 37 | -------------------------------------------------------------------------------- /en/dev/api.md: -------------------------------------------------------------------------------- 1 | # Telegram API VS Bot API. What Is the Difference? 2 | 3 | Basically, developing a bot means developing a program which connects to Telegram servers, receives some info (like 4 | incoming messages) and sends some instructions (like "reply to that message"). 5 | Let's dive into how it works. 6 | 7 | **MTProto API** (also known as **Telegram API**) is the API through which your mobile or desktop Telegram apps connect 8 | to the Telegram servers. It is open, meaning that developers can use the API to create own Telegram apps. 9 | 10 | It is named after MTProto encryption protocol which was specially developed by Telegram team. 11 | 12 | **Telegram Bot API** is a different API that can only be used for bots. It is built on top of MTProto API. 13 | 14 | Bot API was created to provide developers with a possibility of writing bots on plain HTTP-requests and not studying 15 | MTProto. 16 | In addition, Bot API has features to make development easier, such as webhooks and built-in HTML/Markdown markup. 17 | 18 | However, you won't need this :) 19 | 20 | You unlikely will write plain HTTP-requests: it is easier to use libraries instead. There are libraries for many 21 | programming languages and usually they have everything for convenient development. 22 | 23 | **So you can develop bots with either Telegram API or Bot API.** 24 | 25 | ## So which API to choose? 26 | 27 | On the one hand, it is easier to pick a library written in Bot API. 28 | 29 | On the other hand, Bot API is more limited. It forbids to [upload large files](../messages/sending#file-limits) 30 | by default or [fetch old messages from chat history](./updates#limitations). 31 | 32 | You can read about choosing the right library [on the next page](./libraries). 33 | 34 | { #api-difference } 35 | 36 | ::: details Functionality of Bot API vs Telegram API 37 | 38 | | Feature | Bot API | Telegram API | 39 | |---------------------------------------------|------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------| 40 | | **Fetching messages** | From [updates](./updates) only | From updates or by message IDs | 41 | | **Fetching users** | From updates only | From updates, by message IDs (if the bot ["saw"](../chats/pm#seen-users) the user) or by username (200 times a day) | 42 | | **File sizes** | ↓ 20 МБ, ↑ 50 МБ (Without [local server](https://core.telegram.org/bots/api#using-a-local-bot-api-server)) | Like regular users | 43 | | **Fetching group members** | No | Yes | 44 | | **Get old updates** | No | Yes | 45 | | **Run multiple programs with the same bot** | Only if other programs use Telegram API | [Yes](./updates#получение-апдеитов-несколько-раз) | 46 | 47 | Telegram API has a feature [to get some updates](https://core.telegram.org/api/updates#recovering-gaps). 48 | This may be useful to get a list of bot users if it was not saved or the database was lost. 49 | {#old-updates} 50 | 51 | ::: 52 | 53 | ## Userbots 54 | 55 | As Telegram API is open and has libraries that work with it, you can easily write a program that controls a user account 56 | rather than a bot. 57 | 58 | Such programs are called userbots. There are userbots that put current time on the user's profile picture, 59 | collect messages from public groups and channels, and so on. 60 | 61 | In general, userbots are useful to automate actions that users are allowed to do and bots aren't. 62 | 63 | ::: warning 64 | Usually Telegram doesn't ban for userbots, but be careful. Telegram may limit or delete spammer accounts. 65 | ::: 66 | 67 | ## Related links 68 | 69 | - [Telegram docs. Technical details of MTProto](https://core.telegram.org/mtproto) 70 | - [Telegram docs. Authorizing bots through Telegram API](https://core.telegram.org/api/bots) 71 | - [Telegram docs. Bot API reference](https://core.telegram.org/bots/api) 72 | - [Telegram docs. Telegram API methods](https://core.telegram.org/methods) 73 | - [Official Bot API channel with updates](https://t.me/BotNews) 74 | -------------------------------------------------------------------------------- /en/dev/basics.md: -------------------------------------------------------------------------------- 1 | # Introduction to Developing Telegram Bots 2 | 3 | Bot is a Telegram user account controlled by a server program. 4 | 5 | Bots can have dialogs with users, send messages, reply to commands 6 | from users, send pictures, be members of groups and channels, and so on. 7 | 8 | Still, bots have some limitations compared to real users, mainly in order to keep users' privacy. For example, bots 9 | can't join groups and have to be added by users. 10 | 11 | ::: info 12 | Although technically bots are users too, in this handbook I use the term "users" to refer to real users. 13 | ::: 14 | 15 | ## How to program a bot 16 | 17 | Short answer: 18 | 19 | 1. Register a bot. 20 | 2. Choose a library for your favorite programming language. 21 | 3. Write code with the help of the library docs and this handbook. 22 | 23 | Note that although you can run the bot program on your computer, you will want to use hosting when the code is ready. 24 | 25 | The next pages in "Development" section of the handbook describe these steps in details. 26 | 27 | ## Related links 28 | 29 | - [Telegram docs. How bots are different from users](https://core.telegram.org/bots#how-do-bots-work) 30 | -------------------------------------------------------------------------------- /en/dev/botfather.md: -------------------------------------------------------------------------------- 1 | # How to Set Up a Telegram Bot through BotFather 2 | 3 | ## Registration 4 | 5 | You can register a bot using [@BotFather](https://t.me/BotFather). 6 | 7 | Once you open BotFather, it will suggest you create a bot with the `/newbot` command. 8 | You will choose bot name and [username](./usernames) and then the bot profile will be created. 9 | 10 | You will obtain the bot token which looks like `1553279091:AAGLECcm23ihHRomX3PrKHc-IMQcIti6afA`. 11 | The token is a key to control the bot. 12 | 13 | ![Example of creating a bot](/pictures/ru/botfather.png) 14 | 15 | ## Settings 16 | 17 | In [@BotFather](https://t.me/BotFather), you can edit bot settings with the `/mybots` command. 18 | 19 | This is how you customize the bot profile and configure special features, such as 20 | forbidding being added to groups. 21 | 22 | One may register up to 20 bots. 23 | 24 | ### Customization { #customization } 25 | 26 | Open the `/mybots` menu, choose the bot and click `Edit bot`. Here are the settings that can be customized: 27 | 28 | ![Avatar, name, description and about](/pictures/ru/customization.png){ style="max-width: 480px" } 29 | 30 | Description is the text that users will see in before starting the dialog with the bot. 31 | It may contain a picture, possibly a GIF. 32 | { style="margin-top: 32px" } 33 | 34 | ::: tip 35 | Spend some time to fill the bot profile: that will be helpful and convenient for users. 36 | Add a profile picture to make the bot more distinguishable in the chat list. 37 | It may be a good idea to include your contacts in "About". 38 | ::: 39 | 40 | ::: info 41 | You can edit [command hints](../messages/commands) 42 | or [inline mode placeholder](../interaction/inline) from the same menu. 43 | ::: 44 | 45 | ### Transferring 46 | 47 | In BotFather's bot settings you can transfer the ownership to another person. 48 | For that, you must have 2FA enabled (for at least 7 days.) The other person should have started 49 | a dialog with the bot. 50 | -------------------------------------------------------------------------------- /en/dev/host.md: -------------------------------------------------------------------------------- 1 | # Running Your Telegram Bot on a Server 2 | 3 | ## Hosting 4 | 5 | You will likely need a server, because you will want to get your program running with a stable power and internet 6 | connection. 7 | 8 | For that, you will need to buy a host. Bot programs usually need a small amount of resources, so 9 | a simple plan from any hosting provider will probably be fine. 10 | 11 |
12 | This is a place for an ad of your cool hosting :) 13 |
14 | 15 | ## Long-polling vs webhooks 16 | 17 | Setting up a server depends on how your bot works. The default option is long-polling, meaning that the program 18 | regularly sends requests to the server to get new updates. But if you use Bot API, your program can alternatively 19 | be a webhook, meaning that Telegram servers will make requests to the program whenever there are updates. 20 | 21 | To set up a webhook, you will need to receive requests through a web application. For aiogram library, there 22 | are [built-in features](https://docs.aiogram.dev/en/latest/dispatcher/webhook.html) to integrate with aiohttp 23 | or any other asynchronous web framework. 24 | 25 | ## Free hosting 26 | 27 | If you are unable to pay for hosting, you can try [PythonAnywhere](https://www.pythonanywhere.com/) 28 | (which works unstably) or 29 | [Yandex Cloud Functions](https://cloud.yandex.ru/docs/functions/tutorials/telegram-bot-serverless). 30 | -------------------------------------------------------------------------------- /en/dev/libraries.md: -------------------------------------------------------------------------------- 1 | # How to Choose the Right Library for a Telegram Bot 2 | 3 | ## Bot API libraries 4 | 5 | A common choice for developing Telegram bots is a Python library called [aiogram](https://github.com/aiogram/aiogram). 6 | It is asynchronous, uses decorators and contains useful development tools. 7 | [Rocketgram](https://github.com/rocketgram/rocketgram) is a popular alternative. 8 | 9 | ::: details aiogram code example 10 | 11 | Here is some example code from [aiogram docs](https://docs.aiogram.dev/en/dev-3.x/). 12 | 13 | ```python 14 | import asyncio 15 | import logging 16 | import sys 17 | from os import getenv 18 | 19 | from aiogram import Bot, Dispatcher, Router, types 20 | from aiogram.enums import ParseMode 21 | from aiogram.filters import CommandStart 22 | from aiogram.types import Message 23 | from aiogram.utils.markdown import hbold 24 | 25 | # Bot token can be obtained via https://t.me/BotFather 26 | TOKEN = getenv("BOT_TOKEN") 27 | 28 | # All handlers should be attached to the Router (or Dispatcher) 29 | dp = Dispatcher() 30 | 31 | 32 | @dp.message(CommandStart()) 33 | async def command_start_handler(message: Message) -> None: 34 | """ 35 | This handler receives messages with `/start` command 36 | """ 37 | # Most event objects have aliases for API methods that can be called in events' context 38 | # For example if you want to answer to incoming message you can use `message.answer(...)` alias 39 | # and the target chat will be passed to :ref:`aiogram.methods.send_message.SendMessage` 40 | # method automatically or call API method directly via 41 | # Bot instance: `bot.send_message(chat_id=message.chat.ID, ...)` 42 | await message.answer(f"Hello, {hbold(message.from_user.full_name)}!") 43 | 44 | 45 | @dp.message() 46 | async def echo_handler(message: types.Message) -> None: 47 | """ 48 | Handler will forward receive a message back to the sender 49 | 50 | By default, message handler will handle all message types (like a text, photo, sticker etc.) 51 | """ 52 | try: 53 | # Send a copy of the received message 54 | await message.send_copy(chat_id=message.chat.ID) 55 | except TypeError: 56 | # But not all the types is supported to be copied so need to handle it 57 | await message.answer("Nice try!") 58 | 59 | 60 | async def main() -> None: 61 | # Initialize Bot instance with a default parse mode which will be passed to all API calls 62 | bot = Bot(TOKEN, parse_mode=ParseMode.HTML) 63 | # And the run events dispatching 64 | await dp.start_polling(bot) 65 | 66 | 67 | if __name__ == "__main__": 68 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 69 | asyncio.run(main()) 70 | ``` 71 | 72 | ::: 73 | 74 | JavaScript is often used as well: check out [Telegraf](https://github.com/telegraf/telegraf) 75 | or [GrammY](https://github.com/grammyjs/grammY). 76 | 77 | There are libraries for many other languages, too. The official site has 78 | [a list](https://core.telegram.org/bots/samples) and seems to keep it actual. 79 | 80 | ## Telegram API libraries 81 | 82 | If you want to use [Telegram API but not Bot API](./api), you should choose a library built on Telegram API. 83 | 84 | There are two such libraries for Python: [Telethon](https://github.com/LonamiWebs/Telethon) 85 | and [Pyrogram](https://github.com/pyrogram/pyrogram). For JavaScript, there is [GramJS](https://github.com/gram-js/gramjs). 86 | 87 | Telegram API libraries are handy if you want to write bots and 88 | [userbots](./api#юзерботы) without re-learning — that's why I prefer always using Telethon. 89 | -------------------------------------------------------------------------------- /en/dev/updates.md: -------------------------------------------------------------------------------- 1 | # Understanding Updates in Telegram Bot Development 2 | 3 | ## What are updates 4 | 5 | Updates are events that the bot program receives from Telegram server. 6 | There can be an update about an incoming message, an update about a user joining a group, and so on. 7 | 8 | I will often use this term further. 9 | 10 | ## The main challenge of developing bots { #limitations } 11 | 12 | **Updates are almost the only one way to get any info about chats, messages, and users.** 13 | 14 | Your program may not fetch the latest user's message or the list of chats where the bot belongs. 15 | Telegram only gives info about the current user or the current chat in updates: 16 | for example, when a user sends a message or the bot is added to the group. 17 | 18 | If you need a list of bot users, received messages, or anything similar, you should save this data. 19 | (You will likely need a database.) 20 | 21 | If you lose this info, you won't be able to get it again. 22 | 23 | ::: tip Telegram API 24 | You can fetch some info using Telegram API and not Bot API: 25 | for example, it is possible to get a message by its ID or the info about a user. 26 | You can see the full list [on the handbook's page on API](../dev/api#api-difference). 27 | ::: 28 | 29 | ## Receiving updates multiple times 30 | 31 | Bot API disallows getting updates multiple times. If you received an update in Bot API, 32 | you won't be able to receive it again. 33 | 34 | There is no such limitation in Telegram API though. This is due to the fact that Telegram API is mainly used for apps: 35 | clearly, a user can have multiple Telegram apps on multiple devices while each of them should receive new messages. 36 | The same works for bots: when you run multiple bot programs on Telegram API, they all get the new updates. 37 | Also, there is [a Telegram API trick](../dev/api#old-updates) to fetch old updates. 38 | -------------------------------------------------------------------------------- /en/dev/usernames.md: -------------------------------------------------------------------------------- 1 | # Claiming a Username for Your Bot 2 | 3 | When you register a bot, you should choose its username carefully. 4 | It will be difficult to change it afterwards. 5 | 6 | ## How should the username look 7 | 8 | Bot usernames are no different from usernames of users, groups and channels. 9 | The only constraint is that a username of a bot must end with "bot." 10 | 11 | A username can look like this: `@ExampleBot` 12 | 13 | There are official bots with special usernames that don't follow the 14 | form: [@pic](https://t.me/pic), [@vid](https://t.me/vid), [@sticker](https://t.me/sticker). Also, you can now buy short 15 | usernames on [Fragment](https://fragment.com/). 16 | 17 | ## Many usernames are taken 18 | 19 | A free username must contain at least 5 characters including "bot." 20 | However, you can't claim such a short username: all usernames of 5 (and maybe 6) characters are taken. 21 | 22 | Unfortunately, all these registered bots are mostly dead. Developers rarely support bots for a long time :( 23 | 24 | ## You can claim a short username through the support 25 | 26 | It is possible to change a bot username for free, even if it's claimed by another (inactive) bot. 27 | You will need to contact the support: [@BotSupport](https://t.me/BotSupport). They will check whether your bot works and 28 | supports 29 | English language. 30 | 31 | The common format is the following: 32 | 33 | ``` 34 | 1. @old_username 35 | 2. @new_username 36 | 3. Some bot description 37 | ``` 38 | 39 | Then cross your fingers and hope the support won't ignore you. 40 | -------------------------------------------------------------------------------- /en/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Telegram Bot Handbook 3 | titleTemplate: false 4 | --- 5 | 6 | 9 | 10 | # Telegram Bot Handbook 11 | 12 | Welcome to the language-agnostic handbook on developing Telegram Bots. 13 | Here, I tried to collect everything you need to plan and develop a stable bot. 14 | 15 | Unlike Telegram site, library docs, or various tutorials, this handbook makes easy 16 | to explore Telegram features and limitations. 17 | 18 | How to choose the library? How to set up commands so that users enter them easily? 19 | Why are chat IDs sometimes negative? 20 | What are strange bot restrictions in groups? How can a user start a dialog with bot but not send a message? 21 | 22 | This is what the handbook is about. You can think of it as an extensive overview on the Telegram bot platform. 23 | 24 | ::: info 25 | The English part of this site is a little bit work-in-progress. Screenshots and videos are still to be 26 | remade in English: I will hopefully do it one day. For now, 27 | I feel like the current version should be published or none ever will. 28 | ::: 29 | 30 | 31 | 32 | 33 | ## Before development 34 | 35 | I recommend you skim over the "Development" section before starting a bot. It covers working with API, 36 | choosing libraries, and other technical details. You may want to skim the following sections as well to have 37 | a better understanding of the Telegram features. 38 | 39 | If you plan to develop a bot with rather uncommon features or capacity, you should read the corresponding pages first. 40 | 41 | ## During development 42 | 43 | The handbook is designed to be consult 44 | 45 | You can consult the handbook to dive into the details of a topic. 46 | 47 | ## About 48 | 49 | The hanbook sources are open on GitHub. Corrections and improvements are welcome! 50 | 51 | Some pictures and videos are taken from the Telegram site. Most screenshots are made in Telegram web apps. 52 | 53 | [Artyom Ivanov](https://t.me/tm_a_t) wrote this and [Ivan Filipenkov](https://t.me/vanutp) consulted. 54 | -------------------------------------------------------------------------------- /en/interaction/html-games.md: -------------------------------------------------------------------------------- 1 | # HTML Games in Bots 2 | 3 | Bots can provide a feature of in-chat HTML games. 4 | 5 | A bot may send game messages or create them in [the inline mode](../interaction/inline). An example of such bot 6 | is official [@gamebot](https://t.me/gamebot). 7 | 8 | --- 9 | 10 | 13 | 14 | ## Related links 15 | 16 | - [Telegram docs. Bot Gaming Platform](https://core.telegram.org/bots/games) 17 | -------------------------------------------------------------------------------- /en/interaction/inline.md: -------------------------------------------------------------------------------- 1 | # Implementing Inline Mode in Telegram Bots 2 | 3 | Inline mode is a feature of sending messages "via bots". 4 | When a bot supports the inline mode, a user can access it from any chat to send a message generated by the bot. 5 | The inline mode works even in chats where the bot does not participate. 6 | 7 | For example, this allows bot users to quickly search for videos or music and instantly send it. 8 | 9 | A user starts the inline mode by entering bot username and a space. They may add a text query afterwards 10 | if needed; the query can contain up to 256 characters. Then, the menu of results appears. 11 | The user clicks on a result to send the message. 12 | 13 | 16 | 17 | A developer can enable inline mode in BotFather, as well as select a placeholder (the default is "Search...") 18 | 19 | Group admins may forbid everyone or selected users sending inline messages. In the official Telegram apps, 20 | this group member restriction is united with the restriction to send stickers and GIFs. 21 | 22 | ## Result layout 23 | 24 | The results may form a grid (which looks well in case of pictures) 25 | or a vertical list (which looks good in case of text). 26 | 27 | ![Grid](/pictures/ru/inline-type-1.png) 28 | 29 | ![List](/pictures/ru/inline-type-2.png) 30 | 31 | Two layouts may be combined, but apparently this works correctly only in Telegram Desktop 32 | (while other official apps show such results in a list.) 33 | 34 | ::: details Combination screenshot 35 | ![Combining two layouts](/pictures/ru/inline-both-types.png){style="max-width: 400px"} 36 | ::: 37 | 38 | ## Inline feedback 39 | 40 | Inline feedback is updates arriving when a user chooses an inline result and sends a message. 41 | You will not receive them unless you explicitly turn on this setting in BotFather. 42 | 43 | Although the purpose of the inline feedback feature is collecting statistics, bot developers 44 | sometimes use it to edit messages after they are sent. This comes handy when the bot should load only 45 | the selected result rather then all of them. For example, a music search bot may 46 | [add a song](../messages/sending#edit-media) to a sent message and not load all songs during the search. 47 | 48 | Here is a trick: a bot may edit a sent inline message only if it contains inline buttons. 49 | (Otherwise, the inline feedback update does not include the message ID.) 50 | 51 | ![BotFather setting to select a percent of incoming updates](/pictures/ru/inline-feedback.png) 52 | 53 | ## Related links 54 | 55 | - [Telegram site. Inline queries](https://core.telegram.org/bots/features#inline-requests) -------------------------------------------------------------------------------- /en/interaction/join-requests.md: -------------------------------------------------------------------------------- 1 | # Managing Join Requests as a Telegram Bot 2 | 3 | When a user joins a group or a channel with a link, admin approval may be required. In this case, 4 | the user doesn't become a member immediately but leaves a join request. 5 | 6 | Admins may approve or decline join requests from the list. Bots with admin rights may do this as well. 7 | 8 | ## When a join request is left 9 | 10 | - **When the group requires admin approval.** 11 | 12 | Admins can turn on this setting in groups with usernames or groups linked to channels. 13 | 14 | - **When the invite link requires approval.** 15 | 16 | A group or a channel may have multiple invite links created by admins. Besides the usage limit and the duration limit, 17 | such links may have an approval requirement. 18 | 19 | Bots with admin rights can create invite links, too. 20 | 21 | ## Bots and join requests 22 | 23 | If bot is a group admin, it receives updates every time a user leaves a join request. 24 | The admin right to add members allows the bot to approve or decline the requests. 25 | 26 | Moreover, the bot can PM those who left join requests. 27 | 28 | ## Related links 29 | 30 | - [Telegram blog. How join requests look](https://telegram.org/blog/shared-media-scrolling-calendar-join-requests-and-more#join-requests-for-groups-and-channels) 31 | -------------------------------------------------------------------------------- /en/interaction/links.md: -------------------------------------------------------------------------------- 1 | # Creating Links to Bots 2 | 3 | ## Regular links 4 | 5 | Links to bots ar similar to links to users, groups, and channels: 6 | the link [t.me/examplebot](https://t.me/examplebot) opens the bot with the username `@examplebot`. 7 | 8 | There is also a direct link: 9 | [tg://resolve?domain=examplebot](tg://resolve?domain=examplebot) 10 | 11 | ::: info About tg:// links 12 | 13 | Links starting with tg:// may replace t.me links or do special actions. 14 | For example, the link [tg://settings](tg://settings) opens settings in Telegram apps. 15 | 16 | Such links are listed [in API documentation](https://core.telegram.org/api/links) and 17 | in the unofficial [@DeepLink](https://t.me/deeplink) channel. 18 | 19 | ::: 20 | 21 | ## Deep links 22 | 23 | Deep link is a link of form [t.me/examplebot?start=YOUR_TEXT](https://t.me/examplebot?start=ВАШ_ТЕКСТ). They are used to start a dialog with the bot 24 | with some initial parameters. 25 | 26 | This works as following. Once a user visits a deep link, they see a dialog with the bot and the "Start" button 27 | (even if they have already [started the dialog](../chats/pm)). A click on the button sends `/start YOUR_TEXT`. 28 | The user, however, sees only `/start`, like if starting the bot regularly. 29 | 30 | 33 | 34 | Deep links are often used for referral programs: for example, the parameter can be ID of the user who shared the link. 35 | 36 | The direct link is similar: [tg://resolve?domain=examplebot&start=YOUR_TEXT](tg://resolve?domain=examplebot&start=ВАШ_ТЕКСТ) 37 | 38 | ## Deep links for groups 39 | 40 | There are deep links for groups as well.. 41 | 42 | The link of form [t.me/examplebot?startgroup=YOUR_TEXT](https://t.me/examplebot?startgroup=ВАШ_ТЕКСТ) opens a chat selection dialog to add the bot; 43 | once the bot is added, the command `/start YOUR_TEXT` will immediately be sent to the group. 44 | 45 | The direct link: [tg://resolve?domain=examplebot&startgroup=true](tg://resolve?domain=examplebot&startgroup=true) 46 | 47 | ## Related links (not deep ones) 48 | 49 | - [Telegram docs on deep links](https://core.telegram.org/bots/features#deep-linking) 50 | -------------------------------------------------------------------------------- /en/interaction/login-widget.md: -------------------------------------------------------------------------------- 1 | # Telegram Login Widget 2 | 3 | Your site may feature a "Log in with Telegram" button. 4 | 5 | The button must be linked to your bot. The button may be configured in such way that 6 | authorizing users will see an "Allow the bot contact me" check box. 7 | 8 | An alternative to Telegram Login Widget is [Login URL button](../messages/buttons), a way to authorize on a site from the Telegram app. 9 | 10 | ## User steps 11 | 12 | 1. The user clicks "Log in with Telegram" and enters their phone number. 13 | 2. Telegram app asks to confirm. 14 | 3. The user chooses "Accept" and logs in. 15 | 16 | ![Screenshot](https://core.telegram.org/file/811140314/17c1/xf4ULBL5tmE.58438/07ff5b2958ed0e7e36) 17 | 18 | ## Related links 19 | 20 | - [Telegram docs. Login Widget](https://core.telegram.org/widgets/login) -------------------------------------------------------------------------------- /en/interaction/mini-apps.md: -------------------------------------------------------------------------------- 1 | # Telegram Mini Apps 2 | 3 | Mini Apps (formerly Web Apps) are a feature of integrating a web page into the bot. 4 | 5 | The documentation describes this extensively: https://core.telegram.org/bots/webapps 6 | 7 | For example, this feature is used by semi-official bot [@Wallet](https://t.me/wallet). 8 | 9 | --- 10 | 11 | 14 | 15 | ## Related links 16 | 17 | - [Telegram docs. Mini Apps](https://core.telegram.org/bots/webapps) 18 | -------------------------------------------------------------------------------- /en/interaction/payments.md: -------------------------------------------------------------------------------- 1 | # Processing Payments Through Telegram Bots 2 | 3 | Bots can receive payments from users. 4 | 5 | Payments are processed with a [provider](https://core.telegram.org/bots/payments#supported-payment-providers) like Stripe. 6 | The providers work in different countries and have different requirements; 7 | your bot may use different providers depending on users. 8 | 9 | ![Example of a message with payment](https://core.telegram.org/file/464001393/101fc/SB_bFCLR0tg.130549/7ecf91aaa44737e8cb) 10 | 11 | ## User interface 12 | 13 | You can try the payment interface in [the Demo Store channel](https://t.me/TestStore). 14 | 15 | A bot can send invoice messages to any chats, even from [inline-mode](../interaction/inline). 16 | The first [button](../messages/buttons#inline) under the message must be a "Buy" button. 17 | 18 | ## Related links 19 | 20 | - [Telegram docs. Payments](https://core.telegram.org/bots/payments) 21 | -------------------------------------------------------------------------------- /en/interaction/stickers.md: -------------------------------------------------------------------------------- 1 | # Managing Sticker Sets and Custom Emoji Sets 2 | 3 | Bots (and only bots) can create sticker sets and custom emoji sets. Each pack must have a user specified as its owner. 4 | 5 | A common way for people to create and manage sticker sets is through [@Stickers](https://t.me/stickers) bot, 6 | but other bots can do it as well. 7 | 8 | Bots are able to create, rename, edit, and delete sets. 9 | 10 | ::: info Custom emoji 11 | Only premium users may use custom emoji from sets. Nevertheless, custom emoji sets can be created 12 | by any bots and owned by any users. 13 | ::: 14 | 15 | ## Formats 16 | 17 | Sticker sets and custom emoji set may be static (PNG or WEBP), video (WEBM), or animated (in a special format based on 18 | Lottie). 19 | Furthermore, a set of single color emoji may be adaptive, meaning that users will see it in the same color as the text 20 | regardless of their color theme. 21 | 22 | ## Related links 23 | 24 | - [Telegram site. Sticker requirements](https://core.telegram.org/stickers) 25 | - [Telegram docs. Creating stickers and custom emoji](https://core.telegram.org/bots/features#stickers-and-custom-emoji) 26 | -------------------------------------------------------------------------------- /en/messages/buttons.md: -------------------------------------------------------------------------------- 1 | # Buttons in Telegram Bots 2 | 3 | There are two types of buttons that bots can show when sending messages: inline buttons 4 | (which are shown below the sent message) or keyboard buttons (which are shown next to the message input.) 5 | 6 | ## Inline buttons { #inline } 7 | 8 | Inline buttons are shown together with the messages. 9 | 10 | ### Callback button 11 | 12 | When a callback button gets pressed, the bot receives [an update](../dev/updates); 13 | then the bot can can edit a message or react in any other way. 14 | 15 | A special action that the bot can do when the button pressed is showing a notification or an alert. 16 | 17 | When receiving the updates, the program can identify the pressed button by a special parameter which is specified 18 | while creating the button. 19 | 20 | 23 | 24 | ### URL button 25 | 26 | A button that acts like a link. 27 | 28 | In Bot API, such button turns into a [user mention](./markup#mention) button if you specify `tg://user?ID=123456789` 29 | as the URL. In Telegram API, user mention button is built in a separate way. 30 | 31 | ![Link below the message](/pictures/ru/url-button.png) 32 | 33 | ### Switch-to-inline button 34 | 35 | A button that opens [bot inline mode](../interaction/inline). You can choose whether this button 36 | will open inline mode in the same chat or open a chat selection dialog first. You can also choose the text query which 37 | will show next to the bot username after the button is clicked (the user may change it afterwards.) 38 | 39 | 42 | 43 | ### Request peer button 44 | 45 | A button that allows the user to send a bit of info about any of their chats. When clicked, it shows a chat selection 46 | dialog. 47 | 48 | You can configure this button flexibly: for example, the chat selection may include only channels with usernames or groups 49 | where the user is an admin. 50 | 51 | ### Other inline butons 52 | 53 | There are more, rather uncommon, buttons: 54 | 55 | - Callback game button. Opens an [HTML game](../interaction/html-games). 56 | - Pay button. Used for [integrated payments](../interaction/payments). 57 | - Web view button. Opens [bot web interface](../interaction/mini-apps). 58 | - Login URL button. Used for authorization on sites. 59 | For example, official [@discussbot](https://t.me/discussbot) utilized it before native comments appeared in Telegram. 60 | The button works similarly to [Telegram Login Widget](../interaction/login-widget) but doesn't require to enter 61 | the phone number and confirm the authorization. 62 | 63 | ## Keyboard buttons 64 | 65 | The second type of buttons is the keyboard buttons. Unlike inline buttons, they are shown below the message input field 66 | (in web versions they are expanded when clicked on ⌘). When pressing a keyboard button, the user simply sends its text. 67 | 68 | In Telegram mobile apps, keyboard buttons replace the keyboard; however, the user is able to hide them and see 69 | the regular keyboard again. 70 | 71 | 74 | 75 | Apart from sending the text, a keyboard button may do one of the following: 76 | 77 | - Ask the account phone number. 78 | - Ask the user's geolocation. 79 | - Open a poll creation menu. 80 | 81 | Of course, these actions require confirmation from the user. 82 | 83 | There is a "resize keyboard" option which determines whether the button keyboard should have flexible height. 84 | For some reason it is off by default, so the buttons look stretched: 85 | 86 | ![](/pictures/ru/wide-buttons.png) 87 | 88 | Keyboard buttons can be shown only with sending a message. 89 | A bot can send keyboard buttons that will hide (but not disappear) after use. 90 | 91 | In groups, keyboard buttons are visible to all members by default. Alternatively, a bot can show 92 | a set of buttons only to mentioned users, that are: 93 | 94 | - The ones whose usernames are included in the message text. 95 | - The sender of the message to which the bot is replying. 96 | 97 | ## Button layouts 98 | 99 | Both inline buttons and keyboard buttons may be aligned in multiple rows. 100 | 101 | A row may contain up to 8 buttons. The total limit of buttons shown at once is 100. 102 | 103 | If you place multiple buttons in a row, you should make sure that their labels look OK in the mobile apps: 104 | the long labels get truncated. 105 | -------------------------------------------------------------------------------- /en/messages/commands.md: -------------------------------------------------------------------------------- 1 | # Mini-Guide on Implementing Telegram Bot Commands 2 | 3 | A common way to interact with bots is through commands. Commands start with “/” and consist of latin letters, digits, 4 | and underscores. 5 | 6 | The commands are highlighted similarly to links. A user can tap on a command to send it. 7 | 8 | ![An example of using commands](/pictures/ru/commands.png) 9 | 10 | ## Commands in groups 11 | 12 | To distinguish commands for different bots in groups, Telegram suggests ending commands with bot usernames. For example, 13 | `/start@examplebot` 14 | 15 | When a user clicks on a command in a bot message, they will automatically send a command with bot username appended. 16 | 17 | A bot [can't see](../chats/groups#privacy) commands ending with other usernames. 18 | 19 | ## Command lists 20 | 21 | Through BotFather, a bot developer can specify a list of command hints with short descriptions. 22 | In this case, whenever a user starts typing a command in chat with the bot, they will see autocomplete menu. 23 | 24 | ![An example of autocomplete with commands from multiple bots](/pictures/ru/commands-autocomplete.png) 25 | 26 | In addition, users will see a "menu" button in personal dialogs and groups with the bot. The button 27 | will open the autocomplete menu. 28 | 29 | If there is `/help` in the command list, a "Help with bot" button which sends this command appears in bot profile. 30 | Similarly, `/settings` command creates a "Settings" button and `/privacy` creates a "Privacy policy" button. 31 | 32 | Alternative way to specify command hints is through API. This way, a bot may show different menus depending 33 | on users and groups. The menus can also depend on user language 34 | (which is convenient for localizing command descriptions) or user admin status 35 | (which can be used for group moderation features.) 36 | 37 | ## Command arguments 38 | 39 | It is not forbidden to ask users to enter additional text after a command, like `/weather London`. 40 | 41 | However, it's difficult for users to enter commands such way. If a user chooses a command in the auto-completion menu, they normally send it immediately. 42 | To complete the command but not send it, a user should press tab key in the desktop apps or long-tap the command 43 | in case of the mobile apps. This is a feature of which many users are not aware. 44 | 45 | Telegram recommends implementing specific commands that can be used without arguments. 46 | 47 | If this is not a way for you, you can consider other ways of interaction. 48 | [Buttons](../messages/buttons) or [inline mode](../interaction/inline) may fit for selecting from multiple options. 49 | For some additional information from the user, the bot can simply ask a question in the next message. 50 | -------------------------------------------------------------------------------- /en/messages/id.md: -------------------------------------------------------------------------------- 1 | # How Message IDs Work 2 | 3 | Each Telegram message has an ID. This includes system messages 4 | like "A user entered the chat" or "A chat title has changed". 5 | 6 | Message IDs in [supergroups](../chats/supergroups) and channels are unique per chat: the first chat message has ID 1, 7 | the second message has ID 2, and so on. 8 | 9 | Messages in personal dialogs and regular groups are numbered consequently: message IDs are counted separately for 10 | a user (or a bot.) 11 | The first received or sent messages in all PMs and groups has ID 1, the second one has ID 2, and so on. 12 | 13 | ::: info 14 | A bot can retrieve a message by its ID through Telegram API. Bot API doesn't provide such feature. 15 | ::: 16 | -------------------------------------------------------------------------------- /en/messages/markup.md: -------------------------------------------------------------------------------- 1 | # Extensive Text Formatting in Telegram Messages 2 | 3 | Bot API allows specifying message markup in HTML or Markdown. Telegram API libraries like Telethon and Pyrogram 4 | usually support similar syntax. 5 | 6 | Message text may include various markup: 7 | 8 | - **Bold text** 9 | - _Italic text_ 10 | - Underlined text 11 | - Strikethrough text 12 | - `Monospaced text` 13 | - [Links](#) 14 | - Spoilers, which mean hidden text 15 | - User mentions through their ID 16 | - Custom emoji (which are available only for bots with [paid usernames](../dev/usernames)) 17 | 18 | A message may contain no more than 100 such markup elements (more will be ignored.) 19 | 20 | In addition, a message may contain any number of username mentions. 21 | 22 | ## Monospaced text 23 | 24 | Monospaced can be a piece of text (similar to `` in HTML) or a block (similar to `
`).
25 | 
26 | When sending a monospaced text block, you can specify code language so that Telegram apps will apply syntax highlighting.
27 | 
28 | ## Spoiler
29 | 
30 | A spoiler is some text hidden behind an animated cover.
31 | 
32 | Pictures can be hidden with a spoiler as well, though this is not related to message markup.
33 | 
34 | ![text and picture behind the spoilers](/pictures/ru/spoiler.png)
35 | 
36 | ## User mentions { #mention }
37 | 
38 | A mention is clickable text which leads to a user profile. To insert a mention using Bot API, one can embed a link 
39 | of form `tg://user?ID=123456789`. A username of a user turns into a mention automatically.
40 | 
41 | When a group member gets mentioned, they get a notification. However, if a message contains more than five mentions,
42 | only five users will get such notifications.
43 | 
44 | Bot may mention a user through ID only if they participate in the current chat or have turned on linking them 
45 | while forwarding their messages. In addition, a bot must [have seen](../chats/pm#seen-users) the user.
46 | 
47 | Username mentions are technically regular text. When a user clicks on 
48 | a username mention, Telegram app fetches info about the username owner.
49 | On contrary, when sending ID mentions, the sender specifies the mentioned user ID which becomes a part of the message.
50 | Recipients get the user profile together with the message, so the mention will be clickable even if the user changes 
51 | its username.
52 | 
53 | ## Related links
54 | 
55 | - [Bot API docs on markup](https://core.telegram.org/bots/api#formatting-options)
56 | 


--------------------------------------------------------------------------------
/en/messages/sending.md:
--------------------------------------------------------------------------------
 1 | # Telegram Bots Sending, Editing, and Forwarding Messages
 2 | 
 3 | This page collects some tips about Telegram messages and related limitations.
 4 | It may be a good idea to make sure that your bot works correctly in the described edge cases.
 5 | 
 6 | ## Sending messages
 7 | 
 8 | Bots can send and receive messages just like users. Those can be either just text messages or messages with media: 
 9 | pictures, videos, files, polls, voice messages, stickers, and so on.
10 | 
11 | Unlike users, bots may also add [buttons](../messages/buttons) to its messages.
12 | 
13 | ### What are albums?
14 | 
15 | An album is multiple messages with pictures which are displayed like one message in Telegram apps.
16 | 
17 | ### What are the file limits? { #file-limits }
18 | 
19 | Telegram allows sharing files up to 4 GB; however, Bot API has more strict limits. Through Bot API, a bot can download 
20 | files up to 20 MB and upload files up to 50 MB. If you use [a local Bot API server](../dev/api#api-difference) though, these limits extend up 
21 | to 2 GB.
22 | 
23 | ### How frequently can a bot send messages?
24 | 
25 | Of course, Telegram won't let you spam. The following average limits are named:
26 | 
27 | - No more than a message per second in a chat.
28 | - No more than 30 messages per second in all chats.
29 | - No more than 20 messages per minute in a group.
30 | 
31 | There is no such option as sending messages to all users at once. If you want to broadcast some information among all 
32 | bot users, you'll have to send messages gradually.
33 | 
34 | Note that the limits concerning more rare actions, such as editing or deleting messages, are more strict.
35 | 
36 | Developers of popular bots can contact the tech support and ask to increase the limits.
37 | 
38 | ### When is it forbidden to send messages?
39 | 
40 | A bot may not send messages to a user who [blocked it](../chats/pm#block). 
41 | A bot may not send messages in a channel or group where the bot is not a member or the admins have restricted sending messages.
42 | 
43 | Premium users can forbid sending voice messages to them (including those round videos.)
44 | 
45 | ## Editing
46 | 
47 | Unlike users, when bot edits a message, the note "Edited" does not appear on a message.
48 | 
49 | ### How to edit media? { #edit-media }
50 | 
51 | While editing a message, one can edit its media as well as the text.
52 | 
53 | A picture, video, or file can be replaced with another picture, video, or file (music counts as files too.)
54 | 
55 | Media can't be added to messages sent without media.
56 | 
57 | ## Forwarding
58 | 
59 | When one forwards a music file, it doesn't get the "Forwarded" label. Strange Telegram rules.
60 | 
61 | It is not allowed to forward messages from groups and channels with the "protected content" setting turned on.
62 | 
63 | ## Related links
64 | 
65 | - [Bot FAQ. Answer about limits](https://core.telegram.org/bots/faq#my-bot-is-hitting-limits-how-do-i-avoid-this)
66 | 


--------------------------------------------------------------------------------
/en/unlisted/official-bots.md:
--------------------------------------------------------------------------------
 1 | # List of Official Telegram Bots
 2 | 
 3 | Collected by @vanutp.
 4 | 
 5 | ```
 6 | @asmico_attach_bot
 7 | @bing
 8 | @bold
 9 | @BotFather
10 | @Channel_Bot
11 | @ContestBot
12 | @dadadsa
13 | @design_bot
14 | @discussbot
15 | @donate
16 | @DurgerKingBot
17 | @EURegulation
18 | @gamebot
19 | @gdprbot
20 | @gif
21 | @GmailBot
22 | @imdb
23 | @jobs_bot
24 | @like
25 | @mainbot
26 | @MTProxybot
27 | @pic
28 | @PremiumBot
29 | @PremiumJoinBot
30 | @PressBot
31 | @previews
32 | @Qqqqqqqqqqqqq
33 | @QuizBot
34 | @replies
35 | @SpamBot
36 | @sticker
37 | @Stickers
38 | @tdlib_bot
39 | @TelegramDonate
40 | @telegraph
41 | @tgx_bot
42 | @TonMobile
43 | @UnsupportedUser64Bot
44 | @username_bot
45 | @VerifyBot
46 | @vid
47 | @vote
48 | @wallet
49 | @WebpageBot
50 | @wiki
51 | @youtube
52 | id 470000 (Volunteer Support)
53 | ```
54 | 


--------------------------------------------------------------------------------
/index.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Telegram Bot Handbook
 3 | titleTemplate: false
 4 | sidebar: false
 5 | aside: false
 6 | lastUpdated: false
 7 | editLink: false
 8 | next: false
 9 | ---
10 | 
11 | # Telegram Bot Handbook
12 | 
13 | [Russian version →](/ru/)
14 | 
15 | [English version →](/en/)
16 | 


--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | [[redirects]]
2 | from = "/"
3 | to = "/en/"
4 | force = true
5 | 


--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "devDependencies": {
 3 |     "vitepress": "^1.0.0-rc.14"
 4 |   },
 5 |   "scripts": {
 6 |     "docs:dev": "vitepress dev",
 7 |     "docs:build": "vitepress build",
 8 |     "docs:preview": "vitepress preview"
 9 |   }
10 | }


--------------------------------------------------------------------------------
/public/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/android-chrome-192x192.png


--------------------------------------------------------------------------------
/public/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/android-chrome-512x512.png


--------------------------------------------------------------------------------
/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/apple-touch-icon.png


--------------------------------------------------------------------------------
/public/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/favicon-16x16.png


--------------------------------------------------------------------------------
/public/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/favicon-32x32.png


--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/favicon.ico


--------------------------------------------------------------------------------
/public/logo-dark.svg:
--------------------------------------------------------------------------------
1 | 
2 | 
3 | 
4 | 
5 | 


--------------------------------------------------------------------------------
/public/logo.svg:
--------------------------------------------------------------------------------
1 | 
2 | 
3 | 
4 | 
5 | 


--------------------------------------------------------------------------------
/public/pictures/other/syntax.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/other/syntax.mp4


--------------------------------------------------------------------------------
/public/pictures/ru/admin-rights.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/admin-rights.png


--------------------------------------------------------------------------------
/public/pictures/ru/bot-profile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/bot-profile.png


--------------------------------------------------------------------------------
/public/pictures/ru/botfather.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/botfather.png


--------------------------------------------------------------------------------
/public/pictures/ru/callback-buttons.webm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/callback-buttons.webm


--------------------------------------------------------------------------------
/public/pictures/ru/channel-buttons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/channel-buttons.png


--------------------------------------------------------------------------------
/public/pictures/ru/commands-autocomplete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/commands-autocomplete.png


--------------------------------------------------------------------------------
/public/pictures/ru/commands.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/commands.png


--------------------------------------------------------------------------------
/public/pictures/ru/customization.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/customization.png


--------------------------------------------------------------------------------
/public/pictures/ru/forum.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/forum.png


--------------------------------------------------------------------------------
/public/pictures/ru/friedrich.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/friedrich.png


--------------------------------------------------------------------------------
/public/pictures/ru/highlighter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/highlighter.png


--------------------------------------------------------------------------------
/public/pictures/ru/inline-both-types.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/inline-both-types.png


--------------------------------------------------------------------------------
/public/pictures/ru/inline-feedback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/inline-feedback.png


--------------------------------------------------------------------------------
/public/pictures/ru/inline-type-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/inline-type-1.png


--------------------------------------------------------------------------------
/public/pictures/ru/inline-type-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/inline-type-2.png


--------------------------------------------------------------------------------
/public/pictures/ru/inline.webm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/inline.webm


--------------------------------------------------------------------------------
/public/pictures/ru/keyboard-buttons.webm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/keyboard-buttons.webm


--------------------------------------------------------------------------------
/public/pictures/ru/privacy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/privacy.png


--------------------------------------------------------------------------------
/public/pictures/ru/spoiler.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/spoiler.png


--------------------------------------------------------------------------------
/public/pictures/ru/start.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/start.gif


--------------------------------------------------------------------------------
/public/pictures/ru/start.webm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/start.webm


--------------------------------------------------------------------------------
/public/pictures/ru/switch-inline-button.webm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/switch-inline-button.webm


--------------------------------------------------------------------------------
/public/pictures/ru/url-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/url-button.png


--------------------------------------------------------------------------------
/public/pictures/ru/wide-buttons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/pictures/ru/wide-buttons.png


--------------------------------------------------------------------------------
/public/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tm-a-t/telegram-bot-handbook/5ea7dcb9fca69d40fb82fd8095f8b6143bedbe08/public/screenshot.png


--------------------------------------------------------------------------------
/public/site.webmanifest:
--------------------------------------------------------------------------------
1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}


--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
 1 | 
2 |
3 | 4 | 5 |
6 | 7 |
8 |       9 |
10 | 11 | # Telegram Bot Handbook 12 | 13 | Developing reliable Telegram bots: features, limitations, tricks. 14 | 15 | **English: https://handbook.tmat.me/en/**    **Russian: https://handbook.tmat.me/ru/** 16 | 17 |
18 | 19 |   20 | 21 |   22 | 23 | 24 | 25 | ![](public/screenshot.png) 26 | 27 | 28 | -------------------------------------------------------------------------------- /ru/chats/channels.md: -------------------------------------------------------------------------------- 1 | # Чем Телеграм-боты могут быть полезны в каналах 2 | 3 | Боты могут выполнять действия админов в каналах: отправлять и изменять посты, переименовывать каналы и так далее. 4 | 5 | Добавить бота в канал можно только как администратора. 6 | 7 | ## Права администратора 8 | 9 | Когда пользователь добавляет бота в канал, открывается меню установки прав админа для этого бота. 10 | 11 | В настройках бота в BotFather можно выбрать, какие права в этом случае предлагать включить по умолчанию. 12 | 13 | ## Добавление кнопок под постами 14 | 15 | Самый частый способ использования ботов в каналах — 16 | добавление под постами кнопок лайков, ссылок и прочего. 17 | 18 | Это работает так. Среди прав, которые можно выдать админам в каналах, есть «редактирование чужих публикаций». 19 | Боты с этим правом могут редактировать посты, добавляя к ним кнопки. 20 | 21 | Вот так, например: 22 | 23 | ![Пост с кнопками](/pictures/ru/channel-buttons.png) 24 | -------------------------------------------------------------------------------- /ru/chats/forums.md: -------------------------------------------------------------------------------- 1 | # Разработка Телеграм-бота для форумов 2 | 3 | Форумы — это группы, разделённые на несколько веток. 4 | 5 |
6 | 7 |
8 | 9 | ![Форум](/pictures/ru/forum.png) 10 | 11 |
На картинке открыт список веток форума, а другие чаты свернулись в узкую колонку.
12 |
13 | 14 | ## С технической точки зрения 15 | 16 | Форум — это обычная группа, но с другим интерфейсом. Чтобы посмотреть его как обычный чат, используйте меню форума 17 | в официальных приложениях Телеграма (в таком виде для удобства над каждым сообщением в приложении показана ветка, куда 18 | оно попало). 19 | 20 | С технической точки зрения ветки устроены так. 21 | 22 | Когда создаётся ветка, появляется системное сообщение вида «Создана ветка». Все ответы на него попадают в эту ветку. 23 | 24 | ID ветки — это и есть ID её системного сообщения. 25 | 26 | Ветка #general — это основная ветка, куда попадают все остальные сообщения. Она имеет ID 1. 27 | 28 | ## Как это использовать 29 | 30 | Если ваш бот работает в группах, то, скорее всего, вам следует учесть, что группа может быть форумом. Например, если 31 | пользователь использовал команду, то вы должны ответить в той же ветке — иначе сообщение попадёт в #general. 32 | 33 | ## Управление ветками 34 | 35 | Боты, как и юзеры, могут открывать, изменять и закрывать ветки. В зависимости от настроек форума для этого может 36 | понадобиться специальное право админа. 37 | -------------------------------------------------------------------------------- /ru/chats/groups.md: -------------------------------------------------------------------------------- 1 | # Разработка Телеграм-бота для групп 2 | 3 | Бота можно добавить в группу; самостоятельно боты вступать в группы не могут. Разработчик может запретить 4 | добавление бота в группы в настройках [в BotFather](../dev/botfather). 5 | 6 | В публичную группу — группу с юзернеймом — ботов могут добавлять только админы. Боту можно дать права администратора в 7 | группе, чтобы он мог выполнять действия админов: например, удалять пользователей. 8 | 9 | В одной группе может быть до 20 ботов. 10 | 11 | ![Пример бота для подсветки синтаксиса, работающего в группах](/pictures/ru/highlighter.png) 12 | 13 | ## Privacy mode — видимость сообщений { #privacy } 14 | 15 | Обычно бот должен реагировать только на [команды](../messages/commands). 16 | Телеграм не уведомляет бота об остальных сообщениях, 17 | и это гарантирует приватность переписки для участников чата. 18 | 19 | Тем не менее некоторым ботам необходимо видеть другие сообщения в группе: например, если это чатбот или антиспам-бот. 20 | Разработчики таких ботов могут отключить privacy mode. 21 | 22 | Privacy mode — настройка в BotFather, которая по умолчанию включена. В этом режиме бот в группах видит только 23 | те сообщения, которые могут быть обращены к нему: 24 | 25 | - [команды](../messages/commands); 26 | - ответы на сообщение бота, ответы на ответы и так далее, 27 | - сообщения с [упоминанием бота](../messages/markup#упоминание-пользователя); 28 | - системные сообщения. 29 | 30 | Если бот — админ в группе, то он видит все сообщения, даже если privacy mode включён. 31 | 32 | Боты с отключённым privacy mode могут видеть все сообщения в группе, кроме сообщений от других ботов. 33 | 34 | ![Пример бота, который видит не все сообщения](/pictures/ru/friedrich.png) 35 | 36 | ::: tip Не получается отключить privacy mode? 37 | Если вы отключили privacy mode, бота нужно удалить из группы и добавить обратно, чтобы изменения вступили в силу. 38 | ::: 39 | 40 | В мобильных и десктопном приложениях Телеграма в списке участников группы видно, включён ли privacy mode: 41 | 42 | ![Пример бота](/pictures/ru/privacy.png){ style="margin: 0 auto" } 43 | 44 | ::: info Force reply {#force-reply} 45 | 46 | Если бот с privacy mode спросил что-либо у участника группы, то сообщение участника должно быть ответом 47 | на сообщение бота, чтобы бот его увидел. 48 | 49 | Для того чтобы не заставлять пользователя нажимать «Ответить», 50 | бот может отправить сообщение с force reply. В этом случае у пользователя автоматически начнётся ответ, как если бы 51 | он нажал «Ответить». 52 | 53 | Но я не рекомендую использовать force reply, потому что автоматический ответ на сообщения сбивает пользователей 54 | с толку. 55 | ::: 56 | 57 | ## Права администратора 58 | 59 | Когда пользователь назначает бота админом чата, он может выбрать, какие права админа ему дать. В настройках BotFather 60 | можно выбрать, какие права в таком случае предлагать включать по умолчанию. 61 | 62 | Право админа на анонимность — способность отправлять сообщения от лица группы — не действует на ботов. 63 | 64 | ![Выбор прав](/pictures/ru/admin-rights.png) 65 | 66 | ## Отправка сообщений участникам 67 | 68 | Сообщения в группе видны всем. Бот не может показать сообщение только одному пользователю, в том числе 69 | поприветствовать нового участника. 70 | 71 | Чтобы не засорять чат, ваш бот может удалять временные сообщения спустя время. Если же бот должен писать в личку 72 | вступающим в группу участникам, для этого могут пригодиться [заявки на вступление](../interaction/join-requests). 73 | 74 | ## Сообщения от лица групп и каналов 75 | 76 | При разработке ботов для групп учитывайте, что сообщения в группах могут приходить не только от лица пользователей, но 77 | также: 78 | 79 | - из привязанного к группе канала (с точки зрения API это пересланные сообщения); 80 | - от лица группы от анонимных администраторов той же группы; 81 | - от лица публичных каналов от премиум-пользователей. 82 | 83 | Корректно обрабатывайте такие случаи. 84 | 85 | ## Ссылки по теме 86 | 87 | - [О privacy mode в документации к API](https://core.telegram.org/bots/features#privacy-mode) 88 | -------------------------------------------------------------------------------- /ru/chats/id.md: -------------------------------------------------------------------------------- 1 | # Как устроены ID пользователей и чатов в Телеграме 2 | 3 | У каждого пользователя, бота, группы или канала в Телеграме есть собственный неизменяемый ID. 4 | 5 | Официальные приложения Телеграма не отображают ID. Если вам понадобится узнать ID пользователей и чатов 6 | в приложении, используйте неофициальные приложения или ботов [вроде этого](https://t.me/getmyid_bot). 7 | 8 | ::: warning 9 | Не храните ID пользователей и чатов в 32-битных числах, потому что ID могут быть очень большими. 10 | Дробные с двойной точностью (как `number` в Джаваскрипте) и целые 64-битные подойдут. 11 | ::: 12 | 13 | ## В Bot API 14 | 15 | В Bot API ID обычных групп начинается с префикса `-`, а ID супергрупп с `-100`. 16 | Так, ID канала `1356415630` превращается в `-1001356415630`. 17 | 18 | ## ID бота в его токене 19 | 20 | В токене бота первая часть — это его ID. Например, токен `110201874:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw` 21 | принадлежит боту с ID `110201874`. 22 | -------------------------------------------------------------------------------- /ru/chats/pm.md: -------------------------------------------------------------------------------- 1 | # Как Телеграм-бот управляет диалогами и пользователями 2 | 3 | ## Как начинается личный диалог 4 | 5 | Бот может написать пользователю в личный чат только с его разрешения. Если диалог 6 | уже начат, бот может отправлять сообщения в любой момент. 7 | 8 | Бот не может писать другим ботам. 9 | 10 | ### 1. Когда пользователь запускает бота 11 | 12 | Личная переписка пользователя с ботом начинается, когда пользователь открывает бота и нажимает на кнопку «Запустить». 13 | 14 | Открыть бота впервые пользователь может, например, по ссылке или через поиск в приложении. 15 | В этот момент пользователь увидит [текст «Что может этот бот»](../dev/botfather#customization) и кнопку «Запустить». 16 | В зависимости от платформы и языка пользователя кнопка эта также может называться «Начать» или «Start». 17 | 18 | Нажатие на эту кнопку отправляет команду `/start`. 19 | Боту следует отвечать на неё приветствием или инструкцией по использованию. 20 | 21 | Когда у пользователя появится переписка с ботом, он увидит бота в списке недавних чатов. 22 | 23 | ![](/pictures/ru/start.gif) 24 | 25 | ::: warning 26 | Команда `/start` не обязательно означает, что это первое сообщение от пользователя. Убедитесь, что ваш бот 27 | не ломается, если пользователь отправил `/start` вручную уже после запуска. 28 | 29 | Более того, первое сообщение от пользователя может не содержать команду `/start`. Через Telegram API пользователь 30 | может начать диалог с любого сообщения. Вряд ли у вашего бота будут такие ненормальные пользователи, 31 | но лучше проверьте, что такое действие не кладёт вашего бота. 32 | ::: 33 | 34 | ::: tip 35 | Чтобы сообщение `/start` содержало дополнительную информацию, используйте [диплинки](../interaction/links). 36 | ::: 37 | 38 | ### 2. В других случаях 39 | 40 | Бот также может написать пользователю, если: 41 | 42 | - пользователь оставил [заявку на вступление](../interaction/join-requests) в группу; 43 | - пользователь авторизовался через бота на сайте [с Telegram Login Widget](../interaction/login-widget). 44 | 45 | Перед диалогом пользователь видит, по какой из этих причин бот может писать пользователю. 46 | 47 | ## Остановка диалога { #block } 48 | 49 | Пользователь может вновь остановить переписку, заблокировав бота. Это значит, что бот снова не сможет отправлять 50 | пользователю сообщения, пока тот его не запустит. 51 | 52 | ::: tip Как проверить, может ли бот писать пользователю 53 | Попробуйте показать в чате с пользователем статус «Бот печатает...». Если сервера Телеграма вернули ошибку, вы не можете 54 | писать пользователю. 55 | 56 | Это значит, что пользователь заблокировал бота или бот никогда не мог писать этому пользователю. 57 | ::: 58 | 59 | ## Профиль пользователя 60 | 61 | Если вы будете хранить пользователей (в базе данных, например) — учтите, что у пользователя обязательно должно быть имя, 62 | но необязательно фамилия и юзернейм. Кроме того, все эти данные пользователи могут в любой момент поменять; поэтому 63 | различать пользователей следует не по юзернейму, а [по их ID](../chats/id). 64 | 65 | ## Языки пользователей 66 | 67 | Боты видят язык, установленный у пользователя в приложении Телеграма. Таким образом ваш бот 68 | может переписываться с пользователем на его языке. 69 | 70 | В апдейтах не всегда отображается язык пользователя. Поэтому, если ваш бот подстраивается под языки пользователей, 71 | для пользователя с неустановленным языком документация Телеграма рекомендует использовать последний язык, который был 72 | известен для этого пользователя, или английский, если такого языка нет. 73 | 74 | ## «Знакомые» пользователи { #seen-users } 75 | 76 | Действия бота могут касаться пользователя только в том случае, если бот «знает» этого пользователя. 77 | Чтобы «узнать» человека, бот должен получить от него сообщение или запросить его профиль по юзернейму. 78 | 79 | Технически это работает так: кроме [ID пользователя](./id) в запросе к серверу бот должен указать свой access hash 80 | этого пользователя. API отдаёт этот access hash вместе с информацией о профиле пользователя в апдейтах. 81 | Bot API и хорошие библиотеки под Telegram API кэшируют access hash, так что скорее всего вам не нужно использовать 82 | его напрямую. 83 | -------------------------------------------------------------------------------- /ru/chats/supergroups.md: -------------------------------------------------------------------------------- 1 | # Что такое супергруппы 2 | 3 | Давным-давно разработчики Телеграма разделили группы на два типа: обычные группы и супергруппы. Супергруппы 4 | предназначались для больших сообществ. Они могли иметь больше участников, публичные ссылки и другие плюшки. 5 | 6 | Но со временем, видимо, эту идею сочли неудобной или непонятной. Теперь в интерфейсе Телеграма 7 | не используется слово «супергруппа», и обычные группы и супергруппы выглядят почти одинаково. 8 | 9 | Тем не менее с технической точки зрения различия остались. Главная особенность супергрупп в том, что в API они 10 | считаются частным случаем каналов. 11 | 12 | В хендбуке я называю группами и обычные, и супергруппы. 13 | 14 | ## Создание супергруппы 15 | 16 | Обычная группа преобразуется в супергруппу, когда у группы меняются определённые настройки. Поскольку в этот момент 17 | технически группа меняется на канал-супергруппу, [ID чата](../chats/id) меняется. Превратить супергруппу обратно 18 | в группу обычную нельзя. 19 | 20 | ## ID сообщений и групп 21 | 22 | [id сообщений](../messages/id) в обычных группах и супергруппах устроены по-разному. 23 | Помимо этого, ID обычных групп в Bot API начинается с префикса `-`, а ID супергрупп с `-100`. 24 | 25 | ## Гигагруппы (broadcast groups) 26 | 27 | Число участников _супергруппы_ ограничено 200 000. Когда число участников близко к лимиту, Телеграм предлагает 28 | админам преобразовать группу в гигагруппу. Гигагруппы могут содержать неограниченное число участников, но отправлять 29 | сообщения в такие группы могут только админы. 30 | 31 | Я не знаю, кому это нужно. 32 | 33 | ## Ссылки по теме 34 | 35 | - [Особенности групп и супергрупп; когда группы становятся супегруппами](https://tginfo.me/groups_vs_supergroups/) 36 | 38 | - [О группах, супергруппах и broadcast groups в документации к API](https://core.telegram.org/api/channel) 39 | -------------------------------------------------------------------------------- /ru/dev/api.md: -------------------------------------------------------------------------------- 1 | # Чем Telegram API отличается от Bot API 2 | 3 | Ботом управляет программа. Она связывается с серверами Телеграма, чтобы 4 | получать информацию (например, о сообщении, которое получил бот) и отдавать команды (например, ответить на сообщение). 5 | Давайте разберёмся, как это происходит. 6 | 7 | **MTProto API** — он же **Telegram API** — это апи, через которое ваше приложение Телеграма на телефоне 8 | или компьютере связывается с серверами Телеграма. Он открыт: разработчики могут использовать его, чтобы создавать 9 | свои приложения для мессенджера. 10 | 11 | Называется оно так потому, что основано на протоколе MTProto, который команда 12 | Телеграм и разработала. 13 | 14 | **Telegram Bot API** — это отдельное апи поверх Telegram API, на котором могут работать только боты. 15 | 16 | Оно было создано для того, чтобы разработчики могли писать ботов на обычных HTTP-запросах, не разбираясь в протоколе 17 | MTProto. Ещё в Bot API есть фичи для упрощения разработки: например, он может работать через вебхуки и автоматически 18 | размечать сообщения через HTML или Markdown. 19 | 20 | Но вам это не нужно :⁠) 21 | 22 | Скорее всего, вы не будете писать сырые HTTP-запросы, а будете использовать готовые библиотеки для разработки ботов. 23 | Такие библиотеки есть под многие языки программирования, и обычно в них есть всё, что вам понадобится для удобной 24 | работы. 25 | 26 | **Для разработки ботов вы можете использовать как библиотеки под Telegram API, так и библиотеки под Bot API.** 27 | 28 | ## Какой API выбрать? 29 | 30 | Под Bot API написано гораздо больше библиотек. 31 | 32 | С другой стороны, в Bot API больше ограничений. Например, через него 33 | нельзя [загружать большие файлы](../messages/sending#file-limits) 34 | или [получать старые сообщения из истории чата](./updates#limitations). 35 | 36 | О выборе библиотеки читайте [на следующей странице](./libraries). 37 | 38 | { #api-difference } 39 | 40 | ::: details Различия функционала Bot API и Telegram API 41 | 42 | | Фича | Bot API | Telegram API | 43 | |------------------------------------------|-------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| 44 | | **Получение сообщений** | Только из [апдейтов](./updates) | Из апдейтов и по ID сообщений | 45 | | **Получение пользователей** | Только из апдейтов | Из апдейтов и по ID (если бот [«видел»](../chats/pm#seen-users) пользователя) и по юзернейму (200 раз в сутки) | 46 | | **Размер файлов** | ↓ 20 МБ, ↑ 50 МБ (Если нет [локального сервера](https://core.telegram.org/bots/api#using-a-local-bot-api-server)) | Как для обычных пользователей | 47 | | **Получение списка участников группы** | Невозможно | Возможно | 48 | | **Получение старых апдейтов** | Невозможно | Возможно | 49 | | **Запуск нескольких программ с одним ботом** | Только если остальные программы на Telegram API | [Возможно](./updates#получение-апдеитов-несколько-раз) | 50 | 51 | В Telegram API ограничено [можно получить старые апдейты](https://core.telegram.org/api/updates#recovering-gaps). 52 | Это полезно, например, чтобы получить список пользователей бота, если он не сохранялся или база данных была утеряна. 53 | {#old-updates} 54 | 55 | ::: 56 | 57 | ## Юзерботы 58 | 59 | Раз Telegram API открыт, и под него даже есть всякие библиотеки, — значит, вы легко можете написать программу, 60 | управляющую не ботом, а аккаунтом пользователя. 61 | 62 | В народе такую программу называют юзерботом. 63 | 64 | Кто-то пишет юзерботов, чтобы каждую 65 | минуту [ставить текущее время себе на аватарку](https://habr.com/ru/articles/457078/), кто-то — чтобы сохранять 66 | сообщения из публичных групп и каналов. 67 | 68 | В общем, с помощью юзерботов можно делать любые действия с Телеграм-аккаунтами, которые нельзя сделать с помощью ботов. 69 | 70 | ::: warning 71 | Телеграм обычно не банит за использование юзерботов, но будьте осторожны: за спам аккаунт могут ограничить 72 | или удалить. 73 | ::: 74 | 75 | ## Ссылки по теме 76 | 77 | - [Технические детали: как устроен протокол MTProto](https://core.telegram.org/mtproto) 78 | - [Об авторизации ботов через Telegram API](https://core.telegram.org/api/bots) 79 | - [Bot API reference](https://core.telegram.org/bots/api) 80 | - [Методы Telegram API](https://core.telegram.org/methods) 81 | - [Канал с обновлениями Bot API](https://t.me/BotNews) 82 | -------------------------------------------------------------------------------- /ru/dev/basics.md: -------------------------------------------------------------------------------- 1 | # Введение в разработку Телеграм-ботов 2 | 3 | Бот — это аккаунт в Телеграме, предназначенный для того, чтобы им управляла программа (сервер). 4 | 5 | Боты могут участвовать в личных сообщениях с пользователями, быть участниками групп и каналов. Они могут отправлять 6 | сообщения, отвечать на команды пользователей, отправлять картинки и ещё много чего делать. 7 | 8 | Боты ограничены в возможностях по сравнению с обычными пользователями, чтобы их приватность не нарушалась: 9 | например, боты не могут самостоятельно вступать в группы. 10 | 11 | ::: info 12 | Хотя с технической точки зрения все боты тоже считаются пользователями, в этом хендбуке пользователями я всё-таки называю 13 | настоящих пользователей. 14 | ::: 15 | 16 | ## Как написать бота 17 | 18 | Если коротко: 19 | 20 | 1. Зарегистрируйте бота. 21 | 2. Выберите библиотеку на любимом языке программирования. 22 | 3. Пишите код, параллельно читая документацию к библиотеке и этот хендбук. 23 | 24 | Вы можете запускать код бота у вас на компьютере, но когда код будет готов, вам стоит купить хостинг и запустить код на 25 | сервере. 26 | 27 | Обо всём этом подробнее — на следующих страницах. 28 | 29 | ## Ссылки по теме 30 | 31 | - [О ботах и их отличиях от обычных пользователей — в документации](https://core.telegram.org/bots#how-do-bots-work) 32 | -------------------------------------------------------------------------------- /ru/dev/botfather.md: -------------------------------------------------------------------------------- 1 | # Как зарегистрировать и настроить Телеграм-бота 2 | 3 | ## Регистрация бота 4 | 5 | Чтобы зарегистрировать бота, напишите специальному боту [@BotFather](https://t.me/BotFather). 6 | 7 | Он предложит создать бота с помощью команды `/new_bot`. Вы выберете название и 8 | [юзернейм](./usernames) бота, и тогда он создаст профиль бота. 9 | 10 | Вы получите токен бота: что-то вроде `1553279091:AAGLECcm23ihHRomX3PrKHc-IMQcIti6afA`. Токен — это ключ, с помощью 11 | которого вы будете управлять ботом. 12 | 13 | ![Пример создания бота](/pictures/ru/botfather.png) 14 | 15 | ## Настройка бота 16 | 17 | Также в [@BotFather](https://t.me/BotFather) вы можете использовать команду `/mybots`, чтобы изменять настройки своих 18 | ботов. 19 | Можно 20 | менять оформление профиля и настраивать специальные фичи: например, контролировать возможность 21 | добавлять бота в группы. 22 | 23 | Один пользователь может зарегистрировать до 20 ботов. 24 | 25 | ### Оформление { #customization } 26 | 27 | Чтобы поменять оформление бота, откройте меню `/mybots`, выберите бота и нажмите на `Edit bot`. Там вы сможете настроить 28 | профиль бота: 29 | 30 | ![Аватарка, имя, описание бота и «о себе»](/pictures/ru/customization.png){ style="max-width: 480px" } 31 | 32 | Описание — это текст, который пользователь увидит перед перепиской в личном чате с ботом. 33 | К описанию вы можете добавить картинку, в том числе гифку. 34 | { style="margin-top: 32px" } 35 | 36 | ::: tip 37 | Потратьте свое время на оформление бота, чтобы пользователям было проще его использовать. 38 | Поставьте аватарку, чтобы бота было проще отличать от других чатов в 39 | приложении. В описании можете свои контакты. 40 | ::: 41 | 42 | ::: info 43 | Там же вы можете поменять [подсказки команд](../messages/commands) 44 | или [placeholder для инлайн-режима](../interaction/inline). 45 | ::: 46 | 47 | ### Передача бота 48 | 49 | В настройках бота в BotFather можно передать право на владение ботом другому человеку. Для этого на вашем аккаунте 50 | должна быть включена двухфакторная авторизация — не менее, чем за 7 дней до передачи. Передать бота можно только 51 | пользователю, который что-либо ему писал. 52 | 53 | 54 | -------------------------------------------------------------------------------- /ru/dev/host.md: -------------------------------------------------------------------------------- 1 | # Как запустить бота на сервере 2 | 3 | ## Хостинг 4 | 5 | Скорее всего, вы захотите запустить вашу программу со стабильным питанием и стабильным интернетом, 6 | так что вам понадобится сервер. 7 | 8 | Для этого нужно будет купить хостинг. Программы для ботов обычно не требуют много ресурсов, поэтому вам хватит 9 | простого тарифа. 10 | 11 |
12 | Здесь может быть реклама вашего хорошего хостинга :) 13 |
14 | 15 | ## Запросы к серверу или вебхуки 16 | 17 | Настройка хостинга зависит от режима работы вашего бота. По умолчанию, чтобы получить апдейты, ваша программа должна 18 | регулярно делать запрос к серверу. Но если вы используете Bot API, то программа может работать как вебхук: 19 | тогда сервера Телеграма будут делать запрос к программе, чтобы сообщить об апдейтах. 20 | 21 | Чтобы реализовать вебхук, вам нужно будет веб-приложение, которое будет принимать запросы с апдейтами. 22 | Если вы используете библиотеку aiogram, вы можете 23 | использовать [встроенные функции](https://docs.aiogram.dev/en/latest/dispatcher/webhook.html) с aiohttp или другим 24 | асинхронным веб-фреймворком. 25 | 26 | ## Бесплатный хостинг 27 | 28 | Если вы совсем не готовы тратить деньги за хостинг, можете запустить код 29 | на [PythonAnywhere](https://www.pythonanywhere.com/) (он нестабильный) или 30 | на [Yandex Cloud Functions](https://cloud.yandex.ru/docs/functions/tutorials/telegram-bot-serverless). 31 | -------------------------------------------------------------------------------- /ru/dev/libraries.md: -------------------------------------------------------------------------------- 1 | --- 2 | comments: 841727 3 | --- 4 | 5 | # Как выбрать правильную библиотеку для Телеграм-бота 6 | 7 | ## Библиотеки для Bot API 8 | 9 | Самая популярная продвинутая библиотека для разработки ботов на Питоне — 10 | это [aiogram](https://github.com/aiogram/aiogram). Её любят, потому что она асинхронная, использует декораторы и содержит удобные инструменты 11 | для разработки. Известная альтернатива — [Rocketgram](https://github.com/rocketgram/rocketgram). 12 | 13 | ::: details Пример кода на aiogram 14 | 15 | Вот для примера код с первой страницы [документации](https://docs.aiogram.dev/en/dev-3.x/) к aiogram. 16 | 17 | ```python 18 | import asyncio 19 | import logging 20 | import sys 21 | from os import getenv 22 | 23 | from aiogram import Bot, Dispatcher, Router, types 24 | from aiogram.enums import ParseMode 25 | from aiogram.filters import CommandStart 26 | from aiogram.types import Message 27 | from aiogram.utils.markdown import hbold 28 | 29 | # Bot token can be obtained via https://t.me/BotFather 30 | TOKEN = getenv("BOT_TOKEN") 31 | 32 | # All handlers should be attached to the Router (or Dispatcher) 33 | dp = Dispatcher() 34 | 35 | 36 | @dp.message(CommandStart()) 37 | async def command_start_handler(message: Message) -> None: 38 | """ 39 | This handler receives messages with `/start` command 40 | """ 41 | # Most event objects have aliases for API methods that can be called in events' context 42 | # For example if you want to answer to incoming message you can use `message.answer(...)` alias 43 | # and the target chat will be passed to :ref:`aiogram.methods.send_message.SendMessage` 44 | # method automatically or call API method directly via 45 | # Bot instance: `bot.send_message(chat_id=message.chat.id, ...)` 46 | await message.answer(f"Hello, {hbold(message.from_user.full_name)}!") 47 | 48 | 49 | @dp.message() 50 | async def echo_handler(message: types.Message) -> None: 51 | """ 52 | Handler will forward receive a message back to the sender 53 | 54 | By default, message handler will handle all message types (like a text, photo, sticker etc.) 55 | """ 56 | try: 57 | # Send a copy of the received message 58 | await message.send_copy(chat_id=message.chat.id) 59 | except TypeError: 60 | # But not all the types is supported to be copied so need to handle it 61 | await message.answer("Nice try!") 62 | 63 | 64 | async def main() -> None: 65 | # Initialize Bot instance with a default parse mode which will be passed to all API calls 66 | bot = Bot(TOKEN, parse_mode=ParseMode.HTML) 67 | # And the run events dispatching 68 | await dp.start_polling(bot) 69 | 70 | 71 | if __name__ == "__main__": 72 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 73 | asyncio.run(main()) 74 | ``` 75 | 76 | ::: 77 | 78 | Кроме этого, ботов часто пишут на Джаваскрипте: например, на [Telegraf](https://github.com/telegraf/telegraf) 79 | и [GrammY](https://github.com/grammyjs/grammY). 80 | 81 | Для многих других языков тоже есть библиотеки. На официальном сайте есть 82 | [списочек](https://core.telegram.org/bots/samples), который даже вроде поддерживается в актуальном состоянии; 83 | но по перечисленнам библиотекам рекомендации дать не могу. 84 | 85 | ## Библиотеки для Telegram API 86 | 87 | Если вы хотите использовать [Telegram API вместо Bot API](./api), вам следует взять библиотеку, которая на этом апи 88 | основана. 89 | 90 | Для Питона есть две хорошие библиотеки: [Telethon](https://github.com/LonamiWebs/Telethon) 91 | и [Pyrogram](https://github.com/pyrogram/pyrogram). Для Джаваскрипта — [GramJS](https://github.com/gram-js/gramjs). 92 | 93 | Библиотеки для Telegram API удобны тем, что на них можно писать и ботов, и 94 | [юзерботов](./api#юзерботы), не переучиваясь. Я так и делаю: для всего использую Telethon. 95 | -------------------------------------------------------------------------------- /ru/dev/updates.md: -------------------------------------------------------------------------------- 1 | # Апдейты, приходящие Телеграм-ботам 2 | 3 | ## Что такое апдейты 4 | 5 | Апдейты (они же updates, то есть обновления) — это события, о которых сервер уведомляет бота. 6 | Это может быть апдейт о входящем сообщении, апдейт о вступлении участника в группу и так далее. 7 | 8 | Я ещё много раз буду использовать это слово на страницах хендбука. 9 | 10 | ## Главная сложность разработки ботов { #limitations } 11 | 12 | Апдейты — почти единственный способ для вашей программы узнать что-то о чатах и сообщениях. 13 | 14 | Например, ваша программа не может спросить у Телеграма, каким было последнее 15 | сообщение от пользователя или в каких чатах состоит бот. Телеграм даёт такую информацию только вместе с апдейтами: 16 | например, когда пользователь присылает сообщение или бота добавляют в группу. 17 | 18 | Если пользователь отправил боту сообщение, и вам нужно будет использовать текст сообщения позже, сохраните его. 19 | 20 | Если вам понадобится иметь список пользователей бота, полученных сообщений и так далее — 21 | вам следует хранить эти данные. Скорее всего, для этого будет нужна база данных. 22 | 23 | Если вы потеряете эту информацию, больше вы никак её не получите. 24 | 25 | ::: tip Telegram API 26 | Некоторую информацию всё-таки можно запросить, используя Telegram API в обход Bot API: 27 | например, так можно получить сообщение по ID или полную информацию о пользователе. 28 | Полный список можно посмотреть [на странице хендбука про API](../dev/api#api-difference). 29 | ::: 30 | 31 | ## Получение апдейтов несколько раз 32 | 33 | Ограничения Bot API не позволяют получать одни и те же апдейты несколько раз. Если вы получили апдейт в Bot API, то 34 | второй раз вы его уже не получите. 35 | 36 | В Telegram API такого ограничения нет. Всё потому, что Telegram API в основном предназначен для приложений: 37 | пользователь может пользоваться мессенджером через несколько 38 | приложений, каждое из которых должен получать новые сообщения. То же работает и для ботов. Если запустить несколько 39 | программ бота на Telegram API, каждая из них будет получать все апдейты. 40 | Кроме того, есть [трюк](../dev/api#old-updates), позволяющий получить старые апдейты второй раз. 41 | -------------------------------------------------------------------------------- /ru/dev/usernames.md: -------------------------------------------------------------------------------- 1 | # О чём следует помнить, выбирая боту юзернейм 2 | 3 | Когда вы будете регистрировать бота, вы должны будете выбрать для него юзернейм. Обратите внимание, что поменять 4 | юзернейм после этого будет сложно. 5 | 6 | ## Какими могут быть юзернеймы 7 | 8 | Юзернеймы ботов ничем не отличаются от юзернеймов пользователей, групп и каналов. Единственное ограничение — обычно они 9 | должны заканчиваться на `bot`. 10 | 11 | Например, юзернейм может выглядеть так: `@ExampleBot`. 12 | 13 | Эти требования не распространяются на официальных ботов: [@pic](https://t.me/pic), [@vid](https://t.me/vid), 14 | [@sticker](https://t.me/sticker). Вы же можете купить короткий юзернейм для бота на 15 | платформе [Fragment](https://fragment.com/). 16 | 17 | ## Многие юзернеймы заняты мёртвыми ботами 18 | 19 | Минимальная длина бесплатного юзернейма — пять символов с учётом суффикса `bot`; но занять такой короткий юзернейм вы 20 | не сможете. Все такие пятибуквенные, а может быть, и все шестибуквенные юзернеймы уже используются. 21 | 22 | Самое обидное, что почти все юзернеймы заняты нерабочими ботами. Разработчики редко готовы поддерживать ботов достаточно 23 | долго. 24 | 25 | ## Получить короткий юзернейм можно через техподдержку 26 | 27 | Теоретически, вы всё же можете бесплатно сменить юзернейм своего бота на более короткий — даже если он занят другим, 28 | неработающим, 29 | ботом. Нужно написать в поддержку: [@BotSupport](https://t.me/BotSupport). Поддержка проверяет бота вручную: бот должен 30 | быть рабочим и поддерживать английский язык. 31 | 32 | Принято использовать такой формат обращения в поддержку: 33 | 34 | ``` 35 | 1. @old_username 36 | 2. @new_username 37 | 3. Что делает бот 38 | ``` 39 | 40 | Если вы везунчик — вам ответят. 41 | -------------------------------------------------------------------------------- /ru/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Telegram Bot Handbook 3 | titleTemplate: false 4 | --- 5 | 6 | 9 | 10 | # Telegram Bot Handbook 11 | 12 | Добро пожаловать в хендбук — карманное руководство по разработке ботов, которое не завязано на конкретные библиотеки или 13 | языки программирования. 14 | 15 | Здесь я расскажу обо всём, что вам понадобится, чтобы спланировать и разработать надёжного бота. 16 | 17 | И хотя вы можете изучить официальный сайт Телеграма, документации к библиотекам и разные туториалы — из них вы не 18 | узнаете, как подступиться к разным возможностям ботов. Как выбрать библиотеку? Как настроить команды бота, чтобы 19 | пользователю было удобно их вводить? Почему ID чатов бывают отрицательными? Что не может делать бот в группах? Как 20 | пользователь может запустить диалог с ботом, ничего ему не отправляя? 21 | 22 | Хендбук — об этом. Можно назвать его подробным обзором на платформу Телеграм-ботов. 23 | 24 | 25 | 26 | ## Перед разработкой 27 | 28 | Перед тем, как вы начнёте писать бота, я советую изучить первый раздел («Разработка»). Он посвящён 29 | работе с API, библиотекам и прочим техническим моментам. Если хотите больше узнать о возможностях Телеграма вообще, 30 | пробегитесь и по следующим разделам. 31 | 32 | Планируете создать бота с необычными фичами или большой нагрузкой? Найдите страницы, посвящённые 33 | нужным функциям. 34 | 35 | ## Во время разработки 36 | 37 | Хендбук удобно использовать как справочник: возвращайтесь к нужной теме, чтобы вчитаться в подробности. 38 | 39 | ## Напоследок 40 | 41 | Хендбук — это расширенная версия моей старой статьи «Всё, о чём должен знать разработчик ботов». 42 | 43 | Страницы лежат на Гитхабе, так что вы можете предлагать дополнения и исправления: буду благодарен. 44 | 45 | Некоторые картинки и видео взяты с официального сайта Телеграма. Большинство скриншотов сделаны в веб-версиях Телеграма. 46 | 47 | Автор: [Артём Иванов](https://t.me/tm_a_t). Консультировал [Ваня Филипенков](https://t.me/vanutp). 48 | -------------------------------------------------------------------------------- /ru/interaction/html-games.md: -------------------------------------------------------------------------------- 1 | # HTML-игры в Телеграм-ботах 2 | 3 | Боты могут позволять пользователям играть в HTML5-игры в чатах. 4 | 5 | Бот может отправлять сообщения-игры или создавать их через [инлайн-режим](../interaction/inline). Вы 6 | можете увидеть, как это работает, на примере официального [@gamebot](https://t.me/gamebot). 7 | 8 | --- 9 | 10 | 13 | 14 | ## Ссылки по теме 15 | 16 | - [Документация Bot Gaming Platform](https://core.telegram.org/bots/games) 17 | -------------------------------------------------------------------------------- /ru/interaction/inline.md: -------------------------------------------------------------------------------- 1 | # Как реализовать инлайн-режим в боте 2 | 3 | Инлайн-режим (inline mode) — это возможность отправлять сообщения «через бота». Если бот поддерживает инлайн-режим, 4 | пользователь может обратиться к боту в любом чате, чтобы отправить сообщение, сгенерированное ботом. Инлайн-режим 5 | работает даже в чатах, где нет этого бота. 6 | 7 | Например, таким образом с помощью бота пользователь может найти видео или музыку и сразу отправить в чат. 8 | 9 | Чтобы запустить инлайн-режим, пользователь вводит в чате юзернейм бота и пробел. Если 10 | требуется, после юзернейма он может добавить текстовый запрос: текст до 256 символов. 11 | Появляется меню результатов. Пользователь выбирает результат и таким образом отправляет сообщение. 12 | 13 | 16 | 17 | Инлайн-режим можно включить в BotFather; там же можно выбрать плейсхолдер вместо стандартного «Search...» 18 | 19 | В группе можно запретить использовать инлайн всем или некоторым участникам. В официальных приложениях Телеграма это 20 | ограничение объединено с ограничением на отправку стикеров и GIF. 21 | 22 | ## Отображение результатов 23 | 24 | Результаты можно отображать сеткой (удобно для выдачи картинок) или вертикальным списком (удобно для выдачи текста). 25 | 26 | ![Сеткой](/pictures/ru/inline-type-1.png) 27 | 28 | ![Списком](/pictures/ru/inline-type-2.png) 29 | 30 | Можно показать вместе результаты двух видов, но, кажется, такой вариант отображается корректно только на Telegram 31 | Desktop. 32 | Остальные приложения покажут такие результаты одним списком. 33 | 34 | ::: details Скриншот результатов двух видов на Telegram Desktop 35 | ![Совмещение двух видов](/pictures/ru/inline-both-types.png){style="max-width: 400px"} 36 | ::: 37 | 38 | ## Inline feedback 39 | 40 | Inline feedback — это апдейты о том, что юзер выбрал инлайн-результат и отправил сообщение. Чтобы получать эти 41 | апдейты, вы должны включить inline feedback в BotFather. 42 | 43 | Inline feedback предназначается для сбора статистики; но разработчики ботов часто используют его для того, чтобы 44 | отредактировать сообщение после отправки. Это полезно, когда нужно подгружать не все результаты сразу, а только 45 | выбранный. Например, если бот используется для поиска музыки, то он может не загружать сразу все песни во время поиска, 46 | а [добавить песню в сообщение](../messages/sending#edit-media) только после отправки. 47 | 48 | Важный момент: если вы получили апдейт об отправке инлайн-сообщения, то вы можете его редактировать, только если к нему 49 | прикреплены инлайн-кнопки. (Если кнопок нет, то в апдейте не указывается ID инлайн-сообщения, так что вы не сможете его 50 | отредактировать.) 51 | 52 | ![Настройка в BotFather. Можно выбрать процент приходящих апдейтов](/pictures/ru/inline-feedback.png) 53 | 54 | ## Ссылки по теме 55 | 56 | - [Об инлайн-запросах на сайте Телеграма](https://core.telegram.org/bots/features#inline-requests) 57 | -------------------------------------------------------------------------------- /ru/interaction/join-requests.md: -------------------------------------------------------------------------------- 1 | # Разработка Телеграм-бота для управления заявками на вступление в чаты 2 | 3 | Если пользователь переходит в группу или канал по ссылке, может потребоваться подтверждение админов. В этом случае 4 | пользователь не вступает в группу, а оставляет заявку на вступление. 5 | 6 | Админы видят список заявок и могут отклонять пользователей или принимать их в чат. Боты-админы тоже могут это делать. 7 | 8 | ## Когда появляется заявка 9 | 10 | - **Если группа требует подтверждения админов.** 11 | 12 | Админы могут включить такое ограничение у групп с юзернеймом или групп, привязанных к каналу. 13 | 14 | - **Если пригласительная ссылка требует подтверждения админов.** 15 | 16 | У группы или канала может быть несколько пригласительных ссылок — их создают админы. У каждой такой ссылки может быть 17 | ограниченное число участников или ограниченное время действия; а ещё ссылка может требовать одобрения админов. 18 | 19 | Боты-админы тоже могут создавать пригласительные ссылки. 20 | 21 | ## Боты и заявки 22 | 23 | Бот-админ в группе или канале получает апдейт каждый раз, когда кто-то оставляет заявку на вступление. 24 | Если бот имеет право админа на добавление участников, он может принимать и отклонять заявки. 25 | 26 | Более того, бот-админ может написать каждому, кто оставил заявку, в личный диалог. 27 | 28 | ## Ссылки по теме 29 | 30 | - [Как выглядят ссылки-приглашения и заявки на вступления в приложении](https://telegram.org/blog/shared-media-scrolling-calendar-join-requests-and-more#join-requests-for-groups-and-channels) 31 | -------------------------------------------------------------------------------- /ru/interaction/links.md: -------------------------------------------------------------------------------- 1 | # Ссылки, открывающие Телеграм-бота 2 | 3 | ## Обычные ссылки 4 | 5 | Ссылки на ботов работают так же, как и ссылки на пользователей, группы и каналы: 6 | бота с юзернеймом `@examplebot` можно открыть по ссылке [t.me/examplebot](https://t.me/examplebot). 7 | 8 | Также можно использовать прямую ссылку: 9 | [tg://resolve?domain=examplebot](tg://resolve?domain=examplebot) 10 | 11 | ::: info О ссылках tg:// 12 | 13 | Ссылки, начинающиеся на tg://, могут не только заменять ссылки t.me. 14 | Ссылка [tg://settings](tg://settings), например, открывает настройки. 15 | 16 | Списки таких ссылок есть [в документации](https://core.telegram.org/api/links) и в неофициальном 17 | канале [@DeepLink](https://t.me/deeplink). 18 | 19 | ::: 20 | 21 | ## Диплинки 22 | 23 | Ссылка [t.me/examplebot?start=ВАШ_ТЕКСТ](https://t.me/examplebot?start=ВАШ_ТЕКСТ) называется диплинком. С её помощью 24 | пользователь может запустить бота с каким-то стартовым параметром. 25 | 26 | Это работает так. Когда пользователь переходит по диплинку, у него открывается переписка с ботом и кнопка «Запустить» — 27 | даже если пользователь уже [запускал бота](../chats/pm). Кнопка «Запустить» отправляет команду `/start ВАШ_ТЕКСТ`. 28 | При этом пользователь увидит только `/start`, как при обычном запуске бота. 29 | 30 | 33 | 34 | Часто диплинки используются для реферальных программ: например, в качестве параметра можно передавать ID пользователя, 35 | поделившегося ссылкой. 36 | 37 | Такая же прямая ссылка: [tg://resolve?domain=examplebot&start=ВАШ_ТЕКСТ](tg://resolve?domain=examplebot&start=ВАШ_ТЕКСТ) 38 | 39 | ## Диплинки для групп 40 | 41 | Диплинки можно использовать не только для личных сообщений, но и для групп. 42 | 43 | Ссылка [t.me/examplebot?startgroup=ВАШ_ТЕКСТ](https://t.me/examplebot?startgroup=ВАШ_ТЕКСТ) откроет у пользователя меню 44 | с выбором группы для добавления бота. Когда пользователь добавит бота, сразу отправится команда `/start ВАШ_ТЕКСТ`. 45 | 46 | Прямая ссылка: [tg://resolve?domain=examplebot&startgroup=true](tg://resolve?domain=examplebot&startgroup=true) 47 | 48 | ## Ссылки по теме 49 | 50 | - [О диплинках в документации к API](https://core.telegram.org/bots/features#deep-linking) 51 | -------------------------------------------------------------------------------- /ru/interaction/login-widget.md: -------------------------------------------------------------------------------- 1 | # Авторизация на сайте через Telegram Login Widget 2 | 3 | Вы можете добавить на свой сайт кнопку «Войти через Telegram». 4 | 5 | В процессе авторизации будет использоваться ваш бот. Можно настроить авторизацию так, что, авторизуясь, пользователи 6 | будут разрешать боту отправлять сообщения в личном чате. 7 | 8 | В качестве альтернативы Telegram Login Widget можете рассмотреть [Login URL button](../messages/buttons): это способ 9 | авторизоваться на сайте из Телеграм-чата. 10 | 11 | ## Как проходит авторизация 12 | 13 | 1. Пользователь сайта нажимает на кнопку «Войти через Telegram» и вводит номер телефона. 14 | 2. Бот Telegram просит подтвердить вход. 15 | 3. Пользователь подтверждает вход, нажимает «Принять» и попадает на сайт. 16 | 17 | ![скриншот входа](https://core.telegram.org/file/811140314/17c1/xf4ULBL5tmE.58438/07ff5b2958ed0e7e36) 18 | 19 | ## Ссылки по теме 20 | 21 | - [Страница Login Widget на сайте Телеграма](https://core.telegram.org/widgets/login) -------------------------------------------------------------------------------- /ru/interaction/mini-apps.md: -------------------------------------------------------------------------------- 1 | # Telegram Mini Apps 2 | 3 | Mini Apps — раньше они назывались Web Apps — это способ внедрить свою веб-страничку в бота. 4 | 5 | Подробный рассказ есть на странице документации: https://core.telegram.org/bots/webapps 6 | 7 | Эту фичу использует полуофициальный бот [@Wallet](https://t.me/wallet). 8 | 9 | --- 10 | 11 | 14 | 15 | ## Ссылки по теме 16 | 17 | - [Документация](https://core.telegram.org/bots/webapps) 18 | -------------------------------------------------------------------------------- /ru/interaction/payments.md: -------------------------------------------------------------------------------- 1 | # Платежи через Телеграм-ботов 2 | 3 | Боты могут принимать платежи от пользователей. 4 | 5 | Платежи можно проводить через 6 | выбранных [провайдеров](https://core.telegram.org/bots/payments#supported-payment-providers), таких как Stripe. 7 | Провайдеры могут работать в разных странах и иметь разные ограничения. Ваш бот может принимать платежи от разных 8 | пользователей через разных провайдеров, если это нужно. 9 | 10 | ![Пример сообщения с оплатой](https://core.telegram.org/file/464001393/101fc/SB_bFCLR0tg.130549/7ecf91aaa44737e8cb) 11 | 12 | ## Интерфейс 13 | 14 | Вы можете увидеть, как выглядит покупка, в канале [Demo Store](https://t.me/TestStore). 15 | 16 | Сообщения с товаром можно отправлять в любые чаты, в том числе через [инлайн-режим](./inline). Под сообщением всегда 17 | находится [кнопка](../messages/buttons#inline) «Купить». Если под сообщением есть несколько кнопок, кнопка «Купить» должна быть 18 | первой. 19 | 20 | ## Ссылки по теме 21 | 22 | - [Документация по платежам](https://core.telegram.org/bots/payments) 23 | -------------------------------------------------------------------------------- /ru/interaction/stickers.md: -------------------------------------------------------------------------------- 1 | # Управление наборами стикеров и эмодзи через Телеграм-бота 2 | 3 | Боты — и только боты — могут создавать наборы стикеров и кастомных эмодзи. 4 | При этом каждый набор должен принадлежать какому-то пользователю. 5 | 6 | Обычно пользователи Телеграма создают наборы и управляют ими через бота [@Stickers](https://t.me/stickers), 7 | но для этого можно использовать и других ботов. 8 | 9 | Боты могут создавать, переименовывать и удалять наборы. 10 | 11 | ::: info Эмодзи 12 | Использовать кастомные эмодзи могут только премиум-пользователи. Тем не менее создавать наборы кастомных эмодзи могут 13 | любые боты, и они могут принадлежать любым пользователям. 14 | ::: 15 | 16 | ## Форматы 17 | 18 | Наборы стикеров и эмодзи могут быть статичными (растровыми), анимированными (на основе формата Lottie) и в формате видео 19 | (webm). Помимо этого, набор одноцветных эмодзи может быть адаптивным: это значит, что у пользователей с тёмной темой 20 | эмодзи будут выглядеть светлыми, а у пользователей со светлой — тёмными. 21 | 22 | ## Ссылки по теме 23 | 24 | - [Стикеры и эмодзи: требования и ограничения](https://core.telegram.org/stickers) 25 | - [О стикерах в документации API](https://core.telegram.org/bots/features#stickers-and-custom-emoji) 26 | -------------------------------------------------------------------------------- /ru/messages/buttons.md: -------------------------------------------------------------------------------- 1 | # Кнопки в Телеграм-ботах 2 | 3 | Отправляя сообщение, бот может либо добавить к нему инлайн-кнопки (это кнопки под сообщением), либо показать 4 | клавиатурные кнопки (это кнопки вместо ввода сообщения). 5 | 6 | Эти два вида кнопок работают по-разному. 7 | 8 | ## Инлайн-кнопки { #inline } 9 | 10 | Инлайн-кнопки, они же inline keyboards или inline buttons, — это кнопки под сообщением. 11 | 12 | ### Callback button 13 | 14 | Просто кнопка, которая сама по себе ничего не делает. 15 | 16 | Когда пользователь нажимает на такую кнопку, боту приходит [апдейт](../dev/updates). После этого бот может что-нибудь сделать: например, 17 | изменить сообщение. 18 | 19 | После нажатия на кнопку бот может показать notification или alert. 20 | 21 | Когда приходит апдейт, различать такие кнопки можно по специальному параметру, который указывается при создании кнопок. 22 | 23 | 26 | 27 | ### URL button 28 | 29 | Кнопка, которая работает как ссылка. 30 | 31 | В Bot API эту кнопку можно использовать как [упоминание пользователя](./markup#mention), указав ссылку 32 | вида `tg://user?id=123456789`. В Telegram API для упоминания есть отдельный вид кнопок. 33 | 34 | ![Кнопка-ссылка под сообщением](/pictures/ru/url-button.png) 35 | 36 | ### Switch-to-inline button 37 | 38 | Кнопка для переключения [в инлайн-режим](../interaction/inline). Можно создать кнопку, 39 | запускающую инлайн в том же чате или открывающую меню для выбора чата. Также при создании кнопки можно указать 40 | текстовый запрос, который появится рядом с юзернеймом бота (но пользователь сможет его отредактировать). 41 | 42 | 45 | 46 | ### Request peer button 47 | 48 | Когда пользователь нажимает на эту кнопку, у него открывается меню выбора чатов. Пользователь выбирает, о каком из чатов 49 | отправить информацию боту. 50 | 51 | Создавая такую кнопку, вы можете гибко настроить, какие именно чаты увидит пользователь в списке: например, 52 | только каналы с юзейрнеймом или только группы, где он админ. 53 | 54 | ### Другие инлайн-кнопки 55 | 56 | Остальные виды кнопок связаны с более редкими фичами ботов: 57 | 58 | - Callback game button — кнопка для открытия [HTML-игры](../interaction/html-games). 59 | - Pay button — кнопка [для платежей](../interaction/payments). 60 | - Web view button — кнопка для открытия [веб-интерфейса в боте](../interaction/mini-apps). 61 | - Login URL button — специальная кнопка для авторизации пользователей на сайте. 62 | Использовалась, например, в официальном боте [@discussbot](https://t.me/discussbot) до появления 63 | в Telegram нативных комментариев. Работает примерно так же, как 64 | и [Telegram Login Widget](../interaction/login-widget), но пользователю не нужно вводить номер телефона 65 | и подтверждать вход; достаточно нажать на кнопку. 66 | 67 | ## Клавиатурные кнопки 68 | 69 | 70 | 71 | Второй тип кнопок — это keyboard buttons. Они отображаются у пользователя под полем ввода сообщения как подсказки 72 | (в веб-версиях раскрываются по кнопке ⌘). Нажав на такую кнопку, пользователь отправит её текст. 73 | 74 | В мобильных приложениях такие кнопки заменяют собой клавиатуру; но пользователь всегда может свернуть кнопки 75 | и увидеть клавиатуру снова. 76 | 77 | 80 | 81 | Клавиатурная кнопка может не просто отправить текст, но также: 82 | 83 | - запросить номер телефона пользователя, 84 | - запросить геолокацию пользователя 85 | - или открыть у пользователя меню создания опроса. 86 | 87 | Есть опция `resize_keyboard`, которая отвечает за то, изменять ли высоту этой «клавиатуры из кнопок». 88 | По умолчанию она почему-то выключена, и клавиатура выглядит растянутой. Получаются кнопки, как на этой картинке: 89 | 90 | ![](/pictures/ru/wide-buttons.png) 91 | 92 | Чтобы показать клавиатурные кнопки, бот должен отправить сообщение. 93 | Можно показать клавиатуру, которая свернётся (но не пропадёт) после нажатия на кнопку. 94 | 95 | По умолчанию, если показать кнопки в группе, они будут видны всем пользователям. Но вместо этого можно показать кнопки 96 | только упоминаемым пользователям, то есть: 97 | 98 | - пользователям, юзернеймы которых были в тексте сообщения, 99 | - и, если это ответ на другое сообщение, пользователю, который его отправил. 100 | 101 | ## Ряды кнопок 102 | 103 | И инлайн-кнопки, и клавиатурные кнопки могут составлять несколько рядов, в каждом из которых находится по несколько 104 | кнопок. 105 | 106 | В ряду может быть до 8 кнопок, а всего, отправляя сообщение, можно показать до 100 кнопок. 107 | 108 | Если вы ставите несколько кнопок в одном ряду, убедитесь, что их надписи видны в мобильных приложениях Телеграма. 109 | Слишком длинный текст на кнопках обрезается. 110 | -------------------------------------------------------------------------------- /ru/messages/commands.md: -------------------------------------------------------------------------------- 1 | # Команды в Телеграм-ботах 2 | 3 | Самый частый сценарий взаимодействия с ботом — через команды. Команды начинаются на «/» и состоят из латинских букв, 4 | цифр и подчёркиваний. 5 | 6 | Команды подсвечиваются как ссылки: можно нажать на команду, чтобы отправить её. 7 | 8 | ![Пример использования команд](/pictures/ru/commands.png) 9 | 10 | ## Команды в группах 11 | 12 | В группах, чтобы различать команды от разных ботов, Телеграм предлагает ставить в конце команды юзернейм бота. 13 | Например: `/start@examplebot` 14 | 15 | Если нажать на команду в сообщении от бота, она отправится с добавленным юзернеймом бота. 16 | 17 | Бот [не увидит](../chats/groups#privacy) команды, на конце которых стоит юзернейм другого бота. 18 | 19 | ## Подсказки команд 20 | 21 | Разработчик бота может указать в BotFather подсказки команд с короткими описаниями. Тогда, вводя команду в чат, 22 | пользователь увидит меню автодополнения. 23 | 24 | ![Пример дополнения команд в группе с командами от разных ботов](/pictures/ru/commands-autocomplete.png) 25 | 26 | Если у бота включены подсказки, то в личных чатах и группах с этим ботом рядом с кнопкой «Отправить» у пользователей 27 | появляется кнопка «Меню», открывающая подсказки. 28 | 29 | Если в подсказках команд есть `/help`, в профиле бота появляется кнопка «Помощь с ботом», которая отправляет эту 30 | команду. Аналогично, если есть `/settings`, то появляется кнопка «Настройки бота», а если `/privacy`, то кнопка 31 | «Политика конфиденциальности». 32 | 33 | Подсказки команд можно настраивать не только в BotFather, но и с помощью API. Таким образом бот может показывать разные 34 | меню команд для разных пользователей и групп. Также меню команд может зависеть от языка 35 | пользователя (это удобно для того, чтобы показывать описания команд на языке пользователя) 36 | и от того, является ли участник группы админом (например, команды для модерации группы). 37 | 38 | ## Аргументы команд 39 | 40 | Конечно, вы можете просить пользователя добавлять после команды какой-то текст: например, `/weather London` 41 | 42 | Тем не менее в Телеграме неудобно отправлять команду с дополнительным текстом. 43 | 44 | Обычно, если пользователь выберёт команду в автодополнении, он сразу её отправит. Чтобы дополнить команду по 45 | подсказке, не отправляя её, в десктопном приложении ему надо будет нажать tab, а в мобильных — зажать подсказку. 46 | Но, конечно, многие пользователи об этом не знают. 47 | 48 | Телеграм рекомендует реализовывать как можно более конкретные команды, чтобы использовать их без аргументов. 49 | 50 | Если это не помогает, можете рассмотреть другие варианты общения пользователя с ботом. Для выбора из нескольких 51 | вариантов подойдут [кнопки](../messages/buttons) или [инлайн-режим](../interaction/inline). Если боту нужна какая-то 52 | дополнительная информация от пользователя, то он может спросить об этом отдельным сообщением. 53 | -------------------------------------------------------------------------------- /ru/messages/id.md: -------------------------------------------------------------------------------- 1 | # Как устроены ID сообщений в Телеграме 2 | 3 | Каждое сообщение в Телеграме имеет свой ID. К системным сообщениям это тоже относится 4 | («пользователь зашел в группу»; «название канала изменилось») 5 | 6 | ID сообщений в супергруппах и каналах уникальны для чата: первое сообщение в чате имеет номер 1, второе имеет номер 2 и 7 | так далее. 8 | 9 | ID сообщений в личных сообщениях и обычных группах имеют сквозную нумерацию: 10 | ID сообщений считаются отдельно для пользователя (или бота). Так, первое полученное или отправленное пользователем 11 | сообщение во всех личках и группах имеет номер 1; второе такое сообщение имеет номер 2 и так далее. 12 | 13 | ::: info 14 | Через Telegram API бот может запросить сообщение по ID в любом чате. При использовании Bot API такой возможности 15 | нет. 16 | ::: 17 | -------------------------------------------------------------------------------- /ru/messages/markup.md: -------------------------------------------------------------------------------- 1 | # Разметка сообщений от Телеграм-ботов 2 | 3 | Сообщения могут содержать жирный текст, курсив и другую разметку. 4 | 5 | Размечать сообщения в Bot API можно в стиле HTML или Markdown. 6 | Аналогичная разметка реализована в библиотеках для Telegram API, таких как Telethon и Pyrogram. 7 | 8 | Текст в Телеграм-сообщениях может быть: 9 | 10 | - **жирным,** 11 | - _курсивным,_ 12 | - подчёркнутым, 13 | - зачёркнутым, 14 | - `моноширинным,` 15 | 16 | а также вы можете встроить в текст: 17 | 18 | - [ссылку](#), 19 | - спойлер — спрятанный текст, 20 | - упоминание пользователя по ID, 21 | - кастомные эмодзи (доступны только для ботов с [платным юзернеймом](../dev/usernames)). 22 | 23 | Суммарно в сообщение можно добавить не более 100 таких элементов разметки; лишние будут игнорироваться. 24 | 25 | Помимо этого, сообщение может содержать сколько угодно упоминаний пользователей по юзернейму. 26 | 27 | ## Моноширинный текст 28 | 29 | Моноширинным можно сделать кусочек текста (как HTML-тегом ``) и блок кода на полную ширину (как `
`).
30 | 
31 | У блока кода можно указать язык кода, и тогда приложения Телеграм будут подсвечивать синтаксис в этом блоке.
32 | 
33 | ## Спойлер
34 | 
35 | Спойлер — это текст, спрятанный за анимированной плашкой.
36 | 
37 | Обернуть в спойлер можно не только текст, но и картинки; хотя это делается не средствами разметки.
38 | 
39 | ![текст и картинка за спойлерами](/pictures/ru/spoiler.png)
40 | 
41 | ## Упоминание пользователя { #mention }
42 | 
43 | Упоминание пользователя — текст, похожий на ссылку, клик по которому открывает профиль пользователя.
44 | Чтобы вставить в сообщение упоминание пользователя, в Bot API достаточно встроить ссылку на `tg://user?ID=123456789`.
45 | Юзернейм пользователя автоматически превращается в упоминание.
46 | 
47 | Если упомянуть в группе её участника, он получит уведомление. Если в сообщении больше пяти упоминаний, уведомления
48 | получат только некоторые пять из них.
49 | 
50 | Бот может упоминать по ID в чате только тех пользователей, которые состоят в чате или разрешили показывать ссылки на себя при
51 | пересылке сообщений.
52 | Бот не может этого сделать, если он не [«видел»](../chats/pm#seen-users) пользователя.
53 | 
54 | Технически упоминания по юзернейму — это обычный текст, при нажатии на который приложение запрашивает у Телеграма 
55 | информацию о пользователе по юзернейму.
56 | Упоминания по ID же работают по-другому: отправитель сообщения вместе с текстом упоминания отправляет ID пользователя,
57 | и он привязывается к сообщению. Получателям вместе с сообщением передаётся профиль пользователя, 
58 | поэтому такое упоминание будет кликабельным, даже если пользователь поменяет юзернейм.
59 | 
60 | ## Ссылки по теме
61 | 
62 | - [Объяснение разметки в документации к Bot API](https://core.telegram.org/bots/api#formatting-options)
63 | 


--------------------------------------------------------------------------------
/ru/messages/sending.md:
--------------------------------------------------------------------------------
 1 | # Отправка, изменение и пересылка сообщений
 2 | 
 3 | На этой странице я собрал информацию об особенностях Телеграм-сообщений и связанных ограничениях ботов.
 4 | Убедитесь, что ваш бот правильно работает даже в крайних случаях, которые здесь описаны.
 5 | 
 6 | ## Отправка сообщений
 7 | 
 8 | Бот может отправлять и получать сообщения, как и пользователи. Это могут быть просто текстовые сообщения, а могут быть
 9 | сообщения с медиа: картинками, видео, файлами, опросами, голосовыми сообщениями, стикерами и так далее.
10 | 
11 | А ещё, в отличие от пользователей, бот может добавлять к своим сообщениям [кнопки](../messages/buttons).
12 | 
13 | ### Как устроены альбомы
14 | 
15 | Альбом — это несколько сообщений-картинок или сообщений-файлов, которые приложения Телеграма отображают как одно сообщение.
16 | 
17 | ### Какие ограничения на файлы { #file-limits }
18 | 
19 | В Телеграме можно делиться файлами до 4 ГБ, но ограничения в Bot API более жёсткие. Через Bot API бот может скачивать
20 | файлы до 20 МБ и отправлять файлы до 50 МБ. Эти лимиты повышаются, если вы используете
21 | [локальный сервер Bot API](../dev/api#api-difference): тогда бот может скачивать и отправлять файлы до 2 ГБ.
22 | 
23 | ### Как часто можно слать сообщения
24 | 
25 | Конечно, спамить не получится. Сам Телеграм называет такие примерные лимиты:
26 | 
27 | - не больше одного сообщения в секунду в один чат,
28 | - не больше 30 сообщений в секунду во все чаты,
29 | - не больше 20 сообщений в минуту в одну группу.
30 | 
31 | Если вы хотите сделать рассылку по всем пользователям, то вы не сможете отправить сообщения всем одновременно;
32 | придётся рассылать постепенно.
33 | 
34 | Учтите, что на более редкие действия, такие как изменение и удаление сообщений, ограничения строже.
35 | Для ботов с большим числом пользователей лимиты могут быть увеличены через поддержку.
36 | 
37 | ### Когда нельзя
38 | 
39 | Бот не может отправить сообщение [заблокировавшему его пользователю](../chats/pm#block);
40 | в группу или канал, где его нет или где админы отняли разрешение на отправку сообщений.
41 | 
42 | Премиум-пользователь может запретить отправку голосовых сообщений (в том числе кружочков).
43 | 
44 | ## Изменение сообщений
45 | 
46 | Когда бот изменяет сообщение, в сообщении не появляется надпись «Изменено», как в сообщениях пользователей.
47 | 
48 | ### Как изменять медиа { #edit-media }
49 | 
50 | Изменяя сообщение, можно изменить не только его текст, но и медиа.
51 | 
52 | Картинку, видео или файл можно заменить на другую картинку, видео или файл (музыка тоже считается файлом).
53 | 
54 | В сообщения, отправленные без медиа, уже нельзя добавить медиа.
55 | 
56 | ## Пересылка сообщений
57 | 
58 | Если попробовать переслать музыку, то она переотправится без подписи «Переслано».
59 | 
60 | Нельзя пересылать сообщения из групп и каналов, в настройках которых включён запрет на сохранение контента
61 | (это настройка называется protected content).
62 | 
63 | ## Ссылки по теме
64 | 
65 | - [Bots FAQ на сайте Телеграма про лимиты](https://core.telegram.org/bots/faq#my-bot-is-hitting-limits-how-do-i-avoid-this)
66 | 


--------------------------------------------------------------------------------
/ru/unlisted/official-bots.md:
--------------------------------------------------------------------------------
 1 | # Список официальных ботов Телеграма
 2 | 
 3 | Собран Ваней Филипенковым.
 4 | 
 5 | ```
 6 | @asmico_attach_bot
 7 | @bing
 8 | @bold
 9 | @BotFather
10 | @Channel_Bot
11 | @ContestBot
12 | @dadadsa
13 | @design_bot
14 | @discussbot
15 | @donate
16 | @DurgerKingBot
17 | @EURegulation
18 | @gamebot
19 | @gdprbot
20 | @gif
21 | @GmailBot
22 | @imdb
23 | @jobs_bot
24 | @like
25 | @mainbot
26 | @MTProxybot
27 | @pic
28 | @PremiumBot
29 | @PremiumJoinBot
30 | @PressBot
31 | @previews
32 | @Qqqqqqqqqqqqq
33 | @QuizBot
34 | @replies
35 | @SpamBot
36 | @sticker
37 | @Stickers
38 | @tdlib_bot
39 | @TelegramDonate
40 | @telegraph
41 | @tgx_bot
42 | @TonMobile
43 | @UnsupportedUser64Bot
44 | @username_bot
45 | @VerifyBot
46 | @vid
47 | @vote
48 | @wallet
49 | @WebpageBot
50 | @wiki
51 | @youtube
52 | id 470000 (Volunteer Support)
53 | ```
54 | 


--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
  1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
  2 | # yarn lockfile v1
  3 | 
  4 | 
  5 | "@algolia/autocomplete-core@1.9.3":
  6 |   version "1.9.3"
  7 |   resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz#1d56482a768c33aae0868c8533049e02e8961be7"
  8 |   integrity sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==
  9 |   dependencies:
 10 |     "@algolia/autocomplete-plugin-algolia-insights" "1.9.3"
 11 |     "@algolia/autocomplete-shared" "1.9.3"
 12 | 
 13 | "@algolia/autocomplete-plugin-algolia-insights@1.9.3":
 14 |   version "1.9.3"
 15 |   resolved "https://registry.yarnpkg.com/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz#9b7f8641052c8ead6d66c1623d444cbe19dde587"
 16 |   integrity sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==
 17 |   dependencies:
 18 |     "@algolia/autocomplete-shared" "1.9.3"
 19 | 
 20 | "@algolia/autocomplete-preset-algolia@1.9.3":
 21 |   version "1.9.3"
 22 |   resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz#64cca4a4304cfcad2cf730e83067e0c1b2f485da"
 23 |   integrity sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==
 24 |   dependencies:
 25 |     "@algolia/autocomplete-shared" "1.9.3"
 26 | 
 27 | "@algolia/autocomplete-shared@1.9.3":
 28 |   version "1.9.3"
 29 |   resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz#2e22e830d36f0a9cf2c0ccd3c7f6d59435b77dfa"
 30 |   integrity sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==
 31 | 
 32 | "@algolia/cache-browser-local-storage@4.20.0":
 33 |   version "4.20.0"
 34 |   resolved "https://registry.yarnpkg.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.20.0.tgz#357318242fc542ffce41d6eb5b4a9b402921b0bb"
 35 |   integrity sha512-uujahcBt4DxduBTvYdwO3sBfHuJvJokiC3BP1+O70fglmE1ShkH8lpXqZBac1rrU3FnNYSUs4pL9lBdTKeRPOQ==
 36 |   dependencies:
 37 |     "@algolia/cache-common" "4.20.0"
 38 | 
 39 | "@algolia/cache-common@4.20.0":
 40 |   version "4.20.0"
 41 |   resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.20.0.tgz#ec52230509fce891091ffd0d890618bcdc2fa20d"
 42 |   integrity sha512-vCfxauaZutL3NImzB2G9LjLt36vKAckc6DhMp05An14kVo8F1Yofb6SIl6U3SaEz8pG2QOB9ptwM5c+zGevwIQ==
 43 | 
 44 | "@algolia/cache-in-memory@4.20.0":
 45 |   version "4.20.0"
 46 |   resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.20.0.tgz#5f18d057bd6b3b075022df085c4f83bcca4e3e67"
 47 |   integrity sha512-Wm9ak/IaacAZXS4mB3+qF/KCoVSBV6aLgIGFEtQtJwjv64g4ePMapORGmCyulCFwfePaRAtcaTbMcJF+voc/bg==
 48 |   dependencies:
 49 |     "@algolia/cache-common" "4.20.0"
 50 | 
 51 | "@algolia/client-account@4.20.0":
 52 |   version "4.20.0"
 53 |   resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.20.0.tgz#23ce0b4cffd63100fb7c1aa1c67a4494de5bd645"
 54 |   integrity sha512-GGToLQvrwo7am4zVkZTnKa72pheQeez/16sURDWm7Seyz+HUxKi3BM6fthVVPUEBhtJ0reyVtuK9ArmnaKl10Q==
 55 |   dependencies:
 56 |     "@algolia/client-common" "4.20.0"
 57 |     "@algolia/client-search" "4.20.0"
 58 |     "@algolia/transporter" "4.20.0"
 59 | 
 60 | "@algolia/client-analytics@4.20.0":
 61 |   version "4.20.0"
 62 |   resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.20.0.tgz#0aa6bef35d3a41ac3991b3f46fcd0bf00d276fa9"
 63 |   integrity sha512-EIr+PdFMOallRdBTHHdKI3CstslgLORQG7844Mq84ib5oVFRVASuuPmG4bXBgiDbcsMLUeOC6zRVJhv1KWI0ug==
 64 |   dependencies:
 65 |     "@algolia/client-common" "4.20.0"
 66 |     "@algolia/client-search" "4.20.0"
 67 |     "@algolia/requester-common" "4.20.0"
 68 |     "@algolia/transporter" "4.20.0"
 69 | 
 70 | "@algolia/client-common@4.20.0":
 71 |   version "4.20.0"
 72 |   resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.20.0.tgz#ca60f04466515548651c4371a742fbb8971790ef"
 73 |   integrity sha512-P3WgMdEss915p+knMMSd/fwiHRHKvDu4DYRrCRaBrsfFw7EQHon+EbRSm4QisS9NYdxbS04kcvNoavVGthyfqQ==
 74 |   dependencies:
 75 |     "@algolia/requester-common" "4.20.0"
 76 |     "@algolia/transporter" "4.20.0"
 77 | 
 78 | "@algolia/client-personalization@4.20.0":
 79 |   version "4.20.0"
 80 |   resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-4.20.0.tgz#ca81308e8ad0db3b27458b78355f124f29657181"
 81 |   integrity sha512-N9+zx0tWOQsLc3K4PVRDV8GUeOLAY0i445En79Pr3zWB+m67V+n/8w4Kw1C5LlbHDDJcyhMMIlqezh6BEk7xAQ==
 82 |   dependencies:
 83 |     "@algolia/client-common" "4.20.0"
 84 |     "@algolia/requester-common" "4.20.0"
 85 |     "@algolia/transporter" "4.20.0"
 86 | 
 87 | "@algolia/client-search@4.20.0":
 88 |   version "4.20.0"
 89 |   resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.20.0.tgz#3bcce817ca6caedc835e0eaf6f580e02ee7c3e15"
 90 |   integrity sha512-zgwqnMvhWLdpzKTpd3sGmMlr4c+iS7eyyLGiaO51zDZWGMkpgoNVmltkzdBwxOVXz0RsFMznIxB9zuarUv4TZg==
 91 |   dependencies:
 92 |     "@algolia/client-common" "4.20.0"
 93 |     "@algolia/requester-common" "4.20.0"
 94 |     "@algolia/transporter" "4.20.0"
 95 | 
 96 | "@algolia/logger-common@4.20.0":
 97 |   version "4.20.0"
 98 |   resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.20.0.tgz#f148ddf67e5d733a06213bebf7117cb8a651ab36"
 99 |   integrity sha512-xouigCMB5WJYEwvoWW5XDv7Z9f0A8VoXJc3VKwlHJw/je+3p2RcDXfksLI4G4lIVncFUYMZx30tP/rsdlvvzHQ==
100 | 
101 | "@algolia/logger-console@4.20.0":
102 |   version "4.20.0"
103 |   resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.20.0.tgz#ac443d27c4e94357f3063e675039cef0aa2de0a7"
104 |   integrity sha512-THlIGG1g/FS63z0StQqDhT6bprUczBI8wnLT3JWvfAQDZX5P6fCg7dG+pIrUBpDIHGszgkqYEqECaKKsdNKOUA==
105 |   dependencies:
106 |     "@algolia/logger-common" "4.20.0"
107 | 
108 | "@algolia/requester-browser-xhr@4.20.0":
109 |   version "4.20.0"
110 |   resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.20.0.tgz#db16d0bdef018b93b51681d3f1e134aca4f64814"
111 |   integrity sha512-HbzoSjcjuUmYOkcHECkVTwAelmvTlgs48N6Owt4FnTOQdwn0b8pdht9eMgishvk8+F8bal354nhx/xOoTfwiAw==
112 |   dependencies:
113 |     "@algolia/requester-common" "4.20.0"
114 | 
115 | "@algolia/requester-common@4.20.0":
116 |   version "4.20.0"
117 |   resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.20.0.tgz#65694b2263a8712b4360fef18680528ffd435b5c"
118 |   integrity sha512-9h6ye6RY/BkfmeJp7Z8gyyeMrmmWsMOCRBXQDs4mZKKsyVlfIVICpcSibbeYcuUdurLhIlrOUkH3rQEgZzonng==
119 | 
120 | "@algolia/requester-node-http@4.20.0":
121 |   version "4.20.0"
122 |   resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.20.0.tgz#b52b182b52b0b16dec4070832267d484a6b1d5bb"
123 |   integrity sha512-ocJ66L60ABSSTRFnCHIEZpNHv6qTxsBwJEPfYaSBsLQodm0F9ptvalFkHMpvj5DfE22oZrcrLbOYM2bdPJRHng==
124 |   dependencies:
125 |     "@algolia/requester-common" "4.20.0"
126 | 
127 | "@algolia/transporter@4.20.0":
128 |   version "4.20.0"
129 |   resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.20.0.tgz#7e5b24333d7cc9a926b2f6a249f87c2889b944a9"
130 |   integrity sha512-Lsii1pGWOAISbzeyuf+r/GPhvHMPHSPrTDWNcIzOE1SG1inlJHICaVe2ikuoRjcpgxZNU54Jl+if15SUCsaTUg==
131 |   dependencies:
132 |     "@algolia/cache-common" "4.20.0"
133 |     "@algolia/logger-common" "4.20.0"
134 |     "@algolia/requester-common" "4.20.0"
135 | 
136 | "@babel/parser@^7.20.15", "@babel/parser@^7.21.3":
137 |   version "7.22.16"
138 |   resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.16.tgz#180aead7f247305cce6551bea2720934e2fa2c95"
139 |   integrity sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==
140 | 
141 | "@docsearch/css@3.5.2", "@docsearch/css@^3.5.2":
142 |   version "3.5.2"
143 |   resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.5.2.tgz#610f47b48814ca94041df969d9fcc47b91fc5aac"
144 |   integrity sha512-SPiDHaWKQZpwR2siD0KQUwlStvIAnEyK6tAE2h2Wuoq8ue9skzhlyVQ1ddzOxX6khULnAALDiR/isSF3bnuciA==
145 | 
146 | "@docsearch/js@^3.5.2":
147 |   version "3.5.2"
148 |   resolved "https://registry.yarnpkg.com/@docsearch/js/-/js-3.5.2.tgz#a11cb2e7e62890e9e940283fed6972ecf632629d"
149 |   integrity sha512-p1YFTCDflk8ieHgFJYfmyHBki1D61+U9idwrLh+GQQMrBSP3DLGKpy0XUJtPjAOPltcVbqsTjiPFfH7JImjUNg==
150 |   dependencies:
151 |     "@docsearch/react" "3.5.2"
152 |     preact "^10.0.0"
153 | 
154 | "@docsearch/react@3.5.2":
155 |   version "3.5.2"
156 |   resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.5.2.tgz#2e6bbee00eb67333b64906352734da6aef1232b9"
157 |   integrity sha512-9Ahcrs5z2jq/DcAvYtvlqEBHImbm4YJI8M9y0x6Tqg598P40HTEkX7hsMcIuThI+hTFxRGZ9hll0Wygm2yEjng==
158 |   dependencies:
159 |     "@algolia/autocomplete-core" "1.9.3"
160 |     "@algolia/autocomplete-preset-algolia" "1.9.3"
161 |     "@docsearch/css" "3.5.2"
162 |     algoliasearch "^4.19.1"
163 | 
164 | "@esbuild/android-arm64@0.18.20":
165 |   version "0.18.20"
166 |   resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622"
167 |   integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==
168 | 
169 | "@esbuild/android-arm@0.18.20":
170 |   version "0.18.20"
171 |   resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682"
172 |   integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==
173 | 
174 | "@esbuild/android-x64@0.18.20":
175 |   version "0.18.20"
176 |   resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2"
177 |   integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==
178 | 
179 | "@esbuild/darwin-arm64@0.18.20":
180 |   version "0.18.20"
181 |   resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1"
182 |   integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==
183 | 
184 | "@esbuild/darwin-x64@0.18.20":
185 |   version "0.18.20"
186 |   resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d"
187 |   integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==
188 | 
189 | "@esbuild/freebsd-arm64@0.18.20":
190 |   version "0.18.20"
191 |   resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54"
192 |   integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==
193 | 
194 | "@esbuild/freebsd-x64@0.18.20":
195 |   version "0.18.20"
196 |   resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e"
197 |   integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==
198 | 
199 | "@esbuild/linux-arm64@0.18.20":
200 |   version "0.18.20"
201 |   resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0"
202 |   integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==
203 | 
204 | "@esbuild/linux-arm@0.18.20":
205 |   version "0.18.20"
206 |   resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0"
207 |   integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==
208 | 
209 | "@esbuild/linux-ia32@0.18.20":
210 |   version "0.18.20"
211 |   resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7"
212 |   integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==
213 | 
214 | "@esbuild/linux-loong64@0.18.20":
215 |   version "0.18.20"
216 |   resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d"
217 |   integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==
218 | 
219 | "@esbuild/linux-mips64el@0.18.20":
220 |   version "0.18.20"
221 |   resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231"
222 |   integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==
223 | 
224 | "@esbuild/linux-ppc64@0.18.20":
225 |   version "0.18.20"
226 |   resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb"
227 |   integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==
228 | 
229 | "@esbuild/linux-riscv64@0.18.20":
230 |   version "0.18.20"
231 |   resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6"
232 |   integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==
233 | 
234 | "@esbuild/linux-s390x@0.18.20":
235 |   version "0.18.20"
236 |   resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071"
237 |   integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==
238 | 
239 | "@esbuild/linux-x64@0.18.20":
240 |   version "0.18.20"
241 |   resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338"
242 |   integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==
243 | 
244 | "@esbuild/netbsd-x64@0.18.20":
245 |   version "0.18.20"
246 |   resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1"
247 |   integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==
248 | 
249 | "@esbuild/openbsd-x64@0.18.20":
250 |   version "0.18.20"
251 |   resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae"
252 |   integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==
253 | 
254 | "@esbuild/sunos-x64@0.18.20":
255 |   version "0.18.20"
256 |   resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d"
257 |   integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==
258 | 
259 | "@esbuild/win32-arm64@0.18.20":
260 |   version "0.18.20"
261 |   resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9"
262 |   integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==
263 | 
264 | "@esbuild/win32-ia32@0.18.20":
265 |   version "0.18.20"
266 |   resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102"
267 |   integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==
268 | 
269 | "@esbuild/win32-x64@0.18.20":
270 |   version "0.18.20"
271 |   resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d"
272 |   integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==
273 | 
274 | "@jridgewell/sourcemap-codec@^1.4.15":
275 |   version "1.4.15"
276 |   resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
277 |   integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
278 | 
279 | "@types/web-bluetooth@^0.0.17":
280 |   version "0.0.17"
281 |   resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.17.tgz#5c9f3c617f64a9735d7b72a7cc671e166d900c40"
282 |   integrity sha512-4p9vcSmxAayx72yn70joFoL44c9MO/0+iVEBIQXe3v2h2SiAsEIo/G5v6ObFWvNKRFjbrVadNf9LqEEZeQPzdA==
283 | 
284 | "@vue/compiler-core@3.3.4":
285 |   version "3.3.4"
286 |   resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.3.4.tgz#7fbf591c1c19e1acd28ffd284526e98b4f581128"
287 |   integrity sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==
288 |   dependencies:
289 |     "@babel/parser" "^7.21.3"
290 |     "@vue/shared" "3.3.4"
291 |     estree-walker "^2.0.2"
292 |     source-map-js "^1.0.2"
293 | 
294 | "@vue/compiler-dom@3.3.4":
295 |   version "3.3.4"
296 |   resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz#f56e09b5f4d7dc350f981784de9713d823341151"
297 |   integrity sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==
298 |   dependencies:
299 |     "@vue/compiler-core" "3.3.4"
300 |     "@vue/shared" "3.3.4"
301 | 
302 | "@vue/compiler-sfc@3.3.4":
303 |   version "3.3.4"
304 |   resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz#b19d942c71938893535b46226d602720593001df"
305 |   integrity sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==
306 |   dependencies:
307 |     "@babel/parser" "^7.20.15"
308 |     "@vue/compiler-core" "3.3.4"
309 |     "@vue/compiler-dom" "3.3.4"
310 |     "@vue/compiler-ssr" "3.3.4"
311 |     "@vue/reactivity-transform" "3.3.4"
312 |     "@vue/shared" "3.3.4"
313 |     estree-walker "^2.0.2"
314 |     magic-string "^0.30.0"
315 |     postcss "^8.1.10"
316 |     source-map-js "^1.0.2"
317 | 
318 | "@vue/compiler-ssr@3.3.4":
319 |   version "3.3.4"
320 |   resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz#9d1379abffa4f2b0cd844174ceec4a9721138777"
321 |   integrity sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==
322 |   dependencies:
323 |     "@vue/compiler-dom" "3.3.4"
324 |     "@vue/shared" "3.3.4"
325 | 
326 | "@vue/devtools-api@^6.5.0":
327 |   version "6.5.0"
328 |   resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.5.0.tgz#98b99425edee70b4c992692628fa1ea2c1e57d07"
329 |   integrity sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==
330 | 
331 | "@vue/reactivity-transform@3.3.4":
332 |   version "3.3.4"
333 |   resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz#52908476e34d6a65c6c21cd2722d41ed8ae51929"
334 |   integrity sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==
335 |   dependencies:
336 |     "@babel/parser" "^7.20.15"
337 |     "@vue/compiler-core" "3.3.4"
338 |     "@vue/shared" "3.3.4"
339 |     estree-walker "^2.0.2"
340 |     magic-string "^0.30.0"
341 | 
342 | "@vue/reactivity@3.3.4":
343 |   version "3.3.4"
344 |   resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.3.4.tgz#a27a29c6cd17faba5a0e99fbb86ee951653e2253"
345 |   integrity sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==
346 |   dependencies:
347 |     "@vue/shared" "3.3.4"
348 | 
349 | "@vue/runtime-core@3.3.4":
350 |   version "3.3.4"
351 |   resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.3.4.tgz#4bb33872bbb583721b340f3088888394195967d1"
352 |   integrity sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==
353 |   dependencies:
354 |     "@vue/reactivity" "3.3.4"
355 |     "@vue/shared" "3.3.4"
356 | 
357 | "@vue/runtime-dom@3.3.4":
358 |   version "3.3.4"
359 |   resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz#992f2579d0ed6ce961f47bbe9bfe4b6791251566"
360 |   integrity sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==
361 |   dependencies:
362 |     "@vue/runtime-core" "3.3.4"
363 |     "@vue/shared" "3.3.4"
364 |     csstype "^3.1.1"
365 | 
366 | "@vue/server-renderer@3.3.4":
367 |   version "3.3.4"
368 |   resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.3.4.tgz#ea46594b795d1536f29bc592dd0f6655f7ea4c4c"
369 |   integrity sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==
370 |   dependencies:
371 |     "@vue/compiler-ssr" "3.3.4"
372 |     "@vue/shared" "3.3.4"
373 | 
374 | "@vue/shared@3.3.4":
375 |   version "3.3.4"
376 |   resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.3.4.tgz#06e83c5027f464eef861c329be81454bc8b70780"
377 |   integrity sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==
378 | 
379 | "@vueuse/core@10.4.1", "@vueuse/core@^10.4.1":
380 |   version "10.4.1"
381 |   resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-10.4.1.tgz#fc2c8a83a571c207aaedbe393b22daa6d35123f2"
382 |   integrity sha512-DkHIfMIoSIBjMgRRvdIvxsyboRZQmImofLyOHADqiVbQVilP8VVHDhBX2ZqoItOgu7dWa8oXiNnScOdPLhdEXg==
383 |   dependencies:
384 |     "@types/web-bluetooth" "^0.0.17"
385 |     "@vueuse/metadata" "10.4.1"
386 |     "@vueuse/shared" "10.4.1"
387 |     vue-demi ">=0.14.5"
388 | 
389 | "@vueuse/integrations@^10.4.1":
390 |   version "10.4.1"
391 |   resolved "https://registry.yarnpkg.com/@vueuse/integrations/-/integrations-10.4.1.tgz#a48356a0bad49f5e724cd9acaebd73d2b66f22a9"
392 |   integrity sha512-uRBPyG5Lxoh1A/J+boiioPT3ELEAPEo4t8W6Mr4yTKIQBeW/FcbsotZNPr4k9uz+3QEksMmflWloS9wCnypM7g==
393 |   dependencies:
394 |     "@vueuse/core" "10.4.1"
395 |     "@vueuse/shared" "10.4.1"
396 |     vue-demi ">=0.14.5"
397 | 
398 | "@vueuse/metadata@10.4.1":
399 |   version "10.4.1"
400 |   resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-10.4.1.tgz#9d2ff5c67abf17a8c07865c2413fbd0e92f7b7d7"
401 |   integrity sha512-2Sc8X+iVzeuMGHr6O2j4gv/zxvQGGOYETYXEc41h0iZXIRnRbJZGmY/QP8dvzqUelf8vg0p/yEA5VpCEu+WpZg==
402 | 
403 | "@vueuse/shared@10.4.1":
404 |   version "10.4.1"
405 |   resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-10.4.1.tgz#d5ce33033c156efb60664b5d6034d6cd4e2f530c"
406 |   integrity sha512-vz5hbAM4qA0lDKmcr2y3pPdU+2EVw/yzfRsBdu+6+USGa4PxqSQRYIUC9/NcT06y+ZgaTsyURw2I9qOFaaXHAg==
407 |   dependencies:
408 |     vue-demi ">=0.14.5"
409 | 
410 | algoliasearch@^4.19.1:
411 |   version "4.20.0"
412 |   resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.20.0.tgz#700c2cb66e14f8a288460036c7b2a554d0d93cf4"
413 |   integrity sha512-y+UHEjnOItoNy0bYO+WWmLWBlPwDjKHW6mNHrPi0NkuhpQOOEbrkwQH/wgKFDLh7qlKjzoKeiRtlpewDPDG23g==
414 |   dependencies:
415 |     "@algolia/cache-browser-local-storage" "4.20.0"
416 |     "@algolia/cache-common" "4.20.0"
417 |     "@algolia/cache-in-memory" "4.20.0"
418 |     "@algolia/client-account" "4.20.0"
419 |     "@algolia/client-analytics" "4.20.0"
420 |     "@algolia/client-common" "4.20.0"
421 |     "@algolia/client-personalization" "4.20.0"
422 |     "@algolia/client-search" "4.20.0"
423 |     "@algolia/logger-common" "4.20.0"
424 |     "@algolia/logger-console" "4.20.0"
425 |     "@algolia/requester-browser-xhr" "4.20.0"
426 |     "@algolia/requester-common" "4.20.0"
427 |     "@algolia/requester-node-http" "4.20.0"
428 |     "@algolia/transporter" "4.20.0"
429 | 
430 | ansi-sequence-parser@^1.1.0:
431 |   version "1.1.1"
432 |   resolved "https://registry.yarnpkg.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz#e0aa1cdcbc8f8bb0b5bca625aac41f5f056973cf"
433 |   integrity sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==
434 | 
435 | csstype@^3.1.1:
436 |   version "3.1.2"
437 |   resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b"
438 |   integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
439 | 
440 | esbuild@^0.18.10:
441 |   version "0.18.20"
442 |   resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6"
443 |   integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==
444 |   optionalDependencies:
445 |     "@esbuild/android-arm" "0.18.20"
446 |     "@esbuild/android-arm64" "0.18.20"
447 |     "@esbuild/android-x64" "0.18.20"
448 |     "@esbuild/darwin-arm64" "0.18.20"
449 |     "@esbuild/darwin-x64" "0.18.20"
450 |     "@esbuild/freebsd-arm64" "0.18.20"
451 |     "@esbuild/freebsd-x64" "0.18.20"
452 |     "@esbuild/linux-arm" "0.18.20"
453 |     "@esbuild/linux-arm64" "0.18.20"
454 |     "@esbuild/linux-ia32" "0.18.20"
455 |     "@esbuild/linux-loong64" "0.18.20"
456 |     "@esbuild/linux-mips64el" "0.18.20"
457 |     "@esbuild/linux-ppc64" "0.18.20"
458 |     "@esbuild/linux-riscv64" "0.18.20"
459 |     "@esbuild/linux-s390x" "0.18.20"
460 |     "@esbuild/linux-x64" "0.18.20"
461 |     "@esbuild/netbsd-x64" "0.18.20"
462 |     "@esbuild/openbsd-x64" "0.18.20"
463 |     "@esbuild/sunos-x64" "0.18.20"
464 |     "@esbuild/win32-arm64" "0.18.20"
465 |     "@esbuild/win32-ia32" "0.18.20"
466 |     "@esbuild/win32-x64" "0.18.20"
467 | 
468 | estree-walker@^2.0.2:
469 |   version "2.0.2"
470 |   resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
471 |   integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
472 | 
473 | focus-trap@^7.5.2:
474 |   version "7.5.2"
475 |   resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-7.5.2.tgz#e5ee678d10a18651f2591ffb66c949fb098d57cf"
476 |   integrity sha512-p6vGNNWLDGwJCiEjkSK6oERj/hEyI9ITsSwIUICBoKLlWiTWXJRfQibCwcoi50rTZdbi87qDtUlMCmQwsGSgPw==
477 |   dependencies:
478 |     tabbable "^6.2.0"
479 | 
480 | fsevents@~2.3.2:
481 |   version "2.3.3"
482 |   resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
483 |   integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
484 | 
485 | jsonc-parser@^3.2.0:
486 |   version "3.2.0"
487 |   resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76"
488 |   integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==
489 | 
490 | magic-string@^0.30.0:
491 |   version "0.30.3"
492 |   resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.3.tgz#403755dfd9d6b398dfa40635d52e96c5ac095b85"
493 |   integrity sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==
494 |   dependencies:
495 |     "@jridgewell/sourcemap-codec" "^1.4.15"
496 | 
497 | mark.js@8.11.1:
498 |   version "8.11.1"
499 |   resolved "https://registry.yarnpkg.com/mark.js/-/mark.js-8.11.1.tgz#180f1f9ebef8b0e638e4166ad52db879beb2ffc5"
500 |   integrity sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==
501 | 
502 | minisearch@^6.1.0:
503 |   version "6.1.0"
504 |   resolved "https://registry.yarnpkg.com/minisearch/-/minisearch-6.1.0.tgz#6e74e743dbd0e88fa5ca52fef2391e0aa7055252"
505 |   integrity sha512-PNxA/X8pWk+TiqPbsoIYH0GQ5Di7m6326/lwU/S4mlo4wGQddIcf/V//1f9TB0V4j59b57b+HZxt8h3iMROGvg==
506 | 
507 | nanoid@^3.3.6:
508 |   version "3.3.6"
509 |   resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c"
510 |   integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==
511 | 
512 | picocolors@^1.0.0:
513 |   version "1.0.0"
514 |   resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
515 |   integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
516 | 
517 | postcss@^8.1.10, postcss@^8.4.27:
518 |   version "8.4.30"
519 |   resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.30.tgz#0e0648d551a606ef2192a26da4cabafcc09c1aa7"
520 |   integrity sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g==
521 |   dependencies:
522 |     nanoid "^3.3.6"
523 |     picocolors "^1.0.0"
524 |     source-map-js "^1.0.2"
525 | 
526 | preact@^10.0.0:
527 |   version "10.17.1"
528 |   resolved "https://registry.yarnpkg.com/preact/-/preact-10.17.1.tgz#0a1b3c658c019e759326b9648c62912cf5c2dde1"
529 |   integrity sha512-X9BODrvQ4Ekwv9GURm9AKAGaomqXmip7NQTZgY7gcNmr7XE83adOMJvd3N42id1tMFU7ojiynRsYnY6/BRFxLA==
530 | 
531 | rollup@^3.27.1:
532 |   version "3.29.2"
533 |   resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.2.tgz#cbc76cd5b03b9f9e93be991d23a1dff9c6d5b740"
534 |   integrity sha512-CJouHoZ27v6siztc21eEQGo0kIcE5D1gVPA571ez0mMYb25LGYGKnVNXpEj5MGlepmDWGXNjDB5q7uNiPHC11A==
535 |   optionalDependencies:
536 |     fsevents "~2.3.2"
537 | 
538 | shiki@^0.14.4:
539 |   version "0.14.4"
540 |   resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.14.4.tgz#2454969b466a5f75067d0f2fa0d7426d32881b20"
541 |   integrity sha512-IXCRip2IQzKwxArNNq1S+On4KPML3Yyn8Zzs/xRgcgOWIr8ntIK3IKzjFPfjy/7kt9ZMjc+FItfqHRBg8b6tNQ==
542 |   dependencies:
543 |     ansi-sequence-parser "^1.1.0"
544 |     jsonc-parser "^3.2.0"
545 |     vscode-oniguruma "^1.7.0"
546 |     vscode-textmate "^8.0.0"
547 | 
548 | source-map-js@^1.0.2:
549 |   version "1.0.2"
550 |   resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
551 |   integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
552 | 
553 | tabbable@^6.2.0:
554 |   version "6.2.0"
555 |   resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97"
556 |   integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==
557 | 
558 | vite@^4.4.9:
559 |   version "4.4.9"
560 |   resolved "https://registry.yarnpkg.com/vite/-/vite-4.4.9.tgz#1402423f1a2f8d66fd8d15e351127c7236d29d3d"
561 |   integrity sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==
562 |   dependencies:
563 |     esbuild "^0.18.10"
564 |     postcss "^8.4.27"
565 |     rollup "^3.27.1"
566 |   optionalDependencies:
567 |     fsevents "~2.3.2"
568 | 
569 | vitepress@^1.0.0-rc.14:
570 |   version "1.0.0-rc.14"
571 |   resolved "https://registry.yarnpkg.com/vitepress/-/vitepress-1.0.0-rc.14.tgz#d014df7890ca26d3ef73a5c05b2a73cc659e961c"
572 |   integrity sha512-yChIeXOAcNvVnSVjhziH1vte0uhKb00PuZf7KdIMfx3ixTMAz73Nn+6gREvCv0SdH+anteGUKz5eljv0ygcgGQ==
573 |   dependencies:
574 |     "@docsearch/css" "^3.5.2"
575 |     "@docsearch/js" "^3.5.2"
576 |     "@vue/devtools-api" "^6.5.0"
577 |     "@vueuse/core" "^10.4.1"
578 |     "@vueuse/integrations" "^10.4.1"
579 |     focus-trap "^7.5.2"
580 |     mark.js "8.11.1"
581 |     minisearch "^6.1.0"
582 |     shiki "^0.14.4"
583 |     vite "^4.4.9"
584 |     vue "^3.3.4"
585 | 
586 | vscode-oniguruma@^1.7.0:
587 |   version "1.7.0"
588 |   resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b"
589 |   integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==
590 | 
591 | vscode-textmate@^8.0.0:
592 |   version "8.0.0"
593 |   resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d"
594 |   integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==
595 | 
596 | vue-demi@>=0.14.5:
597 |   version "0.14.6"
598 |   resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.6.tgz#dc706582851dc1cdc17a0054f4fec2eb6df74c92"
599 |   integrity sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==
600 | 
601 | vue@^3.3.4:
602 |   version "3.3.4"
603 |   resolved "https://registry.yarnpkg.com/vue/-/vue-3.3.4.tgz#8ed945d3873667df1d0fcf3b2463ada028f88bd6"
604 |   integrity sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==
605 |   dependencies:
606 |     "@vue/compiler-dom" "3.3.4"
607 |     "@vue/compiler-sfc" "3.3.4"
608 |     "@vue/runtime-dom" "3.3.4"
609 |     "@vue/server-renderer" "3.3.4"
610 |     "@vue/shared" "3.3.4"
611 | 


--------------------------------------------------------------------------------