From 141bc4b1617138bf1d20c84d72def3781cdd5c87 Mon Sep 17 00:00:00 2001 From: Er2 Date: Sun, 15 Aug 2021 20:01:35 +0300 Subject: [PATCH] add more methods, inline queries --- etc/api/api.lua | 68 ++++++++++++---- etc/api/core.lua | 12 ++- etc/api/inline.lua | 156 +++++++++++++++++++++++++++++++++++++ etc/api/tools.lua | 4 +- src/events/inlineQuery.lua | 3 + 5 files changed, 221 insertions(+), 22 deletions(-) create mode 100644 etc/api/inline.lua create mode 100644 src/events/inlineQuery.lua diff --git a/etc/api/api.lua b/etc/api/api.lua index 63fbce5..187164c 100644 --- a/etc/api/api.lua +++ b/etc/api/api.lua @@ -3,15 +3,23 @@ -- Zlib License --]] -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, +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 } 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 @@ -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 diff --git a/etc/api/core.lua b/etc/api/core.lua index ec0860f..1a306cb 100644 --- a/etc/api/core.lua +++ b/etc/api/core.lua @@ -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,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 for _, v in pairs(u.result) do offs = v.update_id + 1 - receiveUpdate(self, v) + 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 diff --git a/etc/api/inline.lua b/etc/api/inline.lua new file mode 100644 index 0000000..46ca17d --- /dev/null +++ b/etc/api/inline.lua @@ -0,0 +1,156 @@ +--[[ Inline query library + -- (c) Er2 2021 + -- 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 diff --git a/etc/api/tools.lua b/etc/api/tools.lua index 277d9b5..5219707 100644 --- a/etc/api/tools.lua +++ b/etc/api/tools.lua @@ -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 diff --git a/src/events/inlineQuery.lua b/src/events/inlineQuery.lua new file mode 100644 index 0000000..8036875 --- /dev/null +++ b/src/events/inlineQuery.lua @@ -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