fcmpush 1.0.1 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d9cd6eef6540ebc26b483f24558870bfd8eecb97f479611519ce4550483336d0
4
- data.tar.gz: 6a137e1f554500d626f12e68b7a9c6734ebd0e537db27f07155f6d8c9baf5c94
3
+ metadata.gz: 0f74702c902a7c7c3c7b15c9a242a715dd3d3b58a37c0b527530dbb9cfc38b74
4
+ data.tar.gz: 9f93f6571276546ac487ed3c39b15f6b7223c07d8a3eeac058a925a78856a5d1
5
5
  SHA512:
6
- metadata.gz: 789a5bdf88fc4ce1f8bdf4289da4cdb4da6f58ee87aa0531f2e5c3d6b82ca7ab2293ff5155725c589f1db554c9646bfced65de0010bc31c3fcb8de7ae37a2b81
7
- data.tar.gz: 3c5af92191e371c1beb2501dfef07cdf122ae41512937fbc8a1154f7d81aa94e2a72351d1544c6210636aaab11126015dd4b7d8b1bda1a32bed1c560b01c9a62
6
+ metadata.gz: 05044cba1bf67f672e94f8b3097a9fe841e65609e50d8c3b9a9ed2999d29a0cb3be1dc36ab8b557ea28386c12bad58e9b3bbb00fdd45b3c6be3dc6f73ca73086
7
+ data.tar.gz: 045dee042ec4079c2c041764c2c0cec198da0c1bd13f1d5bfdde47bc7d9d0c0693d07eb64470d99ef5ec90e428a9de95df18ae974e7c8e9b48fe543a6f3efd49
data/fcmpush.gemspec CHANGED
@@ -22,10 +22,10 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ['lib']
24
24
 
25
- spec.required_ruby_version = '>= 2.3', '< 2.8'
25
+ spec.required_ruby_version = '>= 2.4', '<= 3.0'
26
26
 
27
- spec.add_dependency 'googleauth', '>= 0.9.0'
28
- spec.add_dependency 'net-http-persistent', '>= 3.1.0'
27
+ spec.add_dependency 'google-apis-identitytoolkit_v3'
28
+ spec.add_dependency 'net-http-persistent', '~> 4.0.1'
29
29
 
30
30
  spec.add_development_dependency 'bundler', '~> 2.0'
31
31
  spec.add_development_dependency 'rake', '~> 13'
@@ -0,0 +1,37 @@
1
+ module Fcmpush
2
+ module Batch
3
+ PART_BOUNDRY = '__END_OF_PART__'.freeze
4
+
5
+ def make_batch_payload(messages, headers)
6
+ uri = URI.join(domain, path)
7
+ subrequests = messages.map do |payload|
8
+ req = Net::HTTP::Post.new(uri, headers)
9
+ req.body = payload
10
+ req
11
+ end
12
+ subrequests.map.with_index { |req, idx| create_part(req, PART_BOUNDRY, idx) }.join + "--#{PART_BOUNDRY}\r\n"
13
+ end
14
+
15
+ def create_part(request, part_boundry, idx)
16
+ serialized_request = serialize_sub_request(request)
17
+ "--#{part_boundry}\r\n" \
18
+ "Content-Length: #{serialized_request.length}\r\n" \
19
+ "Content-Type: application/http\r\n" \
20
+ "Content-Id: #{idx + 1}\r\n" \
21
+ "Content-Transfer-Encoding: binary\r\n" \
22
+ "\r\n" \
23
+ "#{serialized_request}\r\n"
24
+ end
25
+
26
+ def serialize_sub_request(request)
27
+ body_str = request.body.is_a?(String) ? request.body : request.body.to_json
28
+ subreqest = "POST #{request.path} HTTP/1.1\r\n" \
29
+ "Content-Length: #{body_str.length}\r\n"
30
+ request.to_hash.each do |k, v|
31
+ subreqest += "#{k}: #{v.join(';')}\r\n"
32
+ end
33
+ subreqest += "\r\n" \
34
+ "#{body_str}\r\n"
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,39 @@
1
+ require 'delegate' if RUBY_VERSION >= '2.7'
2
+
3
+ module Fcmpush
4
+ class BatchResponse < DelegateClass(Net::HTTPResponse)
5
+ alias response __getobj__
6
+ alias headers to_hash
7
+ HAS_SYMBOL_GC = RUBY_VERSION > '2.2.0'
8
+
9
+ def json
10
+ parsable? ? @parsed ||= parse_body(body) : nil
11
+ end
12
+
13
+ def inspect
14
+ "#<BatchResponse response: #{response.inspect}, json: #{json}>"
15
+ end
16
+ alias to_s inspect
17
+
18
+ def parsable?
19
+ !body.nil? && !body.empty?
20
+ end
21
+
22
+ def success_count
23
+ @success_count ||= json.length - failure_count
24
+ end
25
+
26
+ def failure_count
27
+ @failure_count ||= json.select { |i| i[:error] }.size
28
+ end
29
+
30
+ private
31
+
32
+ def parse_body(raw_body)
33
+ devider = raw_body.match(/(\r\n--batch_.*)\r\n/)[1]
34
+ raw_body.split(devider)[1..-2].map do |response|
35
+ JSON.parse(response.split("\r\n\r\n")[2], symbolize_names: HAS_SYMBOL_GC)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,13 +1,17 @@
1
1
  require 'fcmpush/exceptions'
2
+ require 'fcmpush/batch'
2
3
  require 'fcmpush/json_response'
4
+ require 'fcmpush/batch_response'
3
5
 
4
6
  module Fcmpush
5
7
  V1_ENDPOINT_PREFIX = '/v1/projects/'.freeze
6
8
  V1_ENDPOINT_SUFFIX = '/messages:send'.freeze
7
9
  TOPIC_DOMAIN = 'https://iid.googleapis.com'.freeze
8
10
  TOPIC_ENDPOINT_PREFIX = '/iid/v1'.freeze
11
+ BATCH_ENDPOINT = '/batch'.freeze
9
12
 
10
13
  class Client
14
+ include Batch
11
15
  attr_reader :domain, :path, :connection, :configuration, :server_key, :access_token, :access_token_expiry
12
16
 
13
17
  def initialize(domain, project_id, configuration, **options)
@@ -15,7 +19,7 @@ module Fcmpush
15
19
  @project_id = project_id
16
20
  @path = V1_ENDPOINT_PREFIX + project_id.to_s + V1_ENDPOINT_SUFFIX
17
21
  @options = {}.merge(options)
18
- @configuration = configuration
22
+ @configuration = configuration.dup
19
23
  access_token_response = v1_authorize
20
24
  @access_token = access_token_response['access_token']
21
25
  @access_token_expiry = Time.now.utc + access_token_response['expires_in']
@@ -25,8 +29,13 @@ module Fcmpush
25
29
 
26
30
  def v1_authorize
27
31
  @auth ||= if configuration.json_key_io
32
+ io = if configuration.json_key_io.respond_to?(:read)
33
+ configuration.json_key_io
34
+ else
35
+ File.open(configuration.json_key_io)
36
+ end
28
37
  Google::Auth::ServiceAccountCredentials.make_creds(
29
- json_key_io: File.open(configuration.json_key_io),
38
+ json_key_io: io,
30
39
  scope: configuration.scope
31
40
  )
32
41
  else
@@ -60,6 +69,14 @@ module Fcmpush
60
69
  raise NetworkError, "A network error occurred: #{e.class} (#{e.message})"
61
70
  end
62
71
 
72
+ def batch_push(messages, query: {}, headers: {})
73
+ uri, request = make_batch_request(messages, query, headers)
74
+ response = exception_handler(connection.request(uri, request))
75
+ BatchResponse.new(response)
76
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
77
+ raise NetworkError, "A network error occurred: #{e.class} (#{e.message})"
78
+ end
79
+
63
80
  private
64
81
 
65
82
  def make_push_request(body, query, headers)
@@ -121,5 +138,18 @@ module Fcmpush
121
138
  registration_tokens: instance_ids
122
139
  }.to_json
123
140
  end
141
+
142
+ def make_batch_request(messages, query, headers)
143
+ uri = URI.join(domain, BATCH_ENDPOINT)
144
+ uri.query = URI.encode_www_form(query) unless query.empty?
145
+
146
+ access_token_refresh
147
+ headers = v1_authorized_header(headers)
148
+ post = Net::HTTP::Post.new(uri, headers)
149
+ post['Content-Type'] = "multipart/mixed; boundary=#{::Fcmpush::Batch::PART_BOUNDRY}"
150
+ post.body = make_batch_payload(messages, headers)
151
+
152
+ [uri, post]
153
+ end
124
154
  end
125
155
  end
@@ -1,3 +1,3 @@
1
1
  module Fcmpush
2
- VERSION = '1.0.1'.freeze
2
+ VERSION = '1.3.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fcmpush
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - miyataka
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-01 00:00:00.000000000 Z
11
+ date: 2021-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: googleauth
14
+ name: google-apis-identitytoolkit_v3
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.9.0
19
+ version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.9.0
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: net-http-persistent
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 3.1.0
33
+ version: 4.0.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 3.1.0
40
+ version: 4.0.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -80,7 +80,7 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '3.0'
83
- description:
83
+ description:
84
84
  email:
85
85
  - voyager.3taka28@gmail.com
86
86
  executables: []
@@ -89,6 +89,8 @@ extra_rdoc_files: []
89
89
  files:
90
90
  - fcmpush.gemspec
91
91
  - lib/fcmpush.rb
92
+ - lib/fcmpush/batch.rb
93
+ - lib/fcmpush/batch_response.rb
92
94
  - lib/fcmpush/client.rb
93
95
  - lib/fcmpush/configuration.rb
94
96
  - lib/fcmpush/exceptions.rb
@@ -100,7 +102,7 @@ licenses:
100
102
  metadata:
101
103
  homepage_uri: https://github.com/miyataka/fcmpush
102
104
  source_code_uri: https://github.com/miyataka/fcmpush
103
- post_install_message:
105
+ post_install_message:
104
106
  rdoc_options: []
105
107
  require_paths:
106
108
  - lib
@@ -108,18 +110,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
108
110
  requirements:
109
111
  - - ">="
110
112
  - !ruby/object:Gem::Version
111
- version: '2.3'
112
- - - "<"
113
+ version: '2.4'
114
+ - - "<="
113
115
  - !ruby/object:Gem::Version
114
- version: '2.8'
116
+ version: '3.0'
115
117
  required_rubygems_version: !ruby/object:Gem::Requirement
116
118
  requirements:
117
119
  - - ">="
118
120
  - !ruby/object:Gem::Version
119
121
  version: '0'
120
122
  requirements: []
121
- rubygems_version: 3.1.2
122
- signing_key:
123
+ rubygems_version: 3.2.3
124
+ signing_key:
123
125
  specification_version: 4
124
126
  summary: Firebase Cloud Messaging API wrapper for ruby, supports HTTP v1. And including
125
127
  access_token Auto Refresh feature!