trycourier 1.0.2 → 1.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.
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