add more methods, inline queries

This commit is contained in:
Er2 2021-08-15 20:01:35 +03:00
parent a303c6d0d0
commit 141bc4b161
5 changed files with 221 additions and 22 deletions

View file

@ -3,15 +3,23 @@
-- Zlib License -- Zlib License
--]] --]]
local tools =require 'etc.api.tools' local tools = require 'etc.api.tools'
local json = require 'etc.json' local json = require 'etc.json'
local events=require 'etc.events' local events = require 'etc.events'
local api = { local api = {
request = function(s, ...) return tools.request(s.token, ...) end, request = function(s, ...) return tools.request(s.token, ...) end
} }
api.__index = api -- Make class api.__index = api -- Make class
events(api) -- inheritance
events(api) -- inheritance -- parse arguments
local function argp(cid, rmp, pmod, dwp)
return
type(cid) == 'table' and cid.chat.id or cid,
type(rmp) == 'table' and json.encode(rmp) or rmp,
(type(pmod) == 'boolean' and pmod == true) and 'MarkdownV2' or pmod,
dwp == nil and true or dwp
end
-- Getters without params -- Getters without params
@ -25,12 +33,9 @@ function api:getChat(cid) return self:request('getChat', {chat_id = cid}) end
-- Setters -- Setters
function api:send(msg, txt, pmod, dwp, dnot, rtmid, rmp) function api:send(msg, txt, pmod, dwp, dnot, rtmid, rmp)
rmp = type(rmp) == 'table' and json.encode(rmp) or rmp msg, rmp, pmod, dwp = argp(msg, rmp, pmod, dwp)
msg = (type(msg) == 'table' and msg.chat and msg.chat.id) and msg.chat.id or msg
pmod = (type(pmod) == 'boolean' and pmod == true) and 'markdown' or pmod
if dwp == nil then dwp = true end
if txt and #txt > 4096 then if txt and #txt >= 4096 then
txt = txt:sub(0, 4092) .. '...' txt = txt:sub(0, 4092) .. '...'
end end
@ -46,10 +51,7 @@ function api:send(msg, txt, pmod, dwp, dnot, rtmid, rmp)
end end
function api:reply(msg, txt, pmod, dwp, rmp, dnot) function api:reply(msg, txt, pmod, dwp, rmp, dnot)
if type(msg) ~= 'table' or not msg.chat or not msg.chat.id or not msg.message_id then return false end _, rmp, pmod, dwp = argp(msg, rmp, pmod, dwp)
rmp = type(rmp) == 'table' and json.encode(rmp) or rmp
pmod = (type(pmod) == 'boolean' and pmod == true) and 'markdown' or pmod
return self:request('sendMessage', { return self:request('sendMessage', {
chat_id = msg.chat.id, chat_id = msg.chat.id,
text = txt, text = txt,
@ -70,9 +72,33 @@ function api:forward(cid, frcid, mid, dnot)
}) })
end end
function api:sendPhoto(cid, f, cap, pmod, dnot, rtmid, rmp)
cid, rmp, pmod = argp(cid, rmp, pmod)
return self:request('sendPhoto', {
chat_id = cid,
caption = cap,
parse_mode = pmod,
disable_notification = dnot,
reply_to_message_id = rtmid,
reply_markup = rmp,
}, { photo = f })
end
function api:sendDocument(cid, f, cap, pmod, dnot, rtmid, rmp)
cid, rmp, pmod = argp(cid, rmp, pmod)
return self:request('sendDocument', {
chat_id = cid,
caption = cap,
parse_mode = pmod,
disable_notification = dnot,
reply_to_message_id = rtmid,
reply_markup = rmp,
}, { document = f })
end
function api:sendPoll(cid, q, opt, anon, ptype, mansw, coptid, expl, pmode, oper, cdate, closed, dnot, rtmid, rmp) function api:sendPoll(cid, q, opt, anon, ptype, mansw, coptid, expl, pmode, oper, cdate, closed, dnot, rtmid, rmp)
cid, rmp, pmode = argp(cid, rmp, pmode)
opt = type(opt) == 'string' and opt or json.encode(opt) opt = type(opt) == 'string' and opt or json.encode(opt)
rmp = type(rmp) == 'table' and json.encode(rmp) or rmp
anon = type(anon) == 'boolean' and anon or false anon = type(anon) == 'boolean' and anon or false
mansw = type(mansw) == 'boolean' and mansw or false mansw = type(mansw) == 'boolean' and mansw or false
return self:request('sendPoll', { return self:request('sendPoll', {
@ -94,6 +120,16 @@ function api:sendPoll(cid, q, opt, anon, ptype, mansw, coptid, expl, pmode, oper
}) })
end end
function api:answerCallback(id, txt, alrt, url, ctime)
return self:request('answerCallbackQuery', {
callback_query_id = id,
text = txt,
show_alert = alrt,
url = url,
cache_time = ctime,
})
end
function api:setMyCommands(cmds) function api:setMyCommands(cmds)
return self:request('setMyCommands', { commands = json.encode(cmds) }) return self:request('setMyCommands', { commands = json.encode(cmds) })
end end

View file

@ -27,8 +27,6 @@ function api:getUpdates(lim, offs, tout, allowed)
end end
local function receiveUpdate(self, update) local function receiveUpdate(self, update)
if update then self:emit('update', update) end
if update.message then if update.message then
local msg = update.message local msg = update.message
local cmd, to = tools.fetchCmd(msg.text or '') local cmd, to = tools.fetchCmd(msg.text or '')
@ -72,7 +70,10 @@ function api:_getUpd(lim, offs, ...)
if not ok or not u or (u and type(u) ~= 'table') or not u.result then return end 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 for _, v in pairs(u.result) do
offs = v.update_id + 1 offs = v.update_id + 1
receiveUpdate(self, v) if type(v) == 'table' then
self:emit('update', v)
receiveUpdate(self, v)
end
end end
return offs return offs
end end
@ -92,7 +93,7 @@ function api:run(lim, offs, tout, al)
tout = tonumber(tout) or 0 tout = tonumber(tout) or 0
self.runs = true self.runs = true
self:emit('ready') self:emit 'ready'
self.co = coroutine.create(api._loop) self.co = coroutine.create(api._loop)
coroutine.resume(self.co, self, lim, tout, offs, al) coroutine.resume(self.co, self, lim, tout, offs, al)
@ -123,6 +124,9 @@ return function(opts)
if type(opts) == 'table' then if type(opts) == 'table' then
if opts.token then self.token = opts.token end if opts.token then self.token = opts.token end
if opts.norun then self.nr = true end if opts.norun then self.nr = true end
if not opts.noinl then
self.inline = require('etc.api.inline')(self)
end
end end
return self return self

156
etc/api/inline.lua Normal file
View file

@ -0,0 +1,156 @@
--[[ Inline query library
-- (c) Er2 2021 <er2@dismail.de>
-- Zlib License
--]]
local inline = {}
inline.__index = inline -- Make class
function inline.query(id, from, q, off, ct, loc)
return {
id = tostring(id),
from = from,
query = q,
offset = off,
chat_type = ct,
location = loc,
}
end
function inline.result(type, id, ...)
type = tostring(type)
local t = setmetatable({
type = type,
id = tostring(tonumber(id) or 1),
}, inline)
local a = {...}
if t.type == 'article' then t.title, t.url, t.hide_url, t.description = table.unpack(a)
elseif t.type == 'photo' then
t.photo_url, t.photo_width, t.photo_height, t.title, t.description,
t.caption, t.parse_mode, t.caption_entities
= table.unpack(a)
elseif t.type == 'gif' or t.type == 'mpeg4_gif' then
local url, width, height, duration
url, width, height, duration, t.title, t.caption, t.parse_mode, t.caption_entities
= table.unpack(a)
if t.type == 'gif' then
t.gif_url, t.gif_width, t.gif_height, t.gif_duration
= url, width, height, duration
else
t.mpeg4_url, t.mpeg4_width, t.mpeg4_height, t.mpeg4_duration
= url, width, height, duration
end
elseif t.type == 'video' then
t.video_url, t.mime_type, t.title, t.caption, t.parse_mode,
t.caption_entities, t.video_width, t.video_height, t.video_duration, t.description
= table.unpack(a)
elseif t.type == 'audio' or t.type == 'voice' then
t.title, t.caption, t.parse_mode, t.caption_entities = table.unpack(a, 2)
if t.type == 'audio' then
t.audio_url, t.performer, t.audio_duration = a[1], a[6], a[7]
else
t.voice_url, t.voice_duration = a[1], a[6]
end
elseif t.type == 'document' then
t.title, t.caption, t.parse_mode, t.caption_entities, t.document_url,
t.mime_type, t.description = table.unpack(a)
elseif t.type == 'location' or t.type == 'venue' then
t.latitude, t.longitude, t.title = table.unpack(a, 1, 3)
if t.type ~= 'venue' then
t.horizontal_accurancy, t.live_period, t.heading, t.proximity_alert_radius
= table.unpack(a, 4, 7)
else
t.address, t.foursquare_id, t.foursquare_type, t.google_place_id, t.google_place_type
= table.unpack(a, 4, 8)
end
elseif t.type == 'contact' then
t.phone_number, t.first_name, t.last_name, t.vcard,
t.reply_markup, t.input_message_content
= table.unpack(a)
elseif t.type == 'game' then t.game_short_name = a[1]
end
return t
end
function inline:thumb(url, width, height, mime)
if self.type == 'audio'
or self.type == 'voice'
or self.type == 'game'
then return self end
self.thumb_url = tostring(url)
if width and height and (
self.type == 'article'
or self.type == 'document'
or self.type == 'contact'
or self.type == 'location'
or self.type == 'venue'
) then
self.thumb_width = tonumber(width)
self.thumb_height = tonumber(height)
end
if mime and (
self.type == 'gif'
or self.type == 'mpeg4_gif'
) then self.thumb_mime_type = mime end
return self
end
function inline:keyboard(...)
if not self.type then return self end
local k = {}
for _, v in pairs {...} do
if type(v) == 'table' then
table.insert(k, v)
end
end
self.reply_markup = k
return self
end
-- Author itself not understands why this funciton needed
-- so not recommends to use it
function inline:messCont(a)
if self.type == 'game' or self.type == 'article' then
self.input_message_content = a
end
return self
end
function inline:answer(id, res, ctime, per, noff, pmt, pmp)
print(dump(res))
if res.id then res = {res} end
return self:request('answerInlineQuery', {
inline_query_id = id,
results = res,
cache_time = ctime,
is_personal = per,
next_offset = noff,
switch_pm_text = pmt,
switch_pm_parameter = pmp,
})
end
return function(api)
local self = setmetatable({
request = function(_, ...) api:request(...) end
}, inline)
return self
end

View file

@ -89,13 +89,13 @@ function tools.req(url, par, f, dbg)
return res, true return res, true
end end
function tools.request(token, endpoint, param, f, dbg) function tools.request(token, endpoint, param, f)
assert(token, 'Provide token!') assert(token, 'Provide token!')
assert(endpoint, 'Provide endpoint!') assert(endpoint, 'Provide endpoint!')
local url = 'https://api.telegram.org/bot' ..token.. '/' ..endpoint local url = 'https://api.telegram.org/bot' ..token.. '/' ..endpoint
-- dbg = true dbg = true
local resp = tools.req(url, param, f, dbg) local resp = tools.req(url, param, f, dbg)
return resp, resp.ok or false return resp, resp.ok or false
end end

View file

@ -0,0 +1,3 @@
return function(C, api, q)
api.inline:answer(q.id, api.inline.result('photo', '1', 'https://cdn.discordapp.com/attachments/871474214270554124/876506659311202395/unknown.png'):thumb('https://cdn.discordapp.com/attachments/871474214270554124/876506659311202395/unknown.png'))
end