API Бота
Основная информация
Telegram боты взаимодействуют с серверами Telegram посредством HTTP-запросов. Telegram Bot API — это спецификация этого интерфейса, то есть длинный список методов и типов данных, обычно называемый документацией. Он определяет все, что могут делать Telegram боты. Вы можете найти его по ссылке на вкладке “Ресурсы” в разделе “Telegram”.
Настройку можно представить следующим образом:
Ваш бот на grammY <———HTTP———> API Бота <———MTProto———> Telegram
Другими словами: когда ваш бот отправляет сообщение, оно будет отправлено в виде HTTP запроса на сервер Bot API. Этот сервер расположен по адресу api
. Он преобразует запрос в родной протокол Telegram под названием MTProto и отправит запрос на бэкенд Telegram, который позаботится об отправке сообщения пользователю.
Аналогично, когда пользователь отвечает, используется обратный путь.
Когда вы запускаете бота, вам нужно решить, как отправлять обновления через HTTP-соединение. Это можно сделать с помощью long polling или вебхуков.
Вы также можете самостоятельно разместить сервер Bot API. В основном это полезно для отправки больших файлов или для уменьшения задержки.
Вызов API бота
API Бота — это то, что определяет, что могут и чего не могут делать боты. Каждый метод Bot API имеет эквивалент в grammY, и мы следим за тем, чтобы библиотека всегда была синхронизирована с последними и самыми лучшими функциями для ботов. Пример: send
в документации Telegram Bot API и в документации grammY API.
Вызов метода
Вы можете вызывать методы API через bot
, или эквивалентно через ctx
:
import { Api, Bot } from "grammy";
const bot = new Bot("");
async function sendHelloTo12345() {
// Отправляет сообщение по ID 12345
await bot.api.sendMessage(12345, "Привет!");
// Отправьте сообщение и сохраните ответ, который содержит информацию об отправленном сообщении.
const sentMessage = await bot.api.sendMessage(12345, "Привет снова!");
console.log(sentMessage.message_id);
// Отправка сообщения без объекта `bot`.
const api = new Api(""); // <-- поместите токен вашего бота между "".
await api.sendMessage(12345, "Йоу!");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const { Api, Bot } = require("grammy");
const bot = new Bot("");
async function sendHelloTo12345() {
// Отправляет сообщение по ID 12345
await bot.api.sendMessage(12345, "Привет!");
// Отправьте сообщение и сохраните ответ, который содержит информацию об отправленном сообщении.
const sentMessage = await bot.api.sendMessage(12345, "Привет снова!");
console.log(sentMessage.message_id);
// Отправка сообщения без объекта `bot`.
const api = new Api(""); // <-- поместите токен вашего бота между "".
await api.sendMessage(12345, "Йоу!");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { Api, Bot } from "https://deno.land/x/grammy@v1.30.0/mod.ts";
const bot = new Bot("");
async function sendHelloTo12345() {
// Отправляет сообщение по ID 12345
await bot.api.sendMessage(12345, "Привет!");
// Отправьте сообщение и сохраните ответ, который содержит информацию об отправленном сообщении.
const sentMessage = await bot.api.sendMessage(12345, "Привет снова!");
console.log(sentMessage.message_id);
// Отправка сообщения без объекта `bot`.
const api = new Api(""); // <-- поместите токен вашего бота между "".
await api.sendMessage(12345, "Йоу!");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Обратите внимание, что
bot
— это просто экземпляр.api Api
, который предварительно сконструирован для вас для удобства. Заметьте также, что если у вас есть доступ к объекту контекста (т.е. вы находитесь внутри обработчика сообщений), всегда предпочтительнее вызыватьctx
или одно из доступных действий..api
Хотя экземпляры Api
охватывают весь Bot API, они иногда немного изменяют сигнатуры функций, чтобы сделать их более удобными для использования. Строго говоря, все методы Bot API ожидают JSON-объект с рядом свойств. Однако обратите внимание, что send
в приведенном выше примере кода получает два аргумента - идентификатор чата и текст. grammY знает, что эти два значения относятся к свойствам chat
и text
соответственно, и создаст для вас правильный JSON-объект.
Как уже упоминалось ранее, вы можете указать другие параметры в третьем аргументе типа Other
:
async function sendHelloTo12345() {
await bot.api.sendMessage(12345, "<i>Привет!</i>", {
parse_mode: "HTML",
});
}
2
3
4
5
Более того, grammY заботится о многочисленных технических деталях, чтобы упростить использование API. Например, некоторые специфические свойства в некоторых специфических методах должны быть преобразованы в строку (JSON
) перед отправкой. Об этом легко забыть, сложно отладить, и это нарушает вывод типов. grammY позволяет задавать объекты последовательно во всем API и гарантирует, что нужные свойства будут подстроены для API на лету перед отправкой.
Определения типов для Bot API
grammY поставляется с полным покрытием типов для Bot API. Репозиторий @grammyjs
содержит определения типов, которые grammY использует внутри. Эти определения типов также напрямую экспортируются из основного пакета grammy
, так что вы можете использовать их в своем собственном коде.
Определения типов в Deno
В Deno вы можете просто импортировать определения типов из файла types
, который находится рядом с файлом mod
:
import { type Chat } from "https://deno.land/x/grammy@v1.30.0/types.ts";
Определения типов в Node.js
В Node.js все гораздо сложнее. Вам нужно импортировать типы из grammy
. Например, вы получаете доступ к типу Chat
следующим образом:
import { type Chat } from "grammy/types";
Однако официально Node.js поддерживает импорт из подпутей только начиная с Node.js 16. Следовательно, TypeScript требует, чтобы module
был установлен на node16
или nodenext
. Настройте свой tsconfig
соответствующим образом и добавьте выделенную строку:
{
"compilerOptions": {
// ...
"moduleResolution": "node16"
// ...
}
}
2
3
4
5
6
7
В некоторых случаях это может работать и без внесения изменений в конфигурацию TypeScript.
Неправильное автодополнение на Node.js
Если вы не измените файл tsconfig
, как описано выше, может случиться так, что ваш редактор кода предложит в автодополнении импортировать типы из grammy
или что-то в этом роде. Все пути, начинающиеся с grammy
, являются внутренними. Не используйте их. Они могут быть произвольно изменены в любой момент времени, поэтому мы настоятельно рекомендуем вам импортировать типы из grammy
.
Выполнение необработанных вызовов API
Бывают случаи, когда вы хотите использовать оригинальные сигнатуры функций, но при этом полагаться на удобство API grammY (например, авто форматирование JSON там, где это необходимо). grammY поддерживает это через свойства bot
(или ctx
).
Вы можете вызывать методы raw следующим образом:
async function sendHelloTo12345() {
await bot.api.raw.sendMessage({
chat_id: 12345,
text: "<i>Привет!</i>",
parse_mode: "HTML",
});
}
2
3
4
5
6
7
По сути, все параметры сигнатуры функции объединяются с объектом options
, когда вы используете необработанный API.
Выбор места расположения дата-центра
Пропустите до конца страницы, если вы только начинаете.
Если вы хотите уменьшить сетевую задержку вашего бота, важно, где вы его разместите.
Сервер Bot API, расположенный за api
, находится в Амстердаме, Нидерланды. Поэтому лучшим местом для запуска бота является Амстердам.
Сравнение хостингов
Возможно, вас заинтересует наше сравнение хостинг
Однако может найтись еще более подходящее место для запуска бота, хотя это потребует гораздо больше усилий.
Помните что API сервер бота на самом деле не содержит вашего бота. Он только ретранслирует запросы, переводит между HTTP и MTProto и так далее. API сервер бота может находиться в Амстердаме, но серверы Telegram распределены по трем разным местам:
- Амстердам, Нидерланды
- Майами, Флорида, США
- Сингапур
Таким образом, когда API сервер бота отправляет запрос на сервера Telegram, ему может потребоваться отправить данные через полмира. Произойдет это или нет, зависит от дата центра самого бота. дата-центр бота — это тот же дата-центр, что и у пользователя, создавшего бота. дата-центр пользователя зависит от многих факторов, в том числе от его местонахождения.
Вот что можно сделать, если вы хотите еще больше уменьшить задержку.
- Свяжитесь с @where
_is и отправьте файл, который был загружен под вашей учетной записью. В нем будет указано местоположение вашего аккаунта. Это также местоположение вашего бота._my _dc _bot - Если ваш дата-центр находится в Амстердаме, вам ничего не нужно делать. В противном случае продолжайте читать.
- Купите VPS в месте расположения вашего дата-центра.
- Запустите локальный Bot API
-сервер на этом VPS. - Разместите своего бота в том же месте, что и ваш дата-центр.
Таким образом, каждый запрос будет проходить только кратчайшее расстояние между Telegram и вашим ботом.
Запуск локального API сервера бота
У запуска локального API сервера бота есть два основных преимущества.
- Ваш бот может отправлять и получать большие файлы.
- У вашего бота может быть меньше задержек при работе в сети (см. выше).
Другие незначительные преимущества перечислены здесь.
Вы должны запускать API сервер бота на VPS. Если вы попытаетесь запустить его в другом месте, он будет падать или терять сообщения.
Вы также должны скомпилировать API сервер бота с нуля. Если у вас есть опыт компиляции больших проектов на C++, это будет полезно, но если его нет, то вы можете просто скопировать инструкции по сборке и надеяться, что они сработают.
Самый простой способ запустить API сервер бота - следовать генератору инструкций по сборке, предоставленному Telegram.
Дополнительные параметры можно найти в репозитории API сервера бота.
Сборка сервера дает вам исполняемый файл, который можно запустить.
Вы получили этот исполняемый файл? Теперь вы можете перенести своего бота на локальный API сервер бота!
Выход из API сервера бота
Сначала вам нужно выйти из API сервера бота. Возьмите этот URL и вставьте его в браузер (не забудьте заменить <токен>
на ваш токен бота):
https://api.telegram.org/bot<токен>/logOut
Вы должны увидеть {"ok":
.
Настройка grammY для использования локального API сервера бота
Далее вы можете указать grammY использовать ваш локальный API сервер бота вместо api
. Допустим, ваш бот работает на localhost
на порту 8081. Тогда вам следует использовать следующую конфигурацию.
const bot = new Bot("", { // <-- используйте тот же токен, что и раньше
client: { apiRoot: "http://localhost:8081" },
});
2
3
Теперь вы можете снова запустить своего бота. Он будет использовать локальный API сервер.
Если что-то пошло не так, и вы не знаете, как это исправить, сколько бы вы ни гуглили, не стесняйтесь присоединяться к нашему чату сообщества и просить помощи! Мы знаем о вашей ошибке даже меньше, чем вы, но наверняка сможем ответить на ваши вопросы.
Помните, что вам также придется настроить свой код для работы с локальными путями к файлам вместо URL, указывающих на ваши файлы. Например, вызов get
даст вам file
, который указывает на ваш локальный диск, а не на файл, который сначала нужно загрузить из Telegram. Аналогично, у плагина files есть метод get
, который больше не будет возвращать URL, а вместо него - абсолютный путь к файлу.
Если вы захотите снова изменить эту конфигурацию и перенести бота на другой сервер, обязательно прочитайте этот раздел в README репозитория API сервера бота.