Trying to get push notifications working - and failing so far

This commit is contained in:
Nick Thomas
2013-09-28 21:11:34 +01:00
parent 9007ad43ae
commit c2a9403a4c

View File

@@ -4,6 +4,9 @@ require 'discourse_api'
require 'json'
require 'pp'
require 'chronic'
require 'base64'
require 'net/https'
PUSH_TYPES = "ann,conv,pm,sub,like,thank,quote,newtopic,tag"
@@ -58,8 +61,22 @@ helpers do
method, arguments = XMLRPC::Marshal.load_call(xml)
method = "xmlrpc_#{method.gsub(/([A-Z])/, '_ ').downcase}"
puts "method = #{method}, args = #{ method =~ /login/ ? "*REDACTED*" : arguments.inspect }"
# FIXME: this is pretty evil
filtered_args = if method == "xmlrpc_login"
tmp = arguments.dup
tmp[1] = "[FILTERED]"
tmp
elsif method == "xmlrpc_update_push_status"
tmp = arguments.dup
tmp[2] = "[FILTERED]"
tmp
else
arguments
end
puts "method = #{method}, args = #{filtered_args.inspect}"
# Check if method exists
if(respond_to?(method))
content_type("text/xml", :charset => "utf-8")
@@ -158,7 +175,7 @@ helpers do
result
end
# Try to keep this instance around for as long as possible...
# TODO: To keep it around, push into Rack::Session, or cookies? Some sort of
# long-lived store. Can go away with process restarts, of course.
@@ -175,13 +192,13 @@ helpers do
def respond_xmlrpc( rsp )
data = XMLRPC::Marshal.dump_response( rsp )
data.gsub!( '<?xml version="1.0" ?>', '<?xml version="1.0" encoding="UTF-8"?>' )
data.tr!("\n", "")
data
end
## http://tapatalk.com/api/api_section.php ##
@@ -225,7 +242,7 @@ helpers do
"min_search_length" => 3, # Boring default
"alert" => "0", # TODO
"direct_unsubscribe" => "0", # TODO
# "push_type" => PUSH_TYPES,
"push_type" => PUSH_TYPES,
# "ban_delete_type" => "none", # TODO
"inappreg" => "0", # TODO
@@ -263,7 +280,7 @@ helpers do
# These are returned by some other forums but aren't documented
"key" => settings.tapatalk_api_key, # tapatalk API key, at a guess?
"push" => "0",
"push" => "1",
# "allow_moderate",
@@ -313,12 +330,12 @@ helpers do
set_cookies = discourse.cookies.each.collect {|c| c.set_cookie_value }
headers( "Set-Cookie" => set_cookies ) if set_cookies.size > 0
# user = user_info.fetch("user")
user = user_info.fetch("user")
respond_xmlrpc(
'result' => true,
# 'user_id' => user["id"], # api level 4
# 'username' => binary_xmlrpc( "username" ), # api level 4
'user_id' => user["id"], # api level 4
'username' => binary_xmlrpc( user["username"] ), # api level 4
# 'usergroup_id' => [], # api level 4
# 'email' => binary_xmlrpc( "" ) # api level 4 # not sent by discourse
# 'icon_url' => make_avatar_url( user["avatar_template"] ), # api level 4
@@ -331,12 +348,23 @@ helpers do
# can_profile => true, # api level 4
'can_upload_avatar' => false, # TODO
# Don't enable push if the user has disabled it
# FIXME: bool or string 1/0 ?
# 'push_type' => PUSH_TYPES.split(",").collect {|type| { 'name' => type, 'value' => push } }
# phpBB3 returns the values as booleans
'push_type' => PUSH_TYPES.split(",").collect {|type|
{ 'name' => type, 'value' => ( push == "1" ) }
}
)
end
# Unsure what this does just yet, trying to get push notifications working.
# Pokes directory.tapatalk.com, as does update_push_status... glue?
def xmlrpc_sign_in( token, code, unknown, username, password )
pp [ "xmlrpc_sign_in args:", args ]
pp [ "rack environment:", request.env ]
respond_xmlrpc( 'result' => false )
end
def xmlrpc_logout_user
discourse.session_destroy({})
respond_xmlrpc( 'result' => true )
@@ -566,7 +594,7 @@ helpers do
def xmlrpc_reply_post( forum_id, topic_id, subject, text_body, attachment_id_array = nil, return_html = false )
csrf_token!
rsp = discourse.post_create( :topic_id => topic_id, :title => subject, :raw => text_body )
result = {
'result' => true,
'post_id' => rsp["id"].to_s,
@@ -577,13 +605,76 @@ helpers do
# 'post_time' => make_xmlrpc_datetime( rsp['updated_at'] ) # api level 4
# attachments # api level 4
}
respond_xmlrpc( result )
end
# def get_smilies # TODO - not a priority
# end
# Grr. Bad tapatalk, bad.
def php_serialize( hash )
# PHP's array serialize format is like this:
# a:<num-elems>:{s:<num-bytes>:"...";i:<val>;...;}
raise ArgumentError.new( "Not a hash" ) unless hash.is_a?(Hash )
elems = hash.collect {|k, v|
raise ArgumentError.new( "key #{k} not a string") unless k.is_a?( String )
raise ArgumentError.new( "value #{v} not Fixnum") unless v.is_a?( Fixnum )
"s:#{k.size}:\"#{k}\";i:#{v}"
}.join(";")
"a:#{hash.size}:{#{elems};}"
end
def xmlrpc_update_push_status( push_status, username, password )
user = discourse.user( :username => username ).fetch( "user" )
# FIXME: TODO: CHECK THE PASSWORD IS VALID!
if !username || !password || password == "" || username == "" ||
!user.has_key?("id") || !user.has_key?("username")
puts "Returning false - problems validating user"
pp user
return respond_xmlrpc( 'result' => false )
end
# push_status is a hash: {"pm"=>1, "conversation"=>1, "newtopic"=>1, "sub"=>1, "like"=>1, "tag"=>1, "quote"=>1}
# We have to do a php-style serialize() on it, base64-encode it and pass it
# on to tapatalk's push API. This is going to get nasty.
uri = URI.parse( settings.tapatalk_api )
uri.path = "/au_update_push_setting.php"
req_data = {
'url' => settings.discourse_api.to_s,
'key' => settings.tapatalk_api_key,
'uid' => user["id"], # FIXME: should we use id instead?
'data' => Base64::encode64( php_serialize( push_status ) ).tr!("\n", "")
}
# We have this strange call to a strange path - that seems to fail anyway -
# to do
tapatalk = Net::HTTP.new( "directory.tapatalk.com", 443 )
tapatalk.use_ssl = true
tapatalk.verify_mode = OpenSSL::SSL::VERIFY_NONE # FIXME
rsp = tapatalk.start {|remote|
req = Net::HTTP::Post.new( uri.path )
req.form_data = req_data
remote.request( req )
}
raise "Unknown response: #{rsp.inspect} #{rsp.body}" unless rsp.is_a?( Net::HTTPOK )
rsp_data = JSON.parse( rsp.body, :create_extensions => false )
unless rsp_data['result']
puts "Warning: POSTing to directory failed: #{rsp_data.inspect}. Upstream ignores said failures, so we will too."
end
respond_xmlrpc( 'result' => true )
end
end
post "/" do