diff --git a/miku/bindings.lua b/miku/bindings.lua index 982ea91..40d0d7f 100644 --- a/miku/bindings.lua +++ b/miku/bindings.lua @@ -22,11 +22,11 @@ local bindings = {} -local HTTPS = require('ssl.https') -HTTPS.timeout = 10 -local JSON = require('dkjson') +local https = require('ssl.https') +https.timeout = 10 +local json = require('dkjson') local ltn12 = require('ltn12') -local MP_ENCODE = require('multipart-post').encode +local mp_encode = require('multipart-post').encode function bindings.init(token) bindings.BASE_URL = 'https://api.telegram.org/bot' .. token .. '/' @@ -65,8 +65,8 @@ function bindings.request(method, parameters, file) parameters = {''} end local response = {} - local body, boundary = MP_ENCODE(parameters) - local success, code = HTTPS.request{ + local body, boundary = mp_encode(parameters) + local success, code = https.request{ url = bindings.BASE_URL .. method, method = 'POST', headers = { @@ -81,7 +81,7 @@ function bindings.request(method, parameters, file) print(method .. ': Connection error. [' .. code .. ']') return false, false else - local result = JSON.decode(data) + local result = json.decode(data) if not result then return false, false elseif result.ok then diff --git a/miku/plugins/cats.lua b/miku/plugins/cats.lua index 5df8d17..99167bb 100644 --- a/miku/plugins/cats.lua +++ b/miku/plugins/cats.lua @@ -59,7 +59,7 @@ function cats:inline_callback(inline_query, config, matches) utilities.answer_inline_query(inline_query, results, 30) end -function cats:action(msg, config) +function cats:action(msg, config, matches) if matches[1] == 'gif' then local url = 'http://thecatapi.com/api/images/get?type=gif&apikey='..apikey local file = download_to_file(url, 'miau.gif') diff --git a/miku/utilities.lua b/miku/utilities.lua index 5898648..e364e87 100644 --- a/miku/utilities.lua +++ b/miku/utilities.lua @@ -451,6 +451,15 @@ function utilities.save_data(filename, data) f:close() end +-- Returns file size as Integer +-- See: https://www.lua.org/pil/21.3.html +function get_file_size(file) + local current = file:seek() -- get current position + local size = file:seek("end") -- get file size + file:seek("set", current) -- restore position + return tonumber(size) +end + -- Gets coordinates for a location. Used by gMaps.lua, time.lua, weather.lua. function utilities.get_coords(input, config) local url = 'https://maps.googleapis.com/maps/api/geocode/json?address='..URL.escape(input)..'&language=de' @@ -724,6 +733,10 @@ function is_service_msg(msg) return var end +-- Make a POST request +-- URL = obvious +-- Arguments = Things, that go into the body. If sending a file, use 'io.open('path/to/file', "r")' +-- Headers = Header table. If not set, we will set a few! function post_petition(url, arguments, headers) local url, h = string.gsub(url, "http://", "") local url, hs = string.gsub(url, "https://", "") @@ -750,8 +763,13 @@ function post_petition(url, arguments, headers) request_constructor.headers["X-Accept"] = "application/json" request_constructor.headers["Accept"] = "application/json" end - request_constructor.headers["Content-Length"] = tostring(#source) - request_constructor.source = ltn12.source.string(source) + if type(arguments) == 'userdata' then + request_constructor.headers["Content-Length"] = get_file_size(source) + request_constructor.source = ltn12.source.file(source) + else + request_constructor.headers["Content-Length"] = tostring(#source) + request_constructor.source = ltn12.source.string(source) + end if post_prot == "http" then ok, response_code, response_headers, response_status_line = http.request(request_constructor) diff --git a/otouto/plugins/voice_to_text.lua b/otouto/plugins/voice_to_text.lua new file mode 100644 index 0000000..f08bd69 --- /dev/null +++ b/otouto/plugins/voice_to_text.lua @@ -0,0 +1,61 @@ +local vtt = {} + +vtt.triggers = { + '/nil' +} + +local apikey = cred_data.witai_apikey + +function vtt:pre_process(msg, config) + if not msg.voice then return msg end -- Ignore + local mime_type = msg.voice.mime_type + if mime_type ~= 'audio/ogg' then return msg end -- We only want to transcript voice messages + local file_id = msg.voice.file_id + local file_size = msg.voice.file_size + if file_size > 19922944 then + print('File is over 20 MB - can\'t download :(') + return msg + end + + utilities.send_typing(msg.chat.id, 'typing') + -- Saving file to the Telegram Cloud + local request = bindings.request('getFile', { + file_id = file_id + } ) + + local download_url = 'https://api.telegram.org/file/bot'..config.bot_api_key..'/'..request.result.file_path + local ogg_file_name = file_id..'.oga' + local ogg_file = download_to_file(download_url, ogg_file_name) + + -- Convert to MP3 + run_command('ffmpeg -loglevel panic -i /tmp/'..ogg_file_name..' -ac 1 -y /tmp/'..file_id..'.mp3') + os.remove('/tmp/'..ogg_file_name) + + local mp3_file = '/tmp/'..file_id..'.mp3' + + -- Voice-To-Text via wit.ai + local headers = { + ["Content-Type"] = "audio/mpeg3", + Authorization = "Bearer "..apikey + } + local data = post_petition('https://api.wit.ai/speech?v=20160526', io.open(mp3_file, 'r'), headers) + os.remove(mp3_file) + + if not data then + return msg + end + + if not data._text then + utilities.send_reply(msg, 'Keine Stimme zu hören oder Erkennung fehlgeschlagen.') + return + end + + utilities.send_reply(msg, data._text) + + return msg +end + +function vtt:action(msg) +end + +return vtt \ No newline at end of file