expo-server-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expo
4
+ module Push
5
+ ##
6
+ # A single receipt for a single notification.
7
+ #
8
+ # - In case of an #ok? receipt, no action need be taken
9
+ # - In case of an #error? receipt, holds the #message, #explain
10
+ #
11
+ # Some failed receipts may expose which push token is not or no longer
12
+ # valid. This is exposed via #original_push_token.
13
+ #
14
+ class Receipt
15
+ attr_reader :data, :receipt_id
16
+
17
+ def initialize(data:, receipt_id:)
18
+ self.data = data
19
+ self.receipt_id = receipt_id
20
+ end
21
+
22
+ def original_push_token
23
+ return nil if ok?
24
+
25
+ if message.include?('PushToken[')
26
+ return /Expo(?:nent)?PushToken\[(?:[^\]]+?)\]/.match(message) { |match| match[0] }
27
+ end
28
+
29
+ /\A[a-z\d]{8}-[a-z\d]{4}-[a-z\d]{4}-[a-z\d]{4}-[a-z\d]{12}\z/i.match(message) { |match| match[0] }
30
+ end
31
+
32
+ def message
33
+ data.fetch('message')
34
+ end
35
+
36
+ def explain
37
+ Expo::Push::Error.explain((data['details'] || {})['error'])
38
+ end
39
+
40
+ def ok?
41
+ data['status'] == 'ok'
42
+ end
43
+
44
+ def error?
45
+ data['status'] == 'error'
46
+ end
47
+
48
+ private
49
+
50
+ attr_writer :data, :receipt_id
51
+ end
52
+
53
+ ##
54
+ # Receipts represent a single call to the receipts endpoint. It holds both
55
+ # the successfully retrieved receipts, as well as the still unresolved IDs.
56
+ #
57
+ # You MUST iterate #each_error and first check if its an Error, which would
58
+ # be the case if the entire call failed. Otherwise, it will iterate through
59
+ # each receipt that indicates a failed push.
60
+ #
61
+ # Keep calling the receipts endpoint until #unresolved_ids is empty, or a
62
+ # day has passed at least.
63
+ #
64
+ # @see Receipt
65
+ #
66
+ class Receipts
67
+ def initialize(results:, requested_ids:)
68
+ self.results = results
69
+ self.requested_ids = requested_ids
70
+ end
71
+
72
+ def each
73
+ receipts.each do |receipt|
74
+ next unless receipt.ok?
75
+
76
+ yield receipt
77
+ end
78
+ end
79
+
80
+ def each_error
81
+ results.each do |receipt|
82
+ next yield receipt if receipt.is_a?(Error)
83
+ next unless receipt.error?
84
+
85
+ yield receipt
86
+ end
87
+ end
88
+
89
+ def unresolved_ids
90
+ requested_ids - results.keys
91
+ end
92
+
93
+ private
94
+
95
+ attr_accessor :results, :requested_ids
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expo
4
+ module Push
5
+ ##
6
+ # A ticket represents a single receipt ticket.
7
+ #
8
+ # - In case of an #ok? ticket, holds the receipt id in #id
9
+ # - In case of an #error? ticket, holds the #message, #explain
10
+ #
11
+ # Some failed tickets may expose which push token is not or no longer
12
+ # valid. This is exposed via #original_push_token.
13
+ #
14
+ class Ticket
15
+ attr_reader :data
16
+
17
+ def initialize(data)
18
+ self.data = data
19
+ end
20
+
21
+ def id
22
+ data.fetch('id')
23
+ end
24
+
25
+ def original_push_token
26
+ return nil if ok?
27
+
28
+ if message.include?('PushToken[')
29
+ return /Expo(?:nent)?PushToken\[(?:[^\]]+?)\]/.match(message) { |match| match[0] }
30
+ end
31
+
32
+ /\A[a-z\d]{8}-[a-z\d]{4}-[a-z\d]{4}-[a-z\d]{4}-[a-z\d]{12}\z/i.match(message) { |match| match[0] }
33
+ end
34
+
35
+ def message
36
+ data.fetch('message')
37
+ end
38
+
39
+ def explain
40
+ Expo::Push::Error.explain((data['details'] || {})['error'])
41
+ end
42
+
43
+ def ok?
44
+ data['status'] == 'ok'
45
+ end
46
+
47
+ def error?
48
+ data['status'] == 'error'
49
+ end
50
+
51
+ private
52
+
53
+ attr_writer :data
54
+ end
55
+
56
+ ##
57
+ # Tickets are paged: each batch when sending the notifications is one
58
+ # tickets entry. Each tickets entry has many tickets.
59
+ #
60
+ # To ease exploration and continuation of the tickets, use the
61
+ # folowing methods:
62
+ #
63
+ # - #batch_ids: slices all the receipts into chunks
64
+ # - #each: iterates over each single ticket that is NOT an error
65
+ # - #each_error: iterates over each errorered batch and failed ticket
66
+ #
67
+ # You MUST handle each error, and you MUST first check if its an Error
68
+ # or not, because of the way an entire batch call can fail.
69
+ #
70
+ # @see Ticket
71
+ #
72
+ class Tickets
73
+ def initialize(results)
74
+ self.results = results
75
+ end
76
+
77
+ def ids
78
+ [].tap do |ids|
79
+ each { |ticket| ids << ticket.id }
80
+ end
81
+ end
82
+
83
+ def batch_ids
84
+ ids.each_slice(PUSH_NOTIFICATION_RECEIPT_CHUNK_LIMIT).to_a
85
+ end
86
+
87
+ def each
88
+ results.each do |tickets|
89
+ next if tickets.is_a?(Error)
90
+
91
+ tickets.each do |ticket|
92
+ next unless ticket.ok?
93
+
94
+ yield ticket
95
+ end
96
+ end
97
+ end
98
+
99
+ def each_error
100
+ results.each do |tickets|
101
+ if tickets.is_a?(Error)
102
+ yield tickets
103
+ else
104
+ tickets.each do |ticket|
105
+ next unless ticket.error?
106
+
107
+ yield ticket
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ private
114
+
115
+ attr_accessor :results
116
+ end
117
+ end
118
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: expo-server-sdk
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Derk-Jan Karrenbeld
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-10-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: connection_pool
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: http
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.0'
41
+ description: This gem has been written to fix shortcomings with the current community
42
+ provided gem, which has many outstanding issues and open pull requests.
43
+ email:
44
+ - derk-jan+github@karrenbeld.info
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitattributes"
50
+ - ".github/workflows/main.yml"
51
+ - ".gitignore"
52
+ - ".rubocop.yml"
53
+ - CODE_OF_CONDUCT.md
54
+ - Gemfile
55
+ - Gemfile.lock
56
+ - LICENSE.txt
57
+ - README.md
58
+ - Rakefile
59
+ - bin/console
60
+ - bin/setup
61
+ - expo-server-sdk.gemspec
62
+ - lib/expo/server/sdk.rb
63
+ - lib/expo/server/sdk/version.rb
64
+ - lib/push/chunk.rb
65
+ - lib/push/client.rb
66
+ - lib/push/notification.rb
67
+ - lib/push/receipts.rb
68
+ - lib/push/tickets.rb
69
+ homepage: https://github.com/sleeplessbyte/expo-server-sdk-ruby
70
+ licenses:
71
+ - MIT
72
+ metadata:
73
+ homepage_uri: https://github.com/sleeplessbyte/expo-server-sdk-ruby
74
+ source_code_uri: https://github.com/sleeplessbyte/expo-server-sdk-ruby
75
+ bug_tracker_uri: https://github.com/sleeplessbyte/expo-server-sdk-ruby/issues
76
+ changelog_uri: https://github.com/sleeplessbyte/expo-server-sdk-ruby/blob/main/CHANGELOG.md
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: 2.6.8
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubygems_version: 3.1.6
93
+ signing_key:
94
+ specification_version: 4
95
+ summary: Modern replacement for exponent-server-sdk
96
+ test_files: []