Skip to content

Use faraday #55

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Mar 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion fcm.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ Gem::Specification.new do |s|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]

s.add_runtime_dependency('httparty', '~> 0.10', '>= 0.10.0')
s.add_runtime_dependency('faraday','0.15.4')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dependency can be too strict for the apps that already using faraday in their Gemfile.

end
222 changes: 65 additions & 157 deletions lib/fcm.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
require 'httparty'
require 'faraday'
require 'cgi'
require 'json'

class FCM
include HTTParty
base_uri 'https://fcm.googleapis.com/fcm'
default_timeout 30
format :json
BASE_URI = 'https://fcm.googleapis.com'
DEFAULT_TIMEOUT = 30
FORMAT = :json

# constants
GROUP_NOTIFICATION_BASE_URI = 'https://android.googleapis.com/gcm'
INSTANCE_ID_API = 'https://iid.googleapis.com/iid'
GROUP_NOTIFICATION_BASE_URI = 'https://android.googleapis.com'
INSTANCE_ID_API = 'https://iid.googleapis.com'
TOPIC_REGEX = /[a-zA-Z0-9\-_.~%]+/

attr_accessor :timeout, :api_key
Expand All @@ -35,38 +34,25 @@ def initialize(api_key, client_options = {})
def send_notification(registration_ids, options = {})
post_body = build_post_body(registration_ids, options)

params = {
body: post_body.to_json,
headers: {
'Authorization' => "key=#{@api_key}",
'Content-Type' => 'application/json'
}
}
response = self.class.post('/send', params.merge(@client_options))
build_response(response, registration_ids)
for_uri(BASE_URI) do |connection|
response = connection.post('/fcm/send', post_body.to_json)
build_response(response, registration_ids)
end
end
alias send send_notification

def create_notification_key(key_name, project_id, registration_ids = [])
post_body = build_post_body(registration_ids, operation: 'create',
notification_key_name: key_name)

params = {
body: post_body.to_json,
headers: {
'Content-Type' => 'application/json',
'project_id' => project_id,
'Authorization' => "key=#{@api_key}"
}
extra_headers = {
'project_id' => project_id
}

response = nil

for_uri(GROUP_NOTIFICATION_BASE_URI) do
response = self.class.post('/notification', params.merge(@client_options))
for_uri(GROUP_NOTIFICATION_BASE_URI, extra_headers) do |connection|
response = connection.post('/gcm/notification', post_body.to_json)
build_response(response)
end

build_response(response)
end
alias create create_notification_key

Expand All @@ -75,21 +61,14 @@ def add_registration_ids(key_name, project_id, notification_key, registration_id
notification_key_name: key_name,
notification_key: notification_key)

params = {
body: post_body.to_json,
headers: {
'Content-Type' => 'application/json',
'project_id' => project_id,
'Authorization' => "key=#{@api_key}"
}
extra_headers = {
'project_id' => project_id
}

response = nil

for_uri(GROUP_NOTIFICATION_BASE_URI) do
response = self.class.post('/notification', params.merge(@client_options))
for_uri(GROUP_NOTIFICATION_BASE_URI, extra_headers) do |connection|
response = connection.post('/gcm/notification', post_body.to_json)
build_response(response)
end
build_response(response)
end
alias add add_registration_ids

Expand All @@ -98,42 +77,32 @@ def remove_registration_ids(key_name, project_id, notification_key, registration
notification_key_name: key_name,
notification_key: notification_key)

params = {
body: post_body.to_json,
headers: {
'Content-Type' => 'application/json',
'project_id' => project_id,
'Authorization' => "key=#{@api_key}"
}
extra_headers = {
'project_id' => project_id
}

response = nil

for_uri(GROUP_NOTIFICATION_BASE_URI) do
response = self.class.post('/notification', params.merge(@client_options))
for_uri(GROUP_NOTIFICATION_BASE_URI, extra_headers) do |connection|
response = connection.post('/gcm/notification', post_body.to_json)
build_response(response)
end
build_response(response)
end
alias remove remove_registration_ids

def recover_notification_key(key_name, project_id)
params = {
query: {
notification_key_name: key_name
},
headers: {
'Content-Type' => 'application/json',
'project_id' => project_id,
'Authorization' => "key=#{@api_key}"
}
}

extra_headers = {
'project_id' => project_id
}

response = nil

for_uri(GROUP_NOTIFICATION_BASE_URI) do
response = self.class.get('/notification', params.merge(@client_options))
for_uri(GROUP_NOTIFICATION_BASE_URI, extra_headers) do |connection|
response = connection.get('/gcm/notification', params)
build_response(response)
end
build_response(response)
end

def send_with_notification_key(notification_key, options = {})
Expand All @@ -142,20 +111,10 @@ def send_with_notification_key(notification_key, options = {})
end

def topic_subscription(topic, registration_id)
params = {
headers: {
'Authorization' => "key=#{@api_key}",
'Content-Type' => 'application/json'
}
}

response = nil

for_uri(INSTANCE_ID_API) do
response = self.class.post("/v1/#{registration_id}/rel/topics/#{topic}", params)
for_uri(INSTANCE_ID_API) do |connection|
response = connection.post("/iid/v1/#{registration_id}/rel/topics/#{topic}")
build_response(response)
end

build_response(response)
end

def batch_topic_subscription(topic, registration_ids)
Expand All @@ -168,94 +127,44 @@ def batch_topic_unsubscription(topic, registration_ids)

def manage_topics_relationship(topic, registration_ids, action)
body = { to: "/topics/#{topic}", registration_tokens: registration_ids }
params = {
body: body.to_json,
headers: {
'Authorization' => "key=#{@api_key}",
'Content-Type' => 'application/json'
}
}

response = nil

for_uri(INSTANCE_ID_API) do
response = self.class.post("/v1/:batch#{action}", params)
for_uri(INSTANCE_ID_API) do |connection|
response = connection.post("/iid/v1:batch#{action}", body.to_json)
build_response(response)
end

build_response(response)
end



def send_to_topic(topic, options = {})
if topic.gsub(TOPIC_REGEX, "").length == 0
send_with_notification_key('/topics/' + topic, options)
end
end

def get_instance_id_info iid_token, options={}
response = nil
for_uri(INSTANCE_ID_API) do
response = self.class.get('/info/'+iid_token, query: options, headers: {
'Authorization' => "key=#{@api_key}",
'Content-type' => 'application/json'
})
params = {
query: options
}

for_uri(INSTANCE_ID_API) do |connection|
response = connection.get('/iid/info/'+iid_token, params)
build_response(response)
end
build_response(response)
end

def subscribe_instance_id_to_topic iid_token, topic_name
response = nil
for_uri(INSTANCE_ID_API) do
response = self.class.post('/v1/'+iid_token+'/rel/topics/'+topic_name, headers: {
'Authorization' => "key=#{@api_key}",
'Content-type' => 'application/json'
})
end
build_response(response)
batch_subscribe_instance_ids_to_topic([iid_token], topic_name)
end

def unsubscribe_instance_id_from_topic iid_token, topic_name
response = nil
for_uri(INSTANCE_ID_API) do
response = self.class.post('/v1/'+iid_token+'/rel/topics/'+topic_name, headers: {
'Authorization' => "key=#{@api_key}",
'Content-type' => 'application/json'
})
end
build_response(response)
batch_unsubscribe_instance_ids_from_topic([iid_token], topic_name)
end

def batch_subscribe_instance_ids_to_topic instance_ids, topic_name
response = nil
for_uri(INSTANCE_ID_API) do
response = self.class.post('/v1:batchAdd', body:{
to: "/topics/#{topic_name}",
registration_tokens: instance_ids
}.to_json,
headers: {
'Authorization' => "key=#{@api_key}",
'Content-type' => 'application/json'
}
)
end
build_response(response)
manage_topics_relationship(topic_name, instance_ids, 'Add')
end

def batch_unsubscribe_instance_ids_from_topic instance_ids, topic_name
response = nil
for_uri(INSTANCE_ID_API) do
response = self.class.post('/v1:batchRemove', body: {
to: "/topics/#{topic_name}",
registration_tokens: instance_ids
}.to_json,
headers: {
'Authorization' => "key=#{@api_key}",
'Content-type' => 'application/json'
}
)
end
build_response(response)
manage_topics_relationship(topic_name, instance_ids, 'Remove')
end

def send_to_topic_condition(condition, options = {})
Expand All @@ -267,11 +176,16 @@ def send_to_topic_condition(condition, options = {})

private

def for_uri(uri)
current_uri = self.class.base_uri
self.class.base_uri uri
yield
self.class.base_uri current_uri
def for_uri(uri, extra_headers = {})
connection = ::Faraday.new(:url => uri) do |faraday|
faraday.adapter Faraday.default_adapter
faraday.headers["Content-Type"] = "application/json"
faraday.headers["Authorization"] = "key=#{api_key}"
extra_headers.each do |key, value|
faraday.headers[key] = value
end
end
yield connection
end

def build_post_body(registration_ids, options = {})
Expand All @@ -281,8 +195,8 @@ def build_post_body(registration_ids, options = {})

def build_response(response, registration_ids = [])
body = response.body || {}
response_hash = { body: body, headers: response.headers, status_code: response.code }
case response.code
response_hash = { body: body, headers: response.headers, status_code: response.status }
case response.status
when 200
response_hash[:response] = 'success'
body = JSON.parse(body) unless body.empty?
Expand Down Expand Up @@ -325,16 +239,10 @@ def build_not_registered_ids(body, registration_id)
end

def execute_notification(body)
params = {
body: body.to_json,
headers: {
'Authorization' => "key=#{@api_key}",
'Content-Type' => 'application/json'
}
}

response = self.class.post('/send', params.merge(@client_options))
build_response(response)
for_uri(BASE_URI) do |connection|
response = connection.post('/fcm/send', body.to_json)
build_response(response)
end
end

def has_canonical_id?(result)
Expand Down
6 changes: 3 additions & 3 deletions spec/fcm_spec.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
require 'spec_helper'

describe FCM do
let(:send_url) { "#{FCM.base_uri}/send" }
let(:group_notification_base_uri) { "https://android.googleapis.com/gcm/notification" }
let(:send_url) { "#{FCM::BASE_URI}/fcm/send" }
let(:group_notification_base_uri) { "#{FCM::GROUP_NOTIFICATION_BASE_URI}/gcm/notification" }
let(:api_key) { 'AIzaSyB-1uEai2WiUapxCs2Q0GZYzPu7Udno5aA' }
let(:registration_id) { '42' }
let(:registration_ids) { ['42'] }
Expand Down Expand Up @@ -254,7 +254,7 @@

it 'should not send notification due to 599' do
subject.send(registration_ids).should eq(body: '{"body-key" => "Body value"}',
headers: { 'header-key' => ['Header value'] },
headers: { 'header-key' => 'Header value' },
response: 'There was an internal error in the FCM server while trying to process the request.',
status_code: 599)
end
Expand Down