Руководство по плагинам grammY для чайников
Если вы хотите разработать свой собственный плагин и опубликовать его, или если вы хотите узнать, как плагины grammY работают под капотом, это место для вас!
Обратите внимание, что уже есть краткое описание grammY
-плагинов и того, что они делают. Эта статья - глубокое погружение в их внутреннюю работу.
Типы плагинов в grammY
В grammY есть два основных типа плагинов:
- Middleware-плагины: Единственная задача плагина - вернуть функцию middleware function, которую можно передать боту grammY.
- Плагины-трансформеры: Единственная задача плагина - вернуть функцию transformer function, которая может быть передана боту grammY.
Однако иногда встречаются плагины, которые выполняют обе задачи. Существуют и другие плагины, которые не являются ни middleware, ни трансформирующими функциями, но мы все равно будем называть их плагинами, поскольку они расширяют grammY различными способами.
Правила внесения изменений
Вы можете публиковать свои плагины в одной из следующих форм:
- Публикация в качестве официального плагина.
- Публикация в качестве третьего плагина.
Если вы решите опубликовать свои плагины от третьего лица, мы все равно сможем предложить вам заметное место на этом сайте. Однако мы предпочитаем, чтобы вы опубликовали свой плагин под именем grammyjs на GitHub, тем самым сделав его официальным плагином. В этом случае вам будет предоставлен доступ к GitHub и npm для публикации. Кроме того, вы будете нести ответственность за поддержку своего кода.
Прежде чем приступить к рассмотрению практических примеров, следует обратить внимание на некоторые правила, если вы хотите, чтобы ваши плагины были размещены на этом сайте.
- Иметь файл README на GitHub (и npm) с короткими и понятными инструкциями по использованию.
- Объясните назначение вашего плагина и как его использовать, добавив страницу в документацию. (Мы можем создать страницу для вас, если вы не знаете, как это сделать).
- Выберите лицензию, например MIT или ISC.
Наконец, вы должны знать, что хотя grammY поддерживает как Node.js, так и Deno, это проект, ориентированный на Deno, и мы также поощряем вас писать свои плагины для Deno (и впоследствии в стиле!). Существует удобный инструмент deno2node, который переносит ваш код из Deno в Node.js, так что мы можем поддерживать обе платформы одинаково хорошо. Поддержка Deno является строгим требованием только для официальных плагинов, но не для сторонних. Тем не менее, очень рекомендуем попробовать Deno. Вы не захотите возвращаться назад.
Разработка фиктивного плагина Middleware
Предположим, мы хотим разработать плагин, который отвечает только определенным пользователям! Например, мы можем решить отвечать только тем, чье имя содержит определенное слово. Для всех остальных бот просто откажется работать.
Вот фиктивный пример:
// plugin.ts
// Импорт типов из grammY (мы реэкспортируем их в `deps.deno.ts`).
import type { Context, Middleware, NextFunction } from "./deps.deno.ts";
// Ваш плагин может иметь одну основную функцию, которая создает middleware
export function onlyAccept<C extends Context>(str: string): Middleware<C> {
// Создавайте и возвращайте middleware
return async (ctx, next) => {
// Получение имени пользователя.
const name = ctx.from?.first_name;
// Пропустите все подходящие обновления.
if (name === undefined || name.includes(str)) {
// Передача потока управления последующему middleware
await next();
} else {
// Скажите им, что они нам не нравятся.
await ctx.reply(`Я с тобой не разговариваю! Тебе наплевать на ${str}!`);
}
};
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Теперь его можно использовать в настоящем боте:
// Здесь код плагина находится в файле под названием `plugin.ts`.
import { onlyAccept } from "./plugin.ts";
import { Bot } from "./deps.deno.ts";
const bot = new Bot("");
bot.use(onlyAccept("grammY"));
bot.on("message", (ctx) => ctx.reply("Вы передали плагин middleware"));
bot.start();
2
3
4
5
6
7
8
9
10
11
Вуаля! У вас есть плагин, верно? Ну, не так быстро. Нам еще нужно упаковать его, но перед этим давайте рассмотрим плагины-трансформеры.
Проектирование плагина фиктивного трансформатора
Представьте, что вы пишете плагин, который автоматически отправляет соответствующее действие чата всякий раз, когда бот отправляет документ. Это значит, что пока ваш бот отправляет файл, пользователи будут автоматически видеть статус “отправляю файл…”. Довольно круто, правда?
// plugin.ts
import type { Transformer } from "./deps.deno.ts";
// Основная функция плагина
export function autoChatAction(): Transformer {
// Создайте и верните трансформирующую функцию
return async (prev, method, payload, signal) => {
// Сохраните обработчик установленного интервала, чтобы мы могли очистить его позже.
let handle: ReturnType<typeof setTimeout> | undefined;
if (method === "sendDocument" && "chat_id" in payload) {
// Теперь мы знаем, что документ отправлен.
const actionPayload = {
chat_id: payload.chat_id,
action: "upload_document",
};
// Повторная установка действия чата во время загрузки файла.
handle ??= setInterval(() => {
prev("sendChatAction", actionPayload).catch(console.error);
}, 5000);
}
try {
// Запустите реальный метод из бота.
return await prev(method, payload, signal);
} finally {
// Очистите интервал, чтобы мы перестали отправлять действие чата клиенту.
clearInterval(handle);
}
};
}
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
Теперь мы можем использовать его в реальном боте:
import { Bot, InputFile } from "./deps.deno.ts";
// Код плагина находится в файле `plugin.ts`.
import { autoChatAction } from "./plugin.ts";
// Создайте экземпляр бота.
const bot = new Bot("");
// Используйте плагин.
bot.api.config.use(autoChatAction());
bot.hears("отправь мне документ", async (ctx) => {
// Если пользователь отправит эту команду, мы вышлем ему pdf-файл (в демонстрационных целях)
await ctx.replyWithDocument(new InputFile("/tmp/document.pdf"));
});
// Запустите бота
bot.start();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Теперь каждый раз, когда мы отправляем документ, действие чата upload
будет отправляться нашему клиенту. Обратите внимание, что это было сделано в демонстрационных целях. Telegram рекомендует использовать действия чата только в тех случаях, когда “ответ от бота займет заметное количество времени”. Вероятно, вам не нужно устанавливать статус, если файл очень маленький, поэтому здесь можно провести некоторую оптимизацию.
Извлечение в плагин
Какой бы тип плагина вы ни создали, его нужно упаковать в отдельный пакет. Это довольно простая задача. Нет никаких особых правил, как это сделать, и npm — это ваша устрица, но для того, чтобы все было организовано, мы предлагаем вам шаблон. Вы можете скачать код из нашего репозитория шаблонов плагинов на Git
Первоначально предложенная структура папок:
plugin-template/
├─ src/
│ ├─ deps.deno.ts
│ ├─ deps.node.ts
│ └─ index.ts
├─ package.json
├─ tsconfig.json
└─ README.md
deps
и deps
: Это для разработчиков, которые хотят написать плагин для Deno, а затем переписать его на Node.js. Как уже упоминалось, мы используем инструмент deno2node
для перевода нашего кода Deno в Node.js. В deno2node
есть функция, которая позволяет вам предоставлять ему файлы, специфичные для времени выполнения. Эти файлы должны находиться рядом друг с другом и следовать структуре имен *
и *
, как объясняется в документации. Вот почему существует два файла: deps
и deps
. Если есть какие-либо специфические для Node.js зависимости, поместите их в deps
, в противном случае оставьте его пустым.
Примечание: Вы также можете использовать другие инструменты, такие как deno dnt, для передачи кода Deno или использования других структур папок. Инструментарий, который вы используете, не имеет значения, главное, что писать код для Deno стало лучше и проще.
tsconfig
: Это файл конфигурации компилятора TypeScript, используемый deno2node
для компиляции вашего кода. В качестве рекомендации в репозитории предоставлен файл по умолчанию. Он соответствует конфигурации TypeScript, которую Deno использует внутри, и мы рекомендуем вам придерживаться этого.
package
: Файл package.json для npm-версии вашего плагина. Не забудьте изменить его в соответствии с вашим проектом.
README
: Инструкции по использованию плагина. Обязательно измените его в соответствии с вашим проектом.
index
: Файл, содержащий вашу логику работу, то есть основной код плагина.
Существует шаблон
Если вы хотите разработать плагин для grammY и не знаете, с чего начать, мы настоятельно рекомендуем воспользоваться кодом шаблона в нашем репозитории. Вы можете клонировать код для себя и начать кодить, основываясь на том, что было описано в этой статье. Этот репозиторий также содержит некоторые дополнительные файлы, такие как .editorconfig
, LICENSE
, .gitignore
и т.д., но вы можете удалить их.
Мне не нравится Deno
Что ж, вы упускаете возможность! Но вы также можете писать свои плагины только для Node.js. Вы всё равно можете опубликовать плагин и включить его в список сторонних плагинов на этом сайте. В этом случае вы можете использовать любую структуру папок, которая вам нравится (если она организована как любой другой проект npm). Просто установите grammY через npm с помощью npm install grammy
и начинайте кодить.
Как подать заявку?
Если у вас есть готовый плагин, вы можете просто отправить запрос на выгрузку на GitHub (в соответствии с Правилами внесения изменений) или сообщить нам в чат коммьюнити для получения дальнейшей помощи.