onesignal-ruby-rails6 0.3.0.1

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 (50) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +14 -0
  3. data/.github/workflows/gempush.yml +41 -0
  4. data/.github/workflows/ruby.yml +20 -0
  5. data/.gitignore +17 -0
  6. data/.rspec +3 -0
  7. data/.rubocop.yml +182 -0
  8. data/CODE_OF_CONDUCT.md +74 -0
  9. data/Gemfile +12 -0
  10. data/Gemfile.lock +85 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +211 -0
  13. data/Rakefile +8 -0
  14. data/bin/console +15 -0
  15. data/bin/setup +8 -0
  16. data/fixtures/vcr_cassettes/os-csv-export.yml +135 -0
  17. data/fixtures/vcr_cassettes/os-fetch-noti.yml +76 -0
  18. data/fixtures/vcr_cassettes/os-fetch-player.yml +72 -0
  19. data/fixtures/vcr_cassettes/os-fetch-players.yml +72 -0
  20. data/fixtures/vcr_cassettes/os-send-noti.yml +145 -0
  21. data/lib/onesignal.rb +60 -0
  22. data/lib/onesignal/attachments.rb +27 -0
  23. data/lib/onesignal/auto_map.rb +13 -0
  24. data/lib/onesignal/autoloader.rb +7 -0
  25. data/lib/onesignal/client.rb +81 -0
  26. data/lib/onesignal/commands.rb +7 -0
  27. data/lib/onesignal/commands/autoloader.rb +7 -0
  28. data/lib/onesignal/commands/base_command.rb +23 -0
  29. data/lib/onesignal/commands/create_notification.rb +15 -0
  30. data/lib/onesignal/commands/csv_export.rb +15 -0
  31. data/lib/onesignal/commands/fetch_notification.rb +15 -0
  32. data/lib/onesignal/commands/fetch_player.rb +15 -0
  33. data/lib/onesignal/commands/fetch_players.rb +11 -0
  34. data/lib/onesignal/configuration.rb +19 -0
  35. data/lib/onesignal/filter.rb +140 -0
  36. data/lib/onesignal/included_targets.rb +47 -0
  37. data/lib/onesignal/notification.rb +37 -0
  38. data/lib/onesignal/notification/contents.rb +17 -0
  39. data/lib/onesignal/notification/headings.rb +17 -0
  40. data/lib/onesignal/responses.rb +7 -0
  41. data/lib/onesignal/responses/autoloader.rb +7 -0
  42. data/lib/onesignal/responses/base_response.rb +18 -0
  43. data/lib/onesignal/responses/csv_export.rb +18 -0
  44. data/lib/onesignal/responses/notification.rb +45 -0
  45. data/lib/onesignal/responses/player.rb +21 -0
  46. data/lib/onesignal/segment.rb +22 -0
  47. data/lib/onesignal/sounds.rb +39 -0
  48. data/lib/onesignal/version.rb +6 -0
  49. data/onesignal-ruby.gemspec +48 -0
  50. metadata +270 -0
@@ -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 CsvExport < BaseCommand
6
+ def initialize params
7
+ @params = params || {}
8
+ end
9
+
10
+ def call
11
+ client.csv_export @params
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,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module OneSignal
6
+ class Configuration
7
+ attr_accessor :app_id, :api_key, :api_url, :active, :logger
8
+
9
+ def initialize
10
+ @app_id = ENV['ONESIGNAL_APP_ID']
11
+ @api_key = ENV['ONESIGNAL_API_KEY']
12
+ @api_url = "https://onesignal.com/api/#{OneSignal::API_VERSION}"
13
+ @active = true
14
+ @logger = Logger.new(STDOUT).tap do |logger|
15
+ logger.level = Logger::INFO
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,140 @@
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 country
47
+ FilterBuilder.new 'country'
48
+ end
49
+
50
+ def location radius:, lat:, long:
51
+ location = OpenStruct.new radius: radius, latitude: lat, longitude: long
52
+ new FilterBuilder.new('location', location: location)
53
+ end
54
+
55
+ def email email
56
+ new(FilterBuilder.new('email', value: email))
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
+ alias < lesser_than
98
+
99
+ def greater_than value
100
+ @b_relation = '>'
101
+ @b_value = value.to_s
102
+ build
103
+ end
104
+
105
+ alias > greater_than
106
+
107
+ def equals value
108
+ @b_relation = '='
109
+ @b_value = value.to_s
110
+ build
111
+ end
112
+
113
+ alias == equals
114
+
115
+ def not_equals value
116
+ @b_relation = '!='
117
+ @b_value = value.to_s
118
+ build
119
+ end
120
+
121
+ alias != not_equals
122
+
123
+ def exists
124
+ @b_relation = 'exists'
125
+ build
126
+ end
127
+
128
+ def not_exists
129
+ @b_relation = 'not_exists'
130
+ build
131
+ end
132
+
133
+ private
134
+
135
+ def build
136
+ Filter.new self
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OneSignal
4
+ class IncludedTargets
5
+ attr_reader :include_player_ids, :include_email_tokens, :include_external_user_ids, :include_ios_tokens,
6
+ :include_wp_wns_uris, :include_amazon_reg_ids, :include_chrome_reg_ids, :include_chrome_web_reg_ids,
7
+ :include_android_reg_ids
8
+
9
+ def initialize params
10
+ raise ArgumentError, 'include_player_ids cannot be used with other targets' if params.key?(:include_player_ids) && params.keys.count > 1
11
+
12
+ @include_player_ids = params[:include_player_ids]
13
+ @include_email_tokens = params[:include_email_tokens]
14
+ @include_external_user_ids = params[:include_external_user_ids]
15
+
16
+ @include_ios_tokens = print_warning params, :include_ios_tokens
17
+ @include_wp_wns_uris = print_warning params, :include_wp_wns_uris
18
+ @include_amazon_reg_ids = print_warning params, :include_amazon_reg_ids
19
+ @include_chrome_reg_ids = print_warning params, :include_chrome_reg_ids
20
+ @include_chrome_web_reg_ids = print_warning params, :include_chrome_web_reg_ids
21
+ @include_android_reg_ids = print_warning params, :include_android_reg_ids
22
+ end
23
+
24
+ def print_warning params, name
25
+ if params.key? name
26
+ OneSignal.config.logger.warn "OneSignal WARNING - Use of #{name} is not recommended. " \
27
+ 'Use either include_player_ids, include_email_tokens or include_external_user_ids. ' \
28
+ 'See https://documentation.onesignal.com/reference#section-send-to-specific-devices'
29
+ end
30
+ params[name]
31
+ end
32
+
33
+ def as_json options = nil
34
+ {
35
+ 'include_player_ids' => @include_player_ids,
36
+ 'include_email_tokens' => @include_email_tokens,
37
+ 'include_external_user_ids' => @include_external_user_ids,
38
+ 'include_ios_tokens' => @include_ios_tokens,
39
+ 'include_wp_wns_uris' => @include_wp_wns_uris,
40
+ 'include_amazon_reg_ids' => @include_amazon_reg_ids,
41
+ 'include_chrome_reg_ids' => @include_chrome_reg_ids,
42
+ 'include_chrome_web_reg_ids' => @include_chrome_web_reg_ids,
43
+ 'include_android_reg_ids' => @include_android_reg_ids
44
+ }
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,37 @@
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
+ :included_targets, :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
+ @included_targets = params[:included_targets]
22
+ @send_after = params[:send_after].to_s
23
+ @attachments = params[:attachments]
24
+ @filters = params[:filters]
25
+ @sounds = params[:sounds]
26
+ end
27
+
28
+ def as_json options = {}
29
+ super(options)
30
+ .except('attachments', 'sounds', 'included_targets')
31
+ .merge(@attachments&.as_json(options) || {})
32
+ .merge(@sounds&.as_json(options) || {})
33
+ .merge(@included_targets&.as_json(options) || {})
34
+ .select { |_k, v| v.present? }
35
+ end
36
+ end
37
+ 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
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OneSignal
4
+ module Responses
5
+ require 'onesignal/responses/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::Responses.autoload classname, File.expand_path("../#{filename}", __FILE__)
7
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OneSignal
4
+ module Responses
5
+ class BaseResponse
6
+ def initialize attributes = {}
7
+ @attributes = attributes.deep_symbolize_keys
8
+ .keep_if { |k, _v| self.class::ATTRIBUTES_WHITELIST.include?(k.to_sym) }
9
+
10
+ self.class::ATTRIBUTES_WHITELIST.each do |attribute|
11
+ self.class.send(:define_method, attribute) do
12
+ @attributes[attribute]
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OneSignal
4
+ module Responses
5
+ # Example JSON
6
+ # {
7
+ # "csv_file_url": "https://onesignal.s3.amazonaws.com/csv_exports/test/users_abc123.csv.gz"
8
+ # }
9
+ class CsvExport < BaseResponse
10
+ ATTRIBUTES_WHITELIST = %i[csv_file_url].freeze
11
+
12
+ def self.from_json json
13
+ body = json.is_a?(String) ? JSON.parse(json) : json
14
+ new(body)
15
+ end
16
+ end
17
+ end
18
+ end