onesignal-ruby 0.2.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.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +14 -0
  3. data/.gitignore +17 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +182 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +12 -0
  8. data/Gemfile.lock +82 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +179 -0
  11. data/Rakefile +8 -0
  12. data/bin/console +15 -0
  13. data/bin/setup +8 -0
  14. data/fixtures/vcr_cassettes/os-fetch-noti.yml +76 -0
  15. data/fixtures/vcr_cassettes/os-fetch-player.yml +72 -0
  16. data/fixtures/vcr_cassettes/os-fetch-players.yml +72 -0
  17. data/fixtures/vcr_cassettes/os-send-noti.yml +145 -0
  18. data/lib/onesignal.rb +49 -0
  19. data/lib/onesignal/attachments.rb +27 -0
  20. data/lib/onesignal/auto_map.rb +13 -0
  21. data/lib/onesignal/autoloader.rb +7 -0
  22. data/lib/onesignal/client.rb +61 -0
  23. data/lib/onesignal/commands.rb +7 -0
  24. data/lib/onesignal/commands/autoloader.rb +7 -0
  25. data/lib/onesignal/commands/base_command.rb +23 -0
  26. data/lib/onesignal/commands/create_notification.rb +15 -0
  27. data/lib/onesignal/commands/fetch_notification.rb +15 -0
  28. data/lib/onesignal/commands/fetch_player.rb +15 -0
  29. data/lib/onesignal/commands/fetch_players.rb +11 -0
  30. data/lib/onesignal/configuration.rb +14 -0
  31. data/lib/onesignal/filter.rb +132 -0
  32. data/lib/onesignal/notification.rb +35 -0
  33. data/lib/onesignal/notification/contents.rb +17 -0
  34. data/lib/onesignal/notification/headings.rb +17 -0
  35. data/lib/onesignal/responses.rb +7 -0
  36. data/lib/onesignal/responses/autoloader.rb +7 -0
  37. data/lib/onesignal/responses/base_response.rb +13 -0
  38. data/lib/onesignal/responses/notification.rb +45 -0
  39. data/lib/onesignal/responses/player.rb +21 -0
  40. data/lib/onesignal/segment.rb +22 -0
  41. data/lib/onesignal/sounds.rb +39 -0
  42. data/lib/onesignal/version.rb +6 -0
  43. data/onesignal-ruby.gemspec +47 -0
  44. metadata +251 -0
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OneSignal
4
+ class Attachments
5
+ attr_reader :data, :url, :ios_attachments, :android_picture, :amazon_picture, :chrome_picture
6
+
7
+ def initialize data: nil, url: nil, ios_attachments: nil, android_picture: nil, amazon_picture: nil, chrome_picture: nil
8
+ @data = data
9
+ @url = url
10
+ @ios_attachments = ios_attachments
11
+ @android_picture = android_picture
12
+ @amazon_picture = amazon_picture
13
+ @chrome_picture = chrome_picture
14
+ end
15
+
16
+ def as_json options = nil
17
+ {
18
+ 'data' => @data.as_json(options),
19
+ 'url' => @url,
20
+ 'ios_attachments' => @ios_attachments.as_json(options),
21
+ 'big_picture' => @android_picture,
22
+ 'adm_big_picture' => @amazon_picture,
23
+ 'chrome_big_picture' => @chrome_picture
24
+ }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OneSignal
4
+ module AutoMap
5
+ def create_readers **attributes
6
+ attributes.keys.each do |k|
7
+ self.class.define_method k do
8
+ attributes[k]
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dir["#{File.expand_path(__dir__)}/*.rb"].each do |file|
4
+ filename = File.basename file
5
+ classname = filename.split('.rb').first.camelize
6
+ OneSignal.autoload classname, File.expand_path("../#{filename}", __FILE__)
7
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+
5
+ module OneSignal
6
+ class Client
7
+ def initialize app_id, api_key, api_url
8
+ @app_id = app_id
9
+ @api_key = api_key
10
+ @api_url = api_url
11
+ @conn = ::Faraday.new(url: api_url) do |faraday|
12
+ # faraday.response :logger do |logger|
13
+ # logger.filter(/(api_key=)(\w+)/, '\1[REMOVED]')
14
+ # logger.filter(/(Basic )(\w+)/, '\1[REMOVED]')
15
+ # end
16
+ faraday.adapter Faraday.default_adapter
17
+ end
18
+ end
19
+
20
+ def create_notification notification
21
+ post 'notifications', notification
22
+ end
23
+
24
+ def fetch_notification notification_id
25
+ get "notifications/#{notification_id}"
26
+ end
27
+
28
+ def fetch_players
29
+ get 'players'
30
+ end
31
+
32
+ def fetch_player player_id
33
+ get "players/#{player_id}"
34
+ end
35
+
36
+ private
37
+
38
+ def create_body payload
39
+ body = payload.as_json
40
+ body['app_id'] = @app_id
41
+ body
42
+ end
43
+
44
+ def post url, body
45
+ @conn.post do |req|
46
+ req.url url
47
+ req.body = create_body(body).to_json
48
+ req.headers['Content-Type'] = 'application/json'
49
+ req.headers['Authorization'] = "Basic #{@api_key}"
50
+ end
51
+ end
52
+
53
+ def get url
54
+ @conn.get do |req|
55
+ req.url url, app_id: @app_id
56
+ req.headers['Content-Type'] = 'application/json'
57
+ req.headers['Authorization'] = "Basic #{@api_key}"
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OneSignal
4
+ module Commands
5
+ require 'onesignal/commands/autoloader'
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dir["#{File.expand_path(__dir__)}/*.rb"].each do |file|
4
+ filename = File.basename file
5
+ classname = filename.split('.rb').first.camelize
6
+ OneSignal::Commands.autoload classname, File.expand_path("../#{filename}", __FILE__)
7
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'simple_command'
4
+
5
+ module OneSignal
6
+ module Commands
7
+ class BaseCommand
8
+ prepend ::SimpleCommand
9
+
10
+ def call
11
+ raise NotImplementedError, 'this is an abstract class'
12
+ end
13
+
14
+ def client
15
+ @client ||= OneSignal::Client.new(config.app_id, config.api_key, config.api_url)
16
+ end
17
+
18
+ def config
19
+ OneSignal.config
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OneSignal
4
+ module Commands
5
+ class CreateNotification < BaseCommand
6
+ def initialize notification
7
+ @notification = notification
8
+ end
9
+
10
+ def call
11
+ client.create_notification @notification
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OneSignal
4
+ module Commands
5
+ class FetchNotification < BaseCommand
6
+ def initialize notification_id
7
+ @notification_id = notification_id
8
+ end
9
+
10
+ def call
11
+ client.fetch_notification @notification_id
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OneSignal
4
+ module Commands
5
+ class FetchPlayer < BaseCommand
6
+ def initialize player_id
7
+ @player_id = player_id
8
+ end
9
+
10
+ def call
11
+ client.fetch_player @player_id
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OneSignal
4
+ module Commands
5
+ class FetchPlayers < BaseCommand
6
+ def call
7
+ client.fetch_players
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OneSignal
4
+ class Configuration
5
+ attr_accessor :app_id, :api_key, :api_url, :active
6
+
7
+ def initialize
8
+ @app_id = ENV['ONESIGNAL_APP_ID']
9
+ @api_key = ENV['ONESIGNAL_API_KEY']
10
+ @api_url = "https://onesignal.com/api/#{OneSignal::API_VERSION}"
11
+ @active = true
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OneSignal
4
+ class Filter
5
+ OR = { operator: 'OR' }.freeze
6
+
7
+ attr_reader :field, :key, :relation, :value, :hours_ago, :location
8
+
9
+ class << self
10
+ def last_session
11
+ FilterBuilder.new 'last_session'
12
+ end
13
+
14
+ def first_session
15
+ FilterBuilder.new 'first_session'
16
+ end
17
+
18
+ def session_count
19
+ FilterBuilder.new 'session_count'
20
+ end
21
+
22
+ def session_time
23
+ FilterBuilder.new 'session_time'
24
+ end
25
+
26
+ def amount_spent
27
+ FilterBuilder.new 'amount_spent'
28
+ end
29
+
30
+ def bought_sku sku
31
+ FilterBuilder.new 'bought_sku', key: sku
32
+ end
33
+
34
+ def tag tag
35
+ FilterBuilder.new 'tag', key: tag
36
+ end
37
+
38
+ def language
39
+ FilterBuilder.new 'language'
40
+ end
41
+
42
+ def app_version
43
+ FilterBuilder.new 'app_version'
44
+ end
45
+
46
+ def location radius:, lat:, long:
47
+ location = OpenStruct.new(radius: radius, latitude: lat, longitude: long)
48
+ new(FilterBuilder.new('location', location: location))
49
+ end
50
+
51
+ def email email
52
+ new(FilterBuilder.new('email', value: email))
53
+ end
54
+
55
+ def country
56
+ FilterBuilder.new('country')
57
+ end
58
+ end
59
+
60
+ def hours_ago!
61
+ @hours_ago ||= @value
62
+ @value = nil
63
+ self
64
+ end
65
+
66
+ def as_json options = nil
67
+ super(options).select { |_k, v| v.present? }
68
+ end
69
+
70
+ private
71
+
72
+ def initialize builder
73
+ @field = builder.b_field
74
+ @key = builder.b_key
75
+ @relation = builder.b_relation
76
+ @value = builder.b_value
77
+ @hours_ago = builder.b_hours_ago
78
+ @location = builder.b_location
79
+ end
80
+
81
+ class FilterBuilder
82
+ attr_reader :b_field, :b_key, :b_relation, :b_value, :b_hours_ago, :b_location
83
+
84
+ def initialize field, params = {}
85
+ @b_field = field
86
+ @b_key = params[:key]
87
+ @b_location = params[:location]
88
+ @b_value = params[:value]
89
+ end
90
+
91
+ def lesser_than value
92
+ @b_relation = '<'
93
+ @b_value = value.to_s
94
+ build
95
+ end
96
+
97
+ def greater_than value
98
+ @b_relation = '>'
99
+ @b_value = value.to_s
100
+ build
101
+ end
102
+
103
+ def equals value
104
+ @b_relation = '='
105
+ @b_value = value.to_s
106
+ build
107
+ end
108
+
109
+ def not_equals value
110
+ @b_relation = '!='
111
+ @b_value = value.to_s
112
+ build
113
+ end
114
+
115
+ def exists
116
+ @b_relation = 'exists'
117
+ build
118
+ end
119
+
120
+ def not_exists
121
+ @b_relation = 'not_exists'
122
+ build
123
+ end
124
+
125
+ private
126
+
127
+ def build
128
+ Filter.new self
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'onesignal/notification/contents'
4
+ require 'onesignal/notification/headings'
5
+
6
+ module OneSignal
7
+ class Notification
8
+ attr_reader :contents, :headings, :template_id, :included_segments, :excluded_segments,
9
+ :send_after, :attachments, :sounds
10
+
11
+ def initialize **params
12
+ unless params.include?(:contents) || params.include?(:template_id)
13
+ raise ArgumentError, 'missing contents or template_id'
14
+ end
15
+
16
+ @contents = params[:contents]
17
+ @headings = params[:headings]
18
+ @template_id = params[:template_id]
19
+ @included_segments = params[:included_segments]
20
+ @excluded_segments = params[:excluded_segments]
21
+ @send_after = params[:send_after].to_s
22
+ @attachments = params[:attachments]
23
+ @filters = params[:filters]
24
+ @sounds = params[:sounds]
25
+ end
26
+
27
+ def as_json options = {}
28
+ super(options)
29
+ .except('attachments', 'sounds')
30
+ .merge(@attachments&.as_json(options) || {})
31
+ .merge(@sounds&.as_json(options) || {})
32
+ .select { |_k, v| v.present? }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OneSignal
4
+ class Notification
5
+ class Contents
6
+ include OneSignal::AutoMap
7
+ extend Forwardable
8
+
9
+ def_delegators :@content, :as_json, :to_json
10
+
11
+ def initialize en:, **content
12
+ @content = content.merge(en: en)
13
+ create_readers @content
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OneSignal
4
+ class Notification
5
+ class Headings
6
+ include OneSignal::AutoMap
7
+ extend Forwardable
8
+
9
+ def_delegators :@headings, :as_json, :to_json
10
+
11
+ def initialize en:, **headings
12
+ @headings = headings.merge(en: en)
13
+ create_readers @headings
14
+ end
15
+ end
16
+ end
17
+ end