From e6b9fe08a7982f0f013bfeb4aae3080c76134727 Mon Sep 17 00:00:00 2001 From: Denver Gingerich Date: Tue, 24 Jan 2017 13:58:10 +0000 Subject: [PATCH] continue 1c75de7: now saves and sends files as MMS --- sgx-catapult.rb | 110 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 5 deletions(-) diff --git a/sgx-catapult.rb b/sgx-catapult.rb index 349ff20aa0c1566235bb8b2b5eee0df790b0ab60..b3d7745a41c687d1c2d7edc588a8f5ae1b92e901 100755 --- a/sgx-catapult.rb +++ b/sgx-catapult.rb @@ -22,6 +22,7 @@ require 'blather/client/dsl' require 'json' require 'net/http' require 'redis/connection/hiredis' +require 'time' require 'uri' require 'uuid' @@ -29,7 +30,7 @@ require 'goliath/api' require 'goliath/server' require 'log4r' -puts "Soprani.ca/SMS Gateway for XMPP - Catapult v0.012" +puts "Soprani.ca/SMS Gateway for XMPP - Catapult v0.013" if ARGV.size != 8 then puts "Usage: sgx-catapult.rb " + @@ -43,6 +44,8 @@ module SGXcatapult extend Blather::DSL @jingle_sids = Hash.new + @jingle_fnames = Hash.new + @partial_data = Hash.new @uuid_gen = UUID.new def self.run @@ -261,22 +264,31 @@ module SGXcatapult @jingle_sids[transport['sid']] = jn[0]['sid'] + # TODO: save as well? Gajim sends, Conversations does not + # TODO: save/validate with eventual full received length + fname = cn.children.find { |v| v.element_name == "description" + }.children.find { |w| w.element_name == "offer" + }.children.find { |x| x.element_name == "file" + }.children.find { |y| y.element_name == "name" } + @jingle_fnames[transport['sid']] = fname.text + puts "RESPONSE9: #{msg.inspect}" write_to_stream msg end iq '/iq/ns:open', :ns => - 'http://jabber.org/protocol/ibb' do |i, xpath_result| + 'http://jabber.org/protocol/ibb' do |i, on| puts "IQo: #{i.inspect}" + + @partial_data[on[0]['sid']] = '' write_to_stream i.reply end iq '/iq/ns:data', :ns => 'http://jabber.org/protocol/ibb' do |i, dn| - # TODO: decode and save partial data so can upload it when done - puts "IQd: #{i.inspect}" + @partial_data[dn[0]['sid']] += Base64.decode64(dn[0].text) write_to_stream i.reply end @@ -286,7 +298,95 @@ module SGXcatapult puts "IQc: #{i.inspect}" write_to_stream i.reply - # TODO: upload cached data to server (do before success reply) + # TODO: refactor below so that "message :chat?" uses same code + num_dest = i.to.to_s.split('@', 2)[0] + + if num_dest[0] != '+' + # TODO: add text re number not (yet) supported/implmnted + write_to_stream error_msg(i.reply, nil, :cancel, + 'item-not-found') + next + end + + bare_jid = i.from.to_s.split('/', 2)[0] + cred_key = "catapult_cred-" + bare_jid + + # TODO: connect at start of program instead + conn = Hiredis::Connection.new + conn.connect(ARGV[4], ARGV[5].to_i) + + conn.write ["EXISTS", cred_key] + if conn.read == 0 + conn.disconnect + + # TODO: add text re credentials not being registered + write_to_stream error_msg(i.reply, nil, :auth, + 'registration-required') + next + end + + conn.write ["LRANGE", cred_key, 0, 3] + user_id, api_token, api_secret, users_num = conn.read + conn.disconnect + + # upload cached data to server (before success reply) + media_name = Time.now.utc.iso8601 + '_' + @uuid_gen.generate + + '_' + @jingle_fnames[cn[0]['sid']] + puts 'name to save: ' + media_name + + uri = URI.parse('https://api.catapult.inetwork.com') + http = Net::HTTP.new(uri.host, uri.port) + http.use_ssl = true + request = Net::HTTP::Put.new('/v1/users/' + user_id + + '/media/' + media_name) + request.basic_auth api_token, api_secret + request.body = @partial_data[cn[0]['sid']] + response = http.request(request) + + puts 'eAPI response to send: ' + response.to_s + ' with code ' + + response.code + ', body "' + response.body + '"' + + if response.code != '200' + # TODO: add text re unexpected code; mention code number + write_to_stream error_msg(i.reply, nil, :cancel, + 'internal-server-error') + next + end + + uri = URI.parse('https://api.catapult.inetwork.com') + http = Net::HTTP.new(uri.host, uri.port) + http.use_ssl = true + request = Net::HTTP::Post.new('/v1/users/' + user_id + + '/messages') + request.basic_auth api_token, api_secret + request.add_field('Content-Type', 'application/json') + request.body = JSON.dump({ + 'from' => users_num, + 'to' => num_dest, + 'text' => '', + 'media' => [ + 'https://api.catapult.inetwork.com/v1/users/' + + user_id + '/media/' + media_name], + 'tag' => i.id # TODO: message has it? + # TODO: add back when Bandwidth AP supports it (?); now: + # "The ''messages'' resource property + # ''receiptRequested'' is not supported for MMS" + #'receiptRequested' => 'all', + #'callbackUrl' => ARGV[6] + }) + response = http.request(request) + + puts 'mAPI response to send: ' + response.to_s + ' with code ' + + response.code + ', body "' + response.body + '"' + + if response.code != '201' + # TODO: add text re unexpected code; mention code number + write_to_stream error_msg(i.reply, nil, :cancel, + 'internal-server-error') + next + end + + @partial_data[cn[0]['sid']] = '' # received the complete file so now close the stream msg = Blather::Stanza::Iq.new :set