--[[ Additional tools -- (c) Er2 2021 -- Zlib license --]] local tools = { json = require 'json', } local json = tools.json local https = require 'ssl.https' local ltn12 = require 'ltn12' local mp = require 'api.multipart' function tools.fetchCmd(text) return text:match '/([%w_]+)', -- cmd text:match '/[%w_]+@([%w_]+)' -- to end function tools.parseArgs(text) -- inside quotes, buffer and final args local iq, buf, args = false, '', {} local qt, esc = nil, false -- quote type and escape, addition -- helper function, add args and clear buffer local function psh() if #buf > 0 then table.insert(args, buf) end buf, qt = '', nil end for i = 1, #text + 1 do local v = text:sub(i, i) -- if space and inside quotes, or end of string if ((v == ' ' or v == '\n' or v == '\t') and not iq) or v == '' then psh() elseif esc then esc, buf = false, buf.. v elseif v == '\\' then esc = true -- if (no current quote or same quote) and quote is supported elseif (not qt or qt == v) and (v == '"' or v == "'") then psh() qt, iq = v, not iq -- quote type, inside quote else buf = buf.. v -- append buffer end end return args end function tools.unparseArgs(args) -- args to string local text = '' for i = 1, #args do local v = args[i] if type(v) == 'string' then if v:match '%s' then text = text.. '"'.. v ..'" ' else text = text.. v ..' ' end end end return text end function tools._req(url, meth, data, ctype) assert(url, 'Provide URL!') assert(meth, 'Provide method!') local resp = {} local head = { url = url, method = meth, headers = { ['Content-Type'] = ctype, ['Content-Length'] = #(data or ''), }, source = ltn12.source.string(data), sink = ltn12.sink.table(resp), } local succ, res = https.request(head) if not succ then print('Connection error [' .. res .. ']') return nil, false end return resp[1], true end function tools.preq(url, par) par = par or {} local body, bound = mp.encode(par) return tools._req( url, 'POST', body, 'multipart/form-data; boundary=' .. bound ) end function tools.greq(url, par, f) par = json.encode(par) return tools._req(url, 'GET', par, 'application/json') end function tools.req(url, par, f, dbg) local res, succ par = par or {} -- files if f and next(f) ~= nil then par = par or {} for k, v in pairs(par) do par[k] = tostring(v) end local ft, fn = next(f) local fr = io.open(fn, 'r') if fr then par[ft] = { filename = fn, data = fr:read '*a' } fr:close() else par[ft] = fn end res, succ = tools.preq(url, par) else -- text res, succ = tools.greq(url, par) end if dbg then print(url, succ, res, par) -- dump(par)) end local s, res = pcall(json.decode, res or '{}') if not s or not succ or not res then return {}, false end return res, true end 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 local resp = tools.req(url, param, f, dbg) return resp, resp.ok or false end return tools