Блок для продвинутых пользователей для улучшенного понимания, как тут все устроено
Любое сообщение, которое получит ваш бот называется update. Оно оборачивается в обертку, называемой context (ctx). ctx это по сути и есть update объект с некоторыми дополнительными полями для упрощения взаимодействия с ботом (быстрые ответы и тд)
context объект передается всем обработчикам первым аргументом, например в bot.command()
, bot.update()
, bot.message()
и т.д.
Несколько примеров использования ctx:
-
ctx.chat.id
- получение значенияupdate.message.chat.id
-
-- /example foo bar baz bot.command("example", function(ctx) local args = ctx.args() ctx.reply.text( table.concat(args, ":") ) -- foo:bar:baz end)
По своей сути эти фильтры апдейтов. Когда вы пишете bot.command("start", function(ctx) end)
, то добавляете фильтр к вашему боту, который выполнится только если в update найдена команда /start. bot.update(callback, uid)
это тоже фильтр, но который выпоняется всегда.
Доступные хендлеры можно посмотреть в ggram/bot.lua, а также написать свои (например, для перехвата гифок или упоминаний и тд)
Middlewares это когда обработчик событий не просто присылает вам в ответ "Привет", а еще может вмешаться в обработку апдейта, добавив новые данные в context, остановить обработку следующих обработчиков, банально залогировать запрос, ничего не меняя и тд. Все Middlewares это и есть те самые обработчики событий, просто иногда воспринимаются как модули.
Все middlewares выполняются в том порядке, в котором вы их добавили и могут влиять на выполнение последующих
Пример:
-- Перехватывает все запросы к боту и добавляет к контексту ctx.key
bot.update(function(ctx) ctx.key = "value" end, "foo")
-- Выполнится, если вы напишете боту /example
-- И споскольку предыдущий middleware добавил поле key к ctx, то print(ctx.key) выведет "value"
-- Обратите внимание на return false
bot.command("example", function(ctx) print(ctx.key) return false end)
-- Еще один обработчик событий, который не выполнится, если выполнится предыдущий, так как в нем мы сделали return false
bot.update(function(ctx) print("Вы видите этот текст только, если не написали /example") end, "bar")
Middlewares позволяют управлять потоком запросов, модифицируя их на лету. К примеру, можно сделать middleware авторизации, rate-limit запросов, дополнительные методы для context и тд
-- Это middleware
local function attach_player(ctx)
if ctx.message and ctx.message.from then
ctx.steamid = sql.QueryValue("SELECT steamid FROM users WHERE telegram_id = " .. ctx.message.from.id) -- таблица выдумана
ctx.player = player.GetBySteamID(ctx.steamid) -- Если игрок не на сервере, то тут будет false
end
end
-- Это тоже middleware
local function restrict_access_for_non_admins(ctx)
if not (ctx.player and ctx.player:IsSuperAdmin()) then
ctx.reply.text("Бот только для администраторов")
return false
end
end
-- handlers
bot.update(attach_player, "attach_player")
bot.update(restrict_access_for_non_admins, "check_access")
bot.command("ban", function(ctx)
ctx.reply.text("Вы админ, если смогли выполнить эту команду")
end)
Примеры некоторых подключаемых middlewares можно найти в папке /middlewares.
Этот объект упрощает отправку запросов к серверам Telegram. Отправка текста, изображений, стикеров, удаление сообщений и тд происходит через reply.
.reply присваивается большинству updates и получить к нему доступ можно через ctx.reply
Если нужно выполнить запрос, например отправить сообщение не из контекста, используйте
bot.reply(chat_id).text("Hello")
Доступные методы можно увидеть в файле reply.lua.
Если остались вопросы, вы можете задать их в Telegram @amd_nick или создать Issue