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

@ -7,12 +7,20 @@ local tools =require 'etc.api.tools'
local json = require 'etc.json'
local events = require 'etc.events'
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
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
function api:getMe() return self:request 'getMe' end
@ -25,12 +33,9 @@ function api:getChat(cid) return self:request('getChat', {chat_id = cid}) end
-- Setters
function api:send(msg, txt, pmod, dwp, dnot, rtmid, rmp)
rmp = type(rmp) == 'table' and json.encode(rmp) or rmp
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
msg, rmp, pmod, dwp = argp(msg, rmp, pmod, dwp)
if txt and #txt > 4096 then
if txt and #txt >= 4096 then
txt = txt:sub(0, 4092) .. '...'
end
@ -46,10 +51,7 @@ function api:send(msg, txt, pmod, dwp, dnot, rtmid, rmp)
end
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 = type(rmp) == 'table' and json.encode(rmp) or rmp
pmod = (type(pmod) == 'boolean' and pmod == true) and 'markdown' or pmod
_, rmp, pmod, dwp = argp(msg, rmp, pmod, dwp)
return self:request('sendMessage', {
chat_id = msg.chat.id,
text = txt,
@ -70,9 +72,33 @@ function api:forward(cid, frcid, mid, dnot)
})
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)
cid, rmp, pmode = argp(cid, rmp, pmode)
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
mansw = type(mansw) == 'boolean' and mansw or false
return self:request('sendPoll', {
@ -94,6 +120,16 @@ function api:sendPoll(cid, q, opt, anon, ptype, mansw, coptid, expl, pmode, oper
})
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)
return self:request('setMyCommands', { commands = json.encode(cmds) })
end

View file

@ -27,8 +27,6 @@ function api:getUpdates(lim, offs, tout, allowed)
end
local function receiveUpdate(self, update)
if update then self:emit('update', update) end
if update.message then
local msg = update.message
local cmd, to = tools.fetchCmd(msg.text or '')
@ -72,8 +70,11 @@ function api:_getUpd(lim, offs, ...)
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
@ -92,7 +93,7 @@ function api:run(lim, offs, tout, al)
tout = tonumber(tout) or 0
self.runs = true
self:emit('ready')
self:emit 'ready'
self.co = coroutine.create(api._loop)
coroutine.resume(self.co, self, lim, tout, offs, al)
@ -123,6 +124,9 @@ return function(opts)
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

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
end
function tools.request(token, endpoint, param, f, dbg)
function tools.request(token, endpoint, param, f)
assert(token, 'Provide token!')
assert(endpoint, 'Provide endpoint!')
local url = 'https://api.telegram.org/bot' ..token.. '/' ..endpoint
-- dbg = true
dbg = true
local resp = tools.req(url, param, f, dbg)
return resp, resp.ok or false
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