trycourier 1.0.2 → 1.1.0

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: 23f5a0957ead43adbaf9f97c33e6236149902be1df820f120214515d36a2d26b
4
- data.tar.gz: 304eff5f123c7adf297bb6e4b1d3a2eb620295bc3a9c2e254e2f369ba194befe
3
+ metadata.gz: 40ffa9399327479e0f0fa89c350decd17f242caa48b91f1a772cebd4f25d5610
4
+ data.tar.gz: fd159122320af8ab96223890b78061dd21ce193adadceb146f7e18d36a798032
5
5
  SHA512:
6
- metadata.gz: 5423807878697faef75fd27e31aee0dd43ce669f176275d6b321d57f03b38736c5a96d1ad9a0baff93c6f83442b22f1fe80efce496de6e6c0f1dd3bbdb8cbae8
7
- data.tar.gz: db0ad387345128716957853b682c0f6639e6a4f14978b7787383228ee76bcccbe97837b8503a840c68bdbe4e18d5d3e078920a21c2ded5a8125c1689031132a5
6
+ metadata.gz: 524f60d42ec87e581ce591d7550f34ab0a5c592d33618465eba1d26a25822b8c8d3974ad188ef5cc089d24947424ffebe434655e64481b81fed244b95fd22fbf
7
+ data.tar.gz: bb97291b655840c5051b78beb48d345827be048392e16c7b7486749eac80e45f111cedc216448d8a93997eaae2f57c90c089c7ff1abbc00ad66aa9930bba9212
@@ -0,0 +1,49 @@
1
+ name: Ruby Gem
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ tags:
7
+ - v*
8
+ pull_request:
9
+ branches: [master]
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: ubuntu-latest
14
+
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - name: Set up Ruby 2.7
18
+ uses: actions/setup-ruby@v1
19
+ with:
20
+ ruby-version: 2.7.x
21
+ - name: Install dependencies
22
+ run: bundle install
23
+ - name: Run tests
24
+ # Skipping rubocop for now
25
+ # run: bundle exec rake
26
+ run: bundle exec rspec spec
27
+ build:
28
+ name: Build + Publish
29
+ needs: test
30
+ if: startsWith(github.ref, 'refs/tags/v')
31
+ runs-on: ubuntu-latest
32
+
33
+ steps:
34
+ - uses: actions/checkout@v2
35
+ - name: Set up Ruby 2.7
36
+ uses: actions/setup-ruby@v1
37
+ with:
38
+ ruby-version: 2.7.x
39
+
40
+ - name: Publish to RubyGems
41
+ run: |
42
+ mkdir -p $HOME/.gem
43
+ touch $HOME/.gem/credentials
44
+ chmod 0600 $HOME/.gem/credentials
45
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
46
+ gem build *.gemspec
47
+ gem push *.gem
48
+ env:
49
+ GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
@@ -0,0 +1,66 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ This project adheres to [Semantic Versioning](http://semver.org/).
5
+
6
+ ## [Unreleased][unreleased]
7
+
8
+ ## [v1.1.0] - 2021-01-26
9
+ ### Added
10
+ - Support for Basic Auth
11
+ - ENV variables `COURIER_AUTH_USERNAME` and `COURIER_AUTH_PASSWORD` OR set with params
12
+ - Token Auth using ENV variables
13
+ - `COURIER_AUTH_TOKEN`
14
+ - Base URL parameter (with default of api.courier.com)
15
+ - ENV variable `COURIER_BASE_URL`
16
+ - Support for Lists API by @jrweingart
17
+ - `POST /send/list` with `client.lists.send` method
18
+ - `GET /lists` with `client.lists.list` method
19
+ - `GET /lists/{list_id}` with `client.lists.get` method
20
+ - `PUT /lists/{list_id}` with `client.lists.put` method
21
+ - `DELETE /lists/{list_id}` with `client.lists.delete` method
22
+ - `PUT /lists/{list_id}/restore` with `client.lists.restore` method
23
+ - `GET /lists/{list_id}/subscriptions` with `client.lists.get_subscriptions` method
24
+ - `PUT /lists/{list_id}/subscriptions` with `client.lists.put_subscriptions` method
25
+ - `PUT /lists/{list_id}/subscriptions/{recipient_id}` with `client.lists.subscribe` method
26
+ - `DELETE /lists/{list_id}/subscriptions/{recipient_id}` with `client.lists.unsubscribe` method
27
+
28
+ - Support for Profiles API by @jrweingart
29
+ - `GET /profiles/{recipient_id}` with `client.profiles.get` method
30
+ - `GET /profiles/{recipient_id}/lists` with `client.profiles.get_subscriptions` method
31
+ - `PUT /profiles/{recipient_id}` with `client.profiles.replace` and `client.profiles.add` methods
32
+ - `PATCH /profiles/{recipient_id}` with `client.profiles.patch` method
33
+ - `POST /profiles/{recipient_id}` with `client.profiles.merge` method
34
+
35
+ - Support for Messages API by @jrweingart
36
+ - `GET /messages` with `client.messages.list` method
37
+ - `GET /messages/{message_id}` with `client.messages.get` method
38
+ - `GET /messages/{message_id}/history` with `client.messages.get_history` method
39
+
40
+ - Support for Events API by @jrweingart
41
+ - `GET /events` with `client.events.list` method
42
+ - `GET /events/{event_id}` with `client.event.get` method
43
+ - `PUT /events/{event_id}` with `client.events.replace` and `client.events.add` methods
44
+
45
+ - Support for Brands API by @jrweingart
46
+ - `GET /brands` with `client.brands.list` method
47
+ - `GET /brands/brand_id` with `client.brands.get` method
48
+ - `POST /brands` with `client.brands.create` method
49
+ - `PUT /brands/brand_id` with `client.brands.replace` method
50
+ - `DELETE /brands/brand_id` with `client.brands.delete` method
51
+
52
+ ## [v1.0.2] - 2021-01-06
53
+ ### Added
54
+ - Minor bug fixes to ensure proper SSL certification by @scarney81
55
+
56
+ ## [v1.0.1] - 2020-03-04
57
+ ### Added
58
+ - Support for Send API by @troy
59
+
60
+ ## v1.0.0 - 2020-03-03
61
+ Initial release by @troygoode
62
+
63
+ [unreleased]: https://github.com/trycourier/courier-ruby/compare/v1.1.0...HEAD
64
+ [v1.1.0]: https://github.com/trycourier/courier-ruby/compare/v1.0.2...v1.1.0
65
+ [v1.0.2]: https://github.com/trycourier/courier-ruby/compare/v1.0.1...v1.0.2
66
+ [v1.0.1]: https://github.com/trycourier/courier-ruby/compare/v1.0.0...v1.0.1
data/Gemfile CHANGED
@@ -5,3 +5,4 @@ gemspec
5
5
 
6
6
  gem "rake", "~> 12.0"
7
7
  gem "rspec", "~> 3.0"
8
+ gem "standard", group: [:development, :test]
@@ -6,8 +6,21 @@ PATH
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ addressable (2.7.0)
10
+ public_suffix (>= 2.0.2, < 5.0)
11
+ ast (2.4.1)
12
+ crack (0.4.5)
13
+ rexml
9
14
  diff-lcs (1.3)
15
+ hashdiff (1.0.1)
16
+ parallel (1.20.1)
17
+ parser (3.0.0.0)
18
+ ast (~> 2.4.1)
19
+ public_suffix (4.0.6)
20
+ rainbow (3.0.0)
10
21
  rake (12.3.3)
22
+ regexp_parser (2.0.3)
23
+ rexml (3.2.4)
11
24
  rspec (3.9.0)
12
25
  rspec-core (~> 3.9.0)
13
26
  rspec-expectations (~> 3.9.0)
@@ -21,6 +34,29 @@ GEM
21
34
  diff-lcs (>= 1.2.0, < 2.0)
22
35
  rspec-support (~> 3.9.0)
23
36
  rspec-support (3.9.2)
37
+ rubocop (1.4.2)
38
+ parallel (~> 1.10)
39
+ parser (>= 2.7.1.5)
40
+ rainbow (>= 2.2.2, < 4.0)
41
+ regexp_parser (>= 1.8)
42
+ rexml
43
+ rubocop-ast (>= 1.1.1)
44
+ ruby-progressbar (~> 1.7)
45
+ unicode-display_width (>= 1.4.0, < 2.0)
46
+ rubocop-ast (1.4.0)
47
+ parser (>= 2.7.1.5)
48
+ rubocop-performance (1.9.1)
49
+ rubocop (>= 0.90.0, < 2.0)
50
+ rubocop-ast (>= 0.4.0)
51
+ ruby-progressbar (1.11.0)
52
+ standard (0.10.2)
53
+ rubocop (= 1.4.2)
54
+ rubocop-performance (= 1.9.1)
55
+ unicode-display_width (1.7.0)
56
+ webmock (3.11.0)
57
+ addressable (>= 2.3.6)
58
+ crack (>= 0.3.2)
59
+ hashdiff (>= 0.4.0, < 2.0.0)
24
60
 
25
61
  PLATFORMS
26
62
  ruby
@@ -28,7 +64,9 @@ PLATFORMS
28
64
  DEPENDENCIES
29
65
  rake (~> 12.0)
30
66
  rspec (~> 3.0)
67
+ standard
31
68
  trycourier!
69
+ webmock (>= 1.24.2)
32
70
 
33
71
  BUNDLED WITH
34
72
  2.1.4
data/README.md CHANGED
@@ -19,35 +19,330 @@ Or install it yourself as:
19
19
  $ gem install trycourier
20
20
 
21
21
  ## Usage
22
-
22
+ After installing, make sure to include this line at the top of your ruby file:
23
23
  ```ruby
24
24
  require "trycourier"
25
+ ```
26
+ To create a Courier Ruby client, all you need to do is pass in your authentication information. Then, you can start sending!
27
+ ### Using token authentication (most secure)
28
+ ```ruby
29
+ client = Courier::Client.new "your-auth-token" # or set via COURIER_AUTH_TOKEN env var (recommended)
30
+ ```
25
31
 
26
- begin
27
- client = Courier::Client.new "your-auth-token" # or set via COURIER_AUTH_TOKEN env var
28
- res = client.send({
32
+ ### Using basic authentication
33
+ ```ruby
34
+ client = Courier::Client.new(username: "USERNAME", password: "PASSWORD") # or set via COURIER_AUTH_USERNAME and COURIER_AUTH_PASSWORD env vars
35
+ ```
36
+ ### Sending a message to an individual recipient
37
+ ```ruby
38
+ client = Courier::Client.new "your-auth-token" # or set via COURIER_AUTH_TOKEN env var
39
+ res = client.send({
29
40
  "event" => "your-event-id",
30
41
  "recipient" => "your-recipient-id",
31
42
 
32
- "profile" => {
43
+ "profile" => { #optional (include any key-value pairs required by your chosen integrations. This information can also be stored in the recipient's profile in Courier)
33
44
  "email": "example@example.com",
34
45
  "phone_number": "555-867-5309"
35
46
  },
36
47
 
37
- "data" => {
48
+ "data" => { #any data you want to pass to a message template
38
49
  "world" => "Ruby!"
39
50
  }
40
51
  })
41
-
42
52
  puts res.code # the HTTP response code
43
- puts res.message_id # if 200, this will be the Courier message ID for this notification
44
- rescue Courier::ResponseError => re
53
+ puts res.message_id # if the code is 200, this will be the Courier message ID for this notification
54
+ rescue Courier::CourierAPIError => re #error sent from from the API
45
55
  puts re.message
46
- rescue Courier::InputError => ie
47
- puts ie.message
48
56
  end
57
+ ```
58
+ ## Advanced Usage
59
+
60
+ ### Lists
61
+ ```ruby
62
+ require "trycourier"
63
+ client = Courier::Client.new "your-auth-token" # or set via COURIER_AUTH_TOKEN env var
64
+
65
+ """
66
+ Creating a List
67
+ """
68
+ res = client.lists.put(list_id, name)
69
+ puts res
49
70
 
71
+ """
72
+ Example: send a message to a list
73
+ """
74
+ resp = client.lists.send(
75
+ event: "your-event-id",
76
+ list: "your.list.id",
77
+ brand: "your-brand-id", # optional
78
+ data: {}, # optional
79
+ override: {} # optional
80
+ )
81
+ puts resp['messageId'])
82
+
83
+ """
84
+ Example: send a message to a list pattern
85
+ """
86
+ resp = client.lists.send(
87
+ event: "your-event-id",
88
+ pattern: "your.list.*", #PATTERN (will send to all list ids that start with "your.list.")
89
+ brand: "your-brand-id", # optional
90
+ data: {}, # optional
91
+ override: {} # optional
92
+ )
93
+ puts resp['messageId'])
94
+
95
+ """
96
+ Example: get all lists
97
+ """
98
+ resp = client.lists.list(
99
+ cursor: "MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
100
+ )
101
+ puts resp
102
+
103
+ """
104
+ Example: get a specific list
105
+ """
106
+ resp = client.lists.get(list_id: "your-list-id")
107
+ puts resp
108
+
109
+
110
+ """
111
+ Example: delete a list
112
+ """
113
+ client.lists.delete(list_id: "your-list-id")
114
+
115
+ """
116
+ Example: restore a list
117
+ """
118
+ client.lists.restore(list_id: "your-list-id")
119
+
120
+ """
121
+ Example: get a list's subscribptions
122
+ """
123
+ resp = client.lists.get_subscriptions(list_id: "your-list-id",
124
+ cursor: "MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
125
+ )
126
+ puts resp
127
+
128
+ """
129
+ Example: replace many recipients to a new or existing list
130
+ """
131
+ client.lists.put_subscriptions(list_id: "your-list-id", recipients: [
132
+ "RECIPIENT_ID_1",
133
+ "RECIPIENT_ID_2"
134
+ ])
135
+
136
+ """
137
+ Example: Example: subscribe single recipient to a new or existing list
138
+ """
139
+ client.lists.subscribe(list_id: "your-list-id", recipient_id: "your-recipient-id")
140
+
141
+ """
142
+ Example: unsubscribe recipient from list
143
+ """
144
+ client.lists.unsubscribe(list_id: "your-list-id", recipient_id: "your-recipient-id")
50
145
  ```
146
+ ### Profiles
147
+ ```Ruby
148
+ """
149
+ Example: create a recipient's profile
150
+ """
151
+ resp = client.profiles.add(
152
+ recipient_id: "your-recipient-id",
153
+ profile: {
154
+ "email" => "example@example.com",
155
+ "name" => "Example Name"
156
+ }
157
+ )
158
+
159
+ """
160
+ Example: replace or create a recipient's profile
161
+ """
162
+ resp = client.profiles.replace(
163
+ recipient_id: "your-recipient-id",
164
+ profile: {
165
+ "email" => "example@example.com"
166
+ }
167
+ )
168
+ puts resp['status']
169
+
170
+ """
171
+ Example: merge or create a recipient's profile
172
+ """
173
+ resp = client.profiles.merge(
174
+ recipient_id: "your-recipient-id",
175
+ profile: {
176
+ "phone_number" => "+15555555555"
177
+ }
178
+ )
179
+ puts resp['status']
180
+
181
+ """
182
+ Example: get the subscribed lists of a recipient
183
+ """
184
+ resp = client.profiles.get_subscriptions(
185
+ recipient_id: "your-recipient-id",
186
+ cursor: "MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA" #optional
187
+ )
188
+ puts resp
189
+
190
+ """
191
+ Example: edit the contents of a recipient's profile with a patch operation
192
+ (follows JSON Patch conventions: RFC 6902).
193
+ """
194
+ resp = client.profiles.patch(
195
+ recipient_id: "your-recipient-id",
196
+ operations: [
197
+ {
198
+ "op" => "add", #operation 1: add this email to profile
199
+ "path" => "/parent",
200
+ "value" => "example@example.com"
201
+ }
202
+ {
203
+ "op" => "replace", #operation 2: update with new email
204
+ "path" => "/parent",
205
+ "value" => "jane@doe.com"
206
+ }
207
+ {
208
+ "op" => "copy", #operation 3: copy that email to /emergency_contact
209
+ "from" => "/parent",
210
+ "path" => "/emergency_contact"
211
+ }
212
+ ...
213
+ ]
214
+ )
215
+ puts resp
216
+
217
+
218
+ """
219
+ Example: get a recipient's profile
220
+ """
221
+ resp = client.profiles.get(recipient_id: "your-recipient-id")
222
+ puts resp
223
+ ```
224
+
225
+ ### Messages
226
+ ```Ruby
227
+ """
228
+ Example: fetch the statuses of messages you've previously sent.
229
+ """
230
+ resp = client.messages.list(
231
+ cursor: "MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
232
+ event: "your-event-id", # optional
233
+ list: "your-list-id", #optional
234
+ message_id: "your-message-id" #optional
235
+ notification: ["message-status-1", "message-status-2",...] #optional
236
+ recipient: "recipient-id" # optional
237
+ )
238
+ puts resp
239
+
240
+ """
241
+ Example: fetch the status of a message you've previously sent
242
+ """
243
+ resp = client.messages.get(message_id: "your-message-id")
244
+ puts resp
245
+
246
+ """
247
+ Example: fetch the array of events of a message you've previously sent.
248
+ """
249
+ resp = client.messages.get_history(
250
+ message_id: "your-message-id",
251
+ type: "list-type" #optional ("FILTERED", "RENDERED", "MAPPED", "PROFILE_LOADED")
252
+ )
253
+ puts resp
254
+ ```
255
+
256
+ ### Events
257
+ ```Ruby
258
+ """
259
+ Example: fetch the list of events
260
+ """
261
+ resp = client.events.list
262
+ puts resp
263
+
264
+ """
265
+ Example: fetch a specific event by event ID
266
+ """
267
+ resp = client.events.get(event_id: "your-event-id")
268
+ puts resp
269
+
270
+ """
271
+ Example: create or replace an event
272
+ """
273
+ resp = client.events.replace(
274
+ event_id: "your-event-id",
275
+ notification_id: "notification_id",
276
+ type: "notificaton" ## optional, defaults to notification
277
+ )
278
+ puts resp
279
+
280
+ """
281
+ Example: get all brands
282
+ """
283
+ resp = client.brands.list(
284
+ cursor: "MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
285
+ )
286
+ puts resp
287
+
288
+ """
289
+ Example: get a specific brand
290
+ """
291
+ resp = client.brands.get(brand_id: "brand_id")
292
+ puts resp
293
+
294
+ """
295
+ Example: create a brand
296
+ """
297
+ resp = client.brands.create(
298
+ name: "brand-name",
299
+ settings: {
300
+ "color" => {
301
+ "primary" => "#0000FF",
302
+ "secondary" => "#FF0000",
303
+ "tertiary" => "#00FF00"
304
+ }
305
+ },
306
+ id: "my-brand-id", #optional
307
+ snippets: {}, #optional
308
+ idempotency_key: "my-idemp-key", #optional
309
+ )
310
+ puts resp
311
+
312
+ """
313
+ Example: replace a brand
314
+ """
315
+ resp = client.brands.replace(
316
+ brand_id: "your-brand-id",
317
+ name: "brand-name",
318
+ settings: {}
319
+ "color" => {
320
+ "primary" => "#FF0000",
321
+ "secondary" => "#00FF00",
322
+ "tertiary" => "#0000FF"
323
+ }
324
+ },
325
+ snippets: {} #optional
326
+ )
327
+ puts resp
328
+
329
+ """
330
+ Example: delete a brand
331
+ """
332
+ resp = client.brands.delete(brand_id: "your-brand-id")
333
+ puts resp
334
+ ```
335
+
336
+ ### Notes on input and errors
337
+ With the exception of passing an auth token to create a client, and ```client.send(body)```, every parameter (optional or required) is sent using keyword arguments.
338
+ In the case of ```client.send(body)```, if the hash does not have the required components, it will throw an InputError exception, which can be caught with rescue blocks:
339
+ ```ruby
340
+ rescue InputError
341
+ ```
342
+ Any other errors from the API are thrown as a CourierAPIError. Catch these errors by putting this after your method calls:
343
+ ```ruby
344
+ rescue CourierAPIError
345
+ ```
51
346
 
52
347
  ## Development
53
348
 
data/Rakefile CHANGED
@@ -1,6 +1,7 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
+ require "standard/rake"
3
4
 
4
5
  RSpec::Core::RakeTask.new(:spec)
5
6
 
6
- task :default => :spec
7
+ task default: %i[spec standard]
@@ -1,12 +1,16 @@
1
+ require "trycourier/events"
2
+ require "trycourier/brands"
3
+ require "trycourier/lists"
4
+ require "trycourier/profiles"
5
+ require "trycourier/session"
6
+ require "trycourier/messages"
1
7
  require "trycourier/version"
8
+ require "trycourier/exceptions"
2
9
  require "net/http"
3
10
  require "json"
4
11
  require "openssl"
5
12
 
6
13
  module Courier
7
- class ResponseError < StandardError; end
8
- class InputError < StandardError; end
9
-
10
14
  class SendResponse
11
15
  attr_reader :code
12
16
  attr_reader :message_id
@@ -18,49 +22,73 @@ module Courier
18
22
  end
19
23
 
20
24
  class Client
21
- def initialize(auth_token = nil)
22
- @auth_token = auth_token || ENV['COURIER_AUTH_TOKEN']
23
- @uri = URI.parse('https://api.trycourier.app/send')
24
- if @auth_token == nil or @auth_token == ""
25
- raise InputError, "Client requires an auth_token be supplied."
25
+ def initialize(auth_token = nil, username: nil, password: nil, base_url: nil)
26
+ base = if base_url
27
+ base_url
28
+ elsif ENV["COURIER_BASE_URL"]
29
+ ENV["COURIER_BASE_URL"]
30
+ else
31
+ "https://api.courier.com"
32
+ end
33
+
34
+ @session = Courier::CourierAPISession.new(base)
35
+
36
+ if auth_token
37
+ @session.init_token_auth(auth_token)
38
+ elsif ENV["COURIER_AUTH_TOKEN"]
39
+ @session.init_token_auth(ENV["COURIER_AUTH_TOKEN"])
40
+ elsif username && password
41
+ @session.init_basic_auth(username, password)
42
+ elsif ENV["COURIER_AUTH_USERNAME"] && ENV["COURIER_AUTH_PASSWORD"]
43
+ @session.init_basic_auth(ENV["COURIER_AUTH_USERNAME"], ENV["COURIER_AUTH_PASSWORD"])
26
44
  end
45
+
46
+ @messages = Courier::Messages.new(@session)
47
+ @profiles = Courier::Profiles.new(@session)
48
+ @lists = Courier::Lists.new(@session)
49
+ @events = Courier::Events.new(@session)
50
+ @brands = Courier::Brands.new(@session)
27
51
  end
28
52
 
29
53
  def send(body)
30
54
  if not body.is_a?(Hash)
31
55
  raise InputError, "Client#send must be passed a Hash as first argument."
32
- elsif body["event"] == nil
56
+ elsif body["event"] == nil && body[:event] == nil
33
57
  raise InputError, "Must specify the 'event' key in Hash supplied to Client#send."
34
- elsif body["recipient"] == nil
58
+ elsif body["recipient"] == nil && body[:recipient] == nil
35
59
  raise InputError, "Must specify the 'recipient' key in Hash supplied to Client#send."
36
- elsif body["data"] != nil and not body["data"].is_a?(Hash)
60
+ elsif (body["data"] != nil and not body["data"].is_a?(Hash)) || (body[:data] != nil and not body[:data].is_a?(Hash))
37
61
  raise InputError, "The 'data' key in the Hash supplied to Client#send must also be a Hash."
38
- elsif body["profile"] != nil and not body["profile"].is_a?(Hash)
62
+ elsif (body["profile"] != nil and not body["profile"].is_a?(Hash)) || (body[:profile] != nil and not body[:profile].is_a?(Hash))
39
63
  raise InputError, "The 'profile' key in the Hash supplied to Client#send must also be a Hash."
40
64
  end
41
65
 
42
- http = Net::HTTP.new(@uri.host, @uri.port)
43
- http.use_ssl = true
44
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
45
-
46
- req = Net::HTTP::Post.new(@uri)
47
- req["authorization"] = "Bearer #{@auth_token}"
48
- req["content-type"] = "application/json"
49
- req["User-Agent"] = "courier-ruby/#{Courier::VERSION}"
50
- req.body = body.to_json
66
+ res = @session.send("/send", "POST", body: body)
51
67
 
52
- res = http.request(req)
53
68
  code = res.code.to_i
54
69
  obj = JSON.parse res.read_body
55
70
 
56
71
  if code == 200
57
72
  message_id = obj["messageId"]
58
- return SendResponse.new(code, message_id)
59
- elsif
60
- message = obj["Message"] == nil ? obj["message"] : obj["Message"]
73
+ SendResponse.new(code, message_id)
74
+ elsif (message = obj["Message"].nil? ? obj["message"] : obj["Message"])
61
75
  err = "#{code}: #{message}"
62
- raise ResponseError, err
76
+ raise CourierAPIError, err
63
77
  end
64
78
  end
79
+
80
+ # getters for all class variables
81
+
82
+ attr_reader :session
83
+
84
+ attr_reader :messages
85
+
86
+ attr_reader :profiles
87
+
88
+ attr_reader :events
89
+
90
+ attr_reader :lists
91
+
92
+ attr_reader :brands
65
93
  end
66
94
  end
@@ -0,0 +1,70 @@
1
+ module Courier
2
+ class Brands
3
+ KEY = "/brands"
4
+
5
+ def initialize(session)
6
+ @session = session
7
+ end
8
+
9
+ def list(cursor: nil)
10
+ params = {}
11
+ if cursor
12
+ params["cursor"] = cursor
13
+ end
14
+ res = @session.send(KEY, "GET", params: params)
15
+ ErrorHandler.check_err(res)
16
+ end
17
+
18
+ def get(brand_id:)
19
+ path = "#{KEY}/#{brand_id}"
20
+ res = @session.send(path, "GET")
21
+ ErrorHandler.check_err(res)
22
+ end
23
+
24
+ def add(name:, settings:, id: nil, snippets: nil, idempotency_key: nil)
25
+ create(name: name, settings: settings, id: id, snippets: snippets, idempotency_key: idempotency_key)
26
+ end
27
+
28
+ def create(name:, settings:, id: nil, snippets: nil, idempotency_key: nil)
29
+ headers = {}
30
+ if idempotency_key
31
+ headers["idempotency_key"] = idempotency_key
32
+ end
33
+
34
+ payload = {
35
+ "name" => name,
36
+ "settings" => settings
37
+ }
38
+ if id
39
+ payload["id"] = id
40
+ end
41
+ if snippets
42
+ payload["snippets"] = snippets
43
+ end
44
+
45
+ res = @session.send(KEY, "POST", body: payload, headers: headers)
46
+ ErrorHandler.check_err(res)
47
+ end
48
+
49
+ def replace(brand_id:, name:, settings:, snippets: nil)
50
+ path = "#{KEY}/#{brand_id}"
51
+
52
+ payload = {
53
+ "name" => name,
54
+ "settings" => settings
55
+ }
56
+ if snippets
57
+ payload["snippets"] = snippets
58
+ end
59
+
60
+ res = @session.send(path, "PUT", body: payload)
61
+ ErrorHandler.check_err_non_json(res)
62
+ end
63
+
64
+ def delete(brand_id:)
65
+ path = "#{KEY}/#{brand_id}"
66
+ res = @session.send(path, "DELETE")
67
+ ErrorHandler.check_err_non_json(res)
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,35 @@
1
+ module Courier
2
+ class Events
3
+ KEY = "/events"
4
+
5
+ def initialize(session)
6
+ @session = session
7
+ end
8
+
9
+ def list
10
+ res = @session.send(KEY, "GET")
11
+ ErrorHandler.check_err(res)
12
+ end
13
+
14
+ def get(event_id:)
15
+ path = "#{KEY}/#{event_id}"
16
+ res = @session.send(path, "GET")
17
+ ErrorHandler.check_err(res)
18
+ end
19
+
20
+ def add(event_id:, id:, type: "notification")
21
+ replace(event_id: event_id, id: id, type: type)
22
+ end
23
+
24
+ def replace(event_id:, id:, type: "notification")
25
+ path = "#{KEY}/#{event_id}"
26
+
27
+ payload = {
28
+ "id" => id,
29
+ "type" => type
30
+ }
31
+ res = @session.send(path, "PUT", body: payload)
32
+ ErrorHandler.check_err_non_json(res)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,37 @@
1
+ require "trycourier/version"
2
+ require "net/http"
3
+ require "json"
4
+ require "openssl"
5
+
6
+ module Courier
7
+ #ResponseError in order to maintain v1.0.2 signature.
8
+ class InputError < StandardError; end
9
+ class ResponseError < StandardError; end
10
+ class CourierAPIError < ResponseError; end
11
+
12
+ class ErrorHandler
13
+ def self.check_err(res)
14
+ code = res.code.to_i
15
+ obj = JSON.parse res.read_body
16
+
17
+ if code < 400
18
+ obj
19
+ elsif (message = obj["Message"].nil? ? obj["message"] : obj["Message"])
20
+ err = "#{code}: #{message}"
21
+ raise CourierAPIError.new err
22
+ end
23
+ end
24
+
25
+ def self.check_err_non_json(res)
26
+ code = res.code.to_i
27
+ if code >= 400
28
+ obj = JSON.parse res.read_body
29
+ if (message = obj["Message"].nil? ? obj["message"] : obj["Message"])
30
+ err = "#{code}: #{message}"
31
+ raise CourierAPIError.new err
32
+ end
33
+ end
34
+ res
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,109 @@
1
+ module Courier
2
+ class Lists
3
+ KEY = "/lists"
4
+
5
+ def initialize(session)
6
+ @session = session
7
+ end
8
+
9
+ def send(event:, list: nil, pattern: nil, data: {}, brand: nil, override: nil, idempotency_key: nil)
10
+ path = "/send/list"
11
+ payload = {
12
+ "event": event,
13
+ "data": data
14
+ }
15
+ if list
16
+ payload["list"] = list
17
+ end
18
+ if pattern
19
+ payload["pattern"] = pattern
20
+ end
21
+ if brand
22
+ payload["brand"] = brand
23
+ end
24
+ if override
25
+ payload["override"] = override
26
+ end
27
+
28
+ headers = {}
29
+ if idempotency_key
30
+ headers["idempotency_key"] = idempotency_key
31
+ end
32
+
33
+ res = @session.send(path, "POST", body: payload, headers: headers)
34
+ ErrorHandler.check_err(res)
35
+ end
36
+
37
+ def list(cursor: nil, pattern: nil)
38
+ params = {}
39
+ if cursor
40
+ params["cursor"] = cursor
41
+ end
42
+ if pattern
43
+ params["pattern"] = pattern
44
+ end
45
+ res = @session.send(KEY, "GET", params: params)
46
+ ErrorHandler.check_err(res)
47
+ end
48
+
49
+ def get(list_id:)
50
+ path = "#{KEY}/#{list_id}"
51
+ res = @session.send(path, "GET")
52
+ ErrorHandler.check_err(res)
53
+ end
54
+
55
+ def put(list_id:, name:)
56
+ path = "#{KEY}/#{list_id}"
57
+
58
+ payload = {
59
+ "name": name.to_s
60
+ }
61
+
62
+ res = @session.send(path, "PUT", body: payload)
63
+ ErrorHandler.check_err_non_json(res)
64
+ end
65
+
66
+ def delete(list_id:)
67
+ path = "#{KEY}/#{list_id}"
68
+ res = @session.send(path, "DELETE")
69
+ ErrorHandler.check_err_non_json(res)
70
+ end
71
+
72
+ def restore(list_id:)
73
+ path = "#{KEY}/#{list_id}/restore"
74
+ res = @session.send(path, "PUT")
75
+ ErrorHandler.check_err_non_json(res)
76
+ end
77
+
78
+ def get_subscriptions(list_id:, cursor: nil)
79
+ path = "#{KEY}/#{list_id}/subscriptions"
80
+ params = {}
81
+ if cursor
82
+ params["cursor"] = cursor
83
+ end
84
+ res = @session.send(path, "GET", params: params)
85
+ ErrorHandler.check_err(res)
86
+ end
87
+
88
+ def put_subscriptions(list_id:, recipients:)
89
+ path = "#{KEY}/#{list_id}/subscriptions"
90
+ payload = {
91
+ "recipients": recipients
92
+ }
93
+ res = @session.send(path, "PUT", body: payload)
94
+ ErrorHandler.check_err_non_json(res)
95
+ end
96
+
97
+ def subscribe(list_id:, recipient_id:)
98
+ path = "#{KEY}/#{list_id}/subscriptions/#{recipient_id}"
99
+ res = @session.send(path, "PUT")
100
+ ErrorHandler.check_err_non_json(res)
101
+ end
102
+
103
+ def unsubscribe(list_id:, recipient_id:)
104
+ path = "#{KEY}/#{list_id}/subscriptions/#{recipient_id}"
105
+ res = @session.send(path, "DELETE")
106
+ ErrorHandler.check_err_non_json(res)
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,51 @@
1
+ module Courier
2
+ class Messages
3
+ KEY = "/messages"
4
+
5
+ def initialize(session)
6
+ @session = session
7
+ end
8
+
9
+ def list(cursor: nil, event: nil, list_id: nil, message_id: nil,
10
+ notification: nil, recipient: nil)
11
+ params = {}
12
+
13
+ if cursor
14
+ params["cursor"] = cursor
15
+ end
16
+ if event
17
+ params["event"] = event
18
+ end
19
+ if list_id
20
+ params["list"] = list_id
21
+ end
22
+ if message_id
23
+ params["messageId"] = message_id
24
+ end
25
+ if notification
26
+ params["notification"] = notification
27
+ end
28
+ if recipient
29
+ params["recipient"] = recipient
30
+ end
31
+ res = @session.send(KEY, "GET", params: params)
32
+ ErrorHandler.check_err(res)
33
+ end
34
+
35
+ def get(message_id:)
36
+ path = "#{KEY}/#{message_id}"
37
+ res = @session.send(path, "GET")
38
+ ErrorHandler.check_err(res)
39
+ end
40
+
41
+ def get_history(message_id:, type: nil)
42
+ path ="#{KEY}/#{message_id}/history"
43
+ params = {}
44
+ if type
45
+ params["type"] = type
46
+ end
47
+ res = @session.send(path, "GET", params: params)
48
+ ErrorHandler.check_err(res)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,64 @@
1
+ module Courier
2
+ class Profiles
3
+ KEY = "/profiles"
4
+
5
+ def initialize(session)
6
+ @session = session
7
+ end
8
+
9
+ def get(recipient_id:)
10
+ path = "#{KEY}/#{recipient_id}"
11
+ res = @session.send(path, "GET")
12
+ ErrorHandler.check_err(res)
13
+ end
14
+
15
+ def get_subscriptions(recipient_id:, cursor: nil)
16
+ path = "#{KEY}/#{recipient_id}/subscriptions"
17
+
18
+ params = {}
19
+ if cursor
20
+ params["cursor"] = cursor
21
+ end
22
+
23
+ res = @session.send(path, "GET", params: params)
24
+ ErrorHandler.check_err(res)
25
+ end
26
+
27
+ def add(recipient_id:, profile:)
28
+ replace(recipient_id: recipient_id, profile: profile)
29
+ end
30
+
31
+ def replace(recipient_id:, profile:)
32
+ path = "#{KEY}/#{recipient_id}"
33
+
34
+ payload = {
35
+ 'profile': profile
36
+ }
37
+
38
+ res = @session.send(path, "PUT", body: payload)
39
+ ErrorHandler.check_err_non_json(res)
40
+ end
41
+
42
+ def merge(recipient_id:, profile:, idempotency_key: nil)
43
+ path = "#{KEY}/#{recipient_id}"
44
+ payload = {
45
+ 'profile': profile
46
+ }
47
+ headers = {}
48
+ if idempotency_key
49
+ headers["Idempotency-Key"] = idempotency_key
50
+ end
51
+ res = @session.send(path, "POST", body: payload, headers: headers)
52
+ ErrorHandler.check_err(res)
53
+ end
54
+
55
+ def patch(recipient_id:, operations:)
56
+ path = "#{KEY}/#{recipient_id}"
57
+ payload = {
58
+ 'patch': operations
59
+ }
60
+ res = @session.send(path, "PATCH", body: payload)
61
+ ErrorHandler.check_err(res)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,81 @@
1
+ require "net/http"
2
+ require "json"
3
+ require "openssl"
4
+
5
+ module Courier
6
+ class CourierAPISession
7
+
8
+ def initialize(base_url)
9
+ @base_url = base_url
10
+ end
11
+
12
+ def init_token_auth(auth_token)
13
+ @auth_token = "Bearer #{auth_token}"
14
+ @auth_method = "token"
15
+ end
16
+
17
+ def init_basic_auth(username, password)
18
+ @username = username
19
+ @password = password
20
+ @auth_method = "basic"
21
+ end
22
+
23
+ def send(path, method, params: nil, body: nil, headers: nil)
24
+ uri = URI.parse(@base_url + path.to_s)
25
+ if params
26
+ uri.query = URI.encode_www_form(params)
27
+ end
28
+ http = Net::HTTP.new(uri.host, uri.port)
29
+ http.use_ssl = true
30
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
31
+
32
+ req = case method
33
+ when "GET"
34
+ Net::HTTP::Get.new(uri)
35
+ when "POST"
36
+ Net::HTTP::Post.new(uri)
37
+ when "PUT"
38
+ Net::HTTP::Put.new(uri)
39
+ when "PATCH"
40
+ Net::HTTP::Patch.new(uri)
41
+ when "DELETE"
42
+ Net::HTTP::Delete.new(uri)
43
+ else
44
+ Net::HTTP::Get.new(uri)
45
+ end
46
+
47
+ case @auth_method
48
+ when "token"
49
+ req["authorization"] = @auth_token
50
+ when "basic"
51
+ req.basic_auth @username, @password
52
+ end
53
+
54
+ req["content-type"] = "application/json"
55
+ req["User-Agent"] = "courier-ruby/#{Courier::VERSION}"
56
+
57
+ if body
58
+ req.body = body.to_json
59
+ end
60
+
61
+ if headers
62
+ headers.each do |k, v|
63
+ req.add_field(k.to_s, v.to_s)
64
+ end
65
+ end
66
+
67
+ http.request(req)
68
+ end
69
+
70
+ def is_authenticated
71
+ if !@auth_method.nil?
72
+ true
73
+ else
74
+ false
75
+ end
76
+ end
77
+
78
+ #getter for base url (for testing)
79
+ attr_reader :base_url
80
+ end
81
+ end
@@ -1,3 +1,3 @@
1
1
  module Courier
2
- VERSION = "1.0.2"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -1,15 +1,15 @@
1
- require_relative 'lib/trycourier/version'
1
+ require_relative "lib/trycourier/version"
2
2
 
3
3
  Gem::Specification.new do |spec|
4
- spec.name = "trycourier"
5
- spec.version = Courier::VERSION
6
- spec.authors = ["Courier"]
7
- spec.email = ["support@trycourier.com"]
4
+ spec.name = "trycourier"
5
+ spec.version = Courier::VERSION
6
+ spec.authors = ["Courier"]
7
+ spec.email = ["support@courier.com"]
8
8
 
9
- spec.summary = %q{Wraps calls to the Courier REST API}
10
- spec.description = %q{Courier is the smartest way to design & deliver notifications. Design your notifications once, deliver them to any channel through one API.}
11
- spec.homepage = "https://github.com/trycourier/courier-ruby"
12
- spec.license = "MIT"
9
+ spec.summary = "Wraps calls to the Courier REST API"
10
+ spec.description = "Courier is the smartest way to design & deliver notifications. Design your notifications once, deliver them to any channel through one API."
11
+ spec.homepage = "https://github.com/trycourier/courier-ruby"
12
+ spec.license = "MIT"
13
13
  spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
14
14
 
15
15
  spec.metadata["allowed_push_host"] = "https://rubygems.org"
@@ -20,10 +20,13 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  # Specify which files should be added to the gem when it is released.
22
22
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
23
+ spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do
24
24
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
25
  end
26
- spec.bindir = "exe"
27
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
+
30
+ spec.add_development_dependency "rspec", "~> 3.2"
31
+ spec.add_development_dependency "webmock", ">=1.24.2"
29
32
  end
metadata CHANGED
@@ -1,28 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trycourier
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Courier
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-06 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2021-01-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: webmock
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.24.2
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.24.2
13
41
  description: Courier is the smartest way to design & deliver notifications. Design
14
42
  your notifications once, deliver them to any channel through one API.
15
43
  email:
16
- - support@trycourier.com
44
+ - support@courier.com
17
45
  executables: []
18
46
  extensions: []
19
47
  extra_rdoc_files: []
20
48
  files:
21
49
  - ".github/ISSUE_TEMPLATE.md"
22
50
  - ".github/PULL_REQUEST_TEMPLATE.md"
51
+ - ".github/workflows/gem-push.yml"
23
52
  - ".gitignore"
24
53
  - ".rspec"
25
- - ".travis.yml"
54
+ - CHANGELOG.md
26
55
  - Gemfile
27
56
  - Gemfile.lock
28
57
  - LICENSE
@@ -31,6 +60,13 @@ files:
31
60
  - bin/console
32
61
  - bin/setup
33
62
  - lib/trycourier.rb
63
+ - lib/trycourier/brands.rb
64
+ - lib/trycourier/events.rb
65
+ - lib/trycourier/exceptions.rb
66
+ - lib/trycourier/lists.rb
67
+ - lib/trycourier/messages.rb
68
+ - lib/trycourier/profiles.rb
69
+ - lib/trycourier/session.rb
34
70
  - lib/trycourier/version.rb
35
71
  - trycourier.gemspec
36
72
  homepage: https://github.com/trycourier/courier-ruby
@@ -56,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
56
92
  - !ruby/object:Gem::Version
57
93
  version: '0'
58
94
  requirements: []
59
- rubygems_version: 3.0.3
95
+ rubygems_version: 3.1.4
60
96
  signing_key:
61
97
  specification_version: 4
62
98
  summary: Wraps calls to the Courier REST API
@@ -1,6 +0,0 @@
1
- ---
2
- language: ruby
3
- cache: bundler
4
- rvm:
5
- - 2.7.0
6
- before_install: gem install bundler -v 2.1.4