2021-08-16 08:47:49 +00:00
|
|
|
--[[ Core file
|
|
|
|
-- (c) Er2 2021 <er2@dismail.de>
|
|
|
|
-- Zlib License
|
|
|
|
--]]
|
|
|
|
|
|
|
|
local tools = require 'api.tools'
|
|
|
|
local api = require 'api.api'
|
|
|
|
api.__index = api
|
|
|
|
|
2022-02-13 12:22:12 +00:00
|
|
|
api.parseArgs = tools.parseArgs
|
|
|
|
api.unparseArgs = tools.unparseArgs
|
|
|
|
|
2021-08-16 08:47:49 +00:00
|
|
|
function api:_ev(t, i, name, ...)
|
|
|
|
local v = t[i]
|
|
|
|
if v.name == name then
|
|
|
|
v.fn(self, ...)
|
|
|
|
if v.type == 'once' then table.remove(t, i) end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- UPDATES --
|
|
|
|
function api:getUpdates(lim, offs, tout, allowed)
|
|
|
|
allowed = type(allowed) == 'table' and tools.json.encode(allowed) or allowed
|
|
|
|
return self:request('getUpdates', {
|
|
|
|
timeout = tout,
|
|
|
|
offset = offs,
|
|
|
|
limit = lim,
|
|
|
|
allowed_updates = allowed
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
|
|
|
local function receiveUpdate(self, update)
|
|
|
|
if update.message then
|
|
|
|
local msg = update.message
|
|
|
|
local cmd, to = tools.fetchCmd(msg.text or '')
|
|
|
|
if cmd and (not to or to == self.info.username) then
|
|
|
|
-- need /cmd@bot in groups
|
|
|
|
if (msg.chat.type == 'group' or msg.chat.type == 'supergroup')
|
|
|
|
and not to then return end
|
|
|
|
|
2022-02-12 18:46:36 +00:00
|
|
|
-- remove needn't text
|
2021-08-16 08:47:49 +00:00
|
|
|
msg.text = msg.text:sub(#cmd + #(to or '') + 3)
|
2022-02-13 12:22:12 +00:00
|
|
|
local args = {}
|
|
|
|
for v in msg.text:gmatch '%S+' do table.insert(args, v) end
|
2021-08-16 08:47:49 +00:00
|
|
|
|
|
|
|
msg.cmd = cmd
|
|
|
|
msg.args = args
|
|
|
|
|
|
|
|
return self:emit('command', msg)
|
|
|
|
elseif cmd then return end
|
|
|
|
|
|
|
|
self:emit('message', msg)
|
|
|
|
|
|
|
|
elseif update.edited_message then
|
|
|
|
self:emit('messageEdit', update.edited_message)
|
|
|
|
|
|
|
|
elseif update.channel_post then self:emit('channelPost', update.channel_post)
|
|
|
|
elseif update.edited_channel_post then self:emit('channelPostEdit', update.edited_channel_post)
|
|
|
|
|
|
|
|
elseif update.poll then self:emit('poll', update.poll)
|
|
|
|
elseif update.poll_answer then self:emit('pollAnswer', update.poll_answer)
|
|
|
|
|
|
|
|
elseif update.callback_query then self:emit('callbackQuery', update.callback_query)
|
|
|
|
elseif update.inline_query then self:emit('inlineQuery', update.inline_query)
|
|
|
|
elseif update.shipping_query then self:emit('shippingQuery', update.shipping_query)
|
|
|
|
elseif update.pre_checkout_query then self:emit('preCheckoutQuery', update.pre_checkout_query)
|
|
|
|
|
|
|
|
elseif update.chosen_inline_result then self:emit('inlineResult', update.chosen_inline_result)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function api:_getUpd(lim, offs, ...)
|
|
|
|
local u, ok = self:getUpdates(lim, offs, ...)
|
2022-01-31 16:44:24 +00:00
|
|
|
if not ok then
|
|
|
|
-- fallback if very long message
|
|
|
|
return offs + 1
|
|
|
|
end
|
2021-08-16 08:47:49 +00:00
|
|
|
if not ok or not u or (u and type(u) ~= 'table') or not u.result then return end
|
|
|
|
for _, v in pairs(u.result) do
|
|
|
|
offs = v.update_id + 1
|
|
|
|
if type(v) == 'table' then
|
|
|
|
self:emit('update', v)
|
|
|
|
receiveUpdate(self, v)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return offs
|
|
|
|
end
|
|
|
|
|
|
|
|
function api:_loop(lim, offs, ...)
|
|
|
|
while api.runs do
|
|
|
|
local o = self:_getUpd(lim, offs, ...)
|
|
|
|
offs = o and o or offs
|
|
|
|
end
|
|
|
|
self:getUpdates(lim, offs, ...)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- RUN --
|
|
|
|
function api:run(lim, offs, tout, al)
|
|
|
|
lim = tonumber(lim) or 1
|
|
|
|
offs = tonumber(offs) or 0
|
|
|
|
tout = tonumber(tout) or 0
|
|
|
|
|
|
|
|
self.runs = true
|
|
|
|
self:emit 'ready'
|
|
|
|
|
|
|
|
self.co = coroutine.create(api._loop)
|
|
|
|
coroutine.resume(self.co, self, lim, tout, offs, al)
|
|
|
|
end
|
|
|
|
|
|
|
|
function api:destroy() self.runs = false end
|
|
|
|
|
|
|
|
function api:login(token, thn)
|
|
|
|
self.token = assert(token or self.token, 'Provide token!')
|
|
|
|
|
|
|
|
repeat
|
|
|
|
local r, o = self:getMe()
|
|
|
|
if o and r then self.info = r end
|
|
|
|
until (self.info or {}).result
|
|
|
|
|
|
|
|
self.info = self.info.result
|
|
|
|
self.info.name = self.info.first_name
|
|
|
|
|
|
|
|
if type(thn) == 'function' then thn(self) end
|
|
|
|
|
|
|
|
if not self.nr then self:run() end
|
|
|
|
end
|
|
|
|
|
|
|
|
return function(opts)
|
|
|
|
if not token or type(token) ~= 'string' then token = nil end
|
|
|
|
|
|
|
|
local self = setmetatable({}, api)
|
|
|
|
if type(opts) == 'table' then
|
|
|
|
if opts.token then self.token = opts.token end
|
|
|
|
if opts.norun then self.nr = true end
|
|
|
|
if not opts.noinl then
|
|
|
|
self.inline = require('etc.api.inline')(self)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return self
|
|
|
|
end
|