class Fcmpush::Client

Attributes

access_token[R]
access_token_expiry[R]
configuration[R]
connection[R]
domain[R]
path[R]
server_key[R]

Public Class Methods

new(domain, project_id, configuration, **options) click to toggle source
# File lib/fcmpush/client.rb, line 17
def initialize(domain, project_id, configuration, **options)
  @domain = domain
  @project_id = project_id
  @path = V1_ENDPOINT_PREFIX + project_id.to_s + V1_ENDPOINT_SUFFIX
  @options = {}.merge(options)
  @configuration = configuration.dup
  access_token_response = v1_authorize
  @access_token = access_token_response['access_token']
  @access_token_expiry = Time.now.utc + access_token_response['expires_in']
  @server_key = configuration.server_key
  @connection = Net::HTTP::Persistent.new
end

Public Instance Methods

batch_push(messages, query: {}, headers: {}) click to toggle source
# File lib/fcmpush/client.rb, line 73
def batch_push(messages, query: {}, headers: {})
  uri, request = make_batch_request(messages, query, headers)
  response = exception_handler(connection.request(uri, request))
  BatchResponse.new(response)
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
  raise NetworkError, "A network error occurred: #{e.class} (#{e.message})"
end
push(body, query: {}, headers: {}) click to toggle source
# File lib/fcmpush/client.rb, line 49
def push(body, query: {}, headers: {})
  uri, request = make_push_request(body, query, headers)
  response = exception_handler(connection.request(uri, request))
  JsonResponse.new(response)
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
  raise NetworkError, "A network error occurred: #{e.class} (#{e.message})"
end
subscribe(topic, *instance_ids, query: {}, headers: {}) click to toggle source
# File lib/fcmpush/client.rb, line 57
def subscribe(topic, *instance_ids, query: {}, headers: {})
  uri, request = make_subscription_request(topic, *instance_ids, :subscribe, query, headers)
  response = exception_handler(connection.request(uri, request))
  JsonResponse.new(response)
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
  raise NetworkError, "A network error occurred: #{e.class} (#{e.message})"
end
unsubscribe(topic, *instance_ids, query: {}, headers: {}) click to toggle source
# File lib/fcmpush/client.rb, line 65
def unsubscribe(topic, *instance_ids, query: {}, headers: {})
  uri, request = make_subscription_request(topic, *instance_ids, :unsubscribe, query, headers)
  response = exception_handler(connection.request(uri, request))
  JsonResponse.new(response)
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
  raise NetworkError, "A network error occurred: #{e.class} (#{e.message})"
end
v1_authorize() click to toggle source
# File lib/fcmpush/client.rb, line 30
def v1_authorize
  @auth ||= if configuration.json_key_io
              io = if configuration.json_key_io.respond_to?(:read)
                     configuration.json_key_io
                   else
                     File.open(configuration.json_key_io)
                   end
              io.rewind if io.respond_to?(:read)
              Google::Auth::ServiceAccountCredentials.make_creds(
                json_key_io: io,
                scope: configuration.scope
              )
            else
              # from ENV
              Google::Auth::ServiceAccountCredentials.make_creds(scope: configuration.scope)
            end
  @auth.fetch_access_token
end

Private Instance Methods

access_token_refresh() click to toggle source
# File lib/fcmpush/client.rb, line 108
def access_token_refresh
  return if access_token_expiry > Time.now.utc + 300

  access_token_response = v1_authorize
  @access_token = access_token_response['access_token']
  @access_token_expiry = Time.now.utc + access_token_response['expires_in']
end
exception_handler(response) click to toggle source
# File lib/fcmpush/client.rb, line 128
def exception_handler(response)
  error = STATUS_TO_EXCEPTION_MAPPING[response.code]
  raise error.new("Receieved an error response #{response.code} #{error.to_s.split('::').last}: #{response.body}", response) if error

  response
end
legacy_authorized_header(headers) click to toggle source
# File lib/fcmpush/client.rb, line 122
def legacy_authorized_header(headers)
  headers.merge('Content-Type' => 'application/json',
                'Accept' => 'application/json',
                'Authorization' => "Bearer key=#{server_key}")
end
make_batch_request(messages, query, headers) click to toggle source
# File lib/fcmpush/client.rb, line 143
def make_batch_request(messages, query, headers)
  uri = URI.join(domain, BATCH_ENDPOINT)
  uri.query = URI.encode_www_form(query) unless query.empty?

  access_token_refresh
  headers = v1_authorized_header(headers)
  post = Net::HTTP::Post.new(uri, headers)
  post['Content-Type'] = "multipart/mixed; boundary=#{::Fcmpush::Batch::PART_BOUNDRY}"
  post.body = make_batch_payload(messages, headers)

  [uri, post]
end
make_push_request(body, query, headers) click to toggle source
# File lib/fcmpush/client.rb, line 83
def make_push_request(body, query, headers)
  uri = URI.join(domain, path)
  uri.query = URI.encode_www_form(query) unless query.empty?

  access_token_refresh
  headers = v1_authorized_header(headers)
  post = Net::HTTP::Post.new(uri, headers)
  post.body = body.is_a?(String) ? body : body.to_json

  [uri, post]
end
make_subscription_body(topic, *instance_ids) click to toggle source
# File lib/fcmpush/client.rb, line 135
def make_subscription_body(topic, *instance_ids)
  topic = topic.match(%r{^/topics/}) ? topic : '/topics/' + topic
  {
    to: topic,
    registration_tokens: instance_ids
  }.to_json
end
make_subscription_request(topic, instance_ids, type, query, headers) click to toggle source
# File lib/fcmpush/client.rb, line 95
def make_subscription_request(topic, instance_ids, type, query, headers)
  suffix = type == :subscribe ? ':batchAdd' : ':batchRemove'

  uri = URI.join(TOPIC_DOMAIN, TOPIC_ENDPOINT_PREFIX + suffix)
  uri.query = URI.encode_www_form(query) unless query.empty?

  headers = legacy_authorized_header(headers)
  post = Net::HTTP::Post.new(uri, headers)
  post.body = make_subscription_body(topic, *instance_ids)

  [uri, post]
end
v1_authorized_header(headers) click to toggle source
# File lib/fcmpush/client.rb, line 116
def v1_authorized_header(headers)
  headers.merge('Content-Type' => 'application/json',
                'Accept' => 'application/json',
                'Authorization' => "Bearer #{access_token}")
end