unsent 1.0.1 → 1.0.2
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 +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +258 -2
- data/lib/unsent/analytics.rb +30 -0
- data/lib/unsent/api_keys.rb +21 -0
- data/lib/unsent/campaigns.rb +4 -0
- data/lib/unsent/client.rb +8 -1
- data/lib/unsent/contact_books.rb +29 -0
- data/lib/unsent/contacts.rb +11 -0
- data/lib/unsent/emails.rb +47 -0
- data/lib/unsent/errors.rb +2 -0
- data/lib/unsent/models/add_suppression_request.rb +223 -0
- data/lib/unsent/models/create_api_key_request.rb +218 -0
- data/lib/unsent/models/create_campaign200_response.rb +750 -0
- data/lib/unsent/models/create_campaign_request.rb +426 -0
- data/lib/unsent/models/create_campaign_request_reply_to.rb +103 -0
- data/lib/unsent/models/create_contact200_response.rb +147 -0
- data/lib/unsent/models/create_contact_book200_response.rb +304 -0
- data/lib/unsent/models/create_contact_book_request.rb +193 -0
- data/lib/unsent/models/create_contact_request.rb +202 -0
- data/lib/unsent/models/create_domain_request.rb +190 -0
- data/lib/unsent/models/create_template200_response.rb +164 -0
- data/lib/unsent/models/create_template_request.rb +226 -0
- data/lib/unsent/models/delete_contact_book200_response.rb +164 -0
- data/lib/unsent/models/get_api_keys200_response_inner.rb +278 -0
- data/lib/unsent/models/get_campaigns200_response_inner.rb +296 -0
- data/lib/unsent/models/get_contact_book200_response.rb +330 -0
- data/lib/unsent/models/get_contact_book200_response_details.rb +218 -0
- data/lib/unsent/models/get_domains200_response_inner.rb +482 -0
- data/lib/unsent/models/get_domains200_response_inner_dns_records_inner.rb +318 -0
- data/lib/unsent/models/get_health200_response.rb +216 -0
- data/lib/unsent/models/get_templates200_response_inner.rb +314 -0
- data/lib/unsent/models/list_emails_domain_id_parameter.rb +103 -0
- data/lib/unsent/models/schedule_campaign_request.rb +185 -0
- data/lib/unsent/models/send_email_request.rb +378 -0
- data/lib/unsent/models/send_email_request_to.rb +103 -0
- data/lib/unsent/models/update_contact_book200_response.rb +190 -0
- data/lib/unsent/models/update_contact_book_request.rb +167 -0
- data/lib/unsent/models/update_contact_request.rb +176 -0
- data/lib/unsent/models/update_template_request.rb +174 -0
- data/lib/unsent/settings.rb +13 -0
- data/lib/unsent/suppressions.rb +28 -0
- data/lib/unsent/templates.rb +29 -0
- data/lib/unsent/version.rb +1 -1
- data/lib/unsent/webhooks.rb +25 -0
- data/lib/unsent.rb +7 -0
- metadata +38 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: aa505d7132d95fc8d1d1081eacdc6dc1c152d7265775437c7841a63f0cfbab0b
|
|
4
|
+
data.tar.gz: d173d3f42bb1b159f2a4d59070d7f1c6db41bb8af2771c29d1808f742541394a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 22ae152f36d21cc5f7dda582594d1b0cb0e667fba6765e9dbf3e14f23e9cf2f65f15f4ff937a09a36303d04d0d4208c5dfd5aa31121bd6c86b759dbc6a40dffd
|
|
7
|
+
data.tar.gz: 12f06ce781b6c75e5cc7985bd9eaa5dd1f48754715a0115cca022ed3467de14daf716284a373d17a2ea7d8beb7cb5d661b5c8b95ecf5ef0b6be18efd2daec831
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -35,7 +35,7 @@ gem install unsent
|
|
|
35
35
|
```ruby
|
|
36
36
|
require 'unsent'
|
|
37
37
|
|
|
38
|
-
client = Unsent::Client.new('
|
|
38
|
+
client = Unsent::Client.new('un_xxx')
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
### Environment Variables
|
|
@@ -267,7 +267,7 @@ end
|
|
|
267
267
|
To handle errors as return values instead:
|
|
268
268
|
|
|
269
269
|
```ruby
|
|
270
|
-
client = Unsent::Client.new('
|
|
270
|
+
client = Unsent::Client.new('un_xxx', raise_on_error: false)
|
|
271
271
|
|
|
272
272
|
data, error = client.emails.get('email_123')
|
|
273
273
|
if error
|
|
@@ -277,6 +277,262 @@ else
|
|
|
277
277
|
end
|
|
278
278
|
```
|
|
279
279
|
|
|
280
|
+
## Email Management
|
|
281
|
+
|
|
282
|
+
### List Emails
|
|
283
|
+
|
|
284
|
+
Retrieve a paginated list of emails with optional filters:
|
|
285
|
+
|
|
286
|
+
```ruby
|
|
287
|
+
data, error = client.emails.list(
|
|
288
|
+
page: 1,
|
|
289
|
+
limit: 10,
|
|
290
|
+
startDate: '2024-01-01',
|
|
291
|
+
endDate: '2024-01-31',
|
|
292
|
+
domainId: 'domain_123'
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
# Support for multiple domain IDs
|
|
296
|
+
data, error = client.emails.list(domainId: ['domain_1', 'domain_2'])
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Email Statistics
|
|
300
|
+
|
|
301
|
+
```ruby
|
|
302
|
+
# Get complaints
|
|
303
|
+
data, error = client.emails.get_complaints(page: 1, limit: 10)
|
|
304
|
+
|
|
305
|
+
# Get bounces
|
|
306
|
+
data, error = client.emails.get_bounces(page: 1, limit: 10)
|
|
307
|
+
|
|
308
|
+
# Get unsubscribes
|
|
309
|
+
data, error = client.emails.get_unsubscribes(page: 1, limit: 10)
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Contact Books
|
|
313
|
+
|
|
314
|
+
Organize your contacts into separate books.
|
|
315
|
+
|
|
316
|
+
### Create Contact Book
|
|
317
|
+
|
|
318
|
+
```ruby
|
|
319
|
+
data, error = client.contact_books.create(
|
|
320
|
+
name: 'Newsletter Subscribers',
|
|
321
|
+
emoji: '📧'
|
|
322
|
+
)
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### List Contact Books
|
|
326
|
+
|
|
327
|
+
```ruby
|
|
328
|
+
books, error = client.contact_books.list
|
|
329
|
+
books.each { |book| puts book['name'] }
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Get Contact Book
|
|
333
|
+
|
|
334
|
+
```ruby
|
|
335
|
+
book, error = client.contact_books.get('book_123')
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Update Contact Book
|
|
339
|
+
|
|
340
|
+
```ruby
|
|
341
|
+
data, error = client.contact_books.update('book_123', name: 'Updated Name')
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Delete Contact Book
|
|
345
|
+
|
|
346
|
+
```ruby
|
|
347
|
+
data, error = client.contact_books.delete('book_123')
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## Contacts
|
|
351
|
+
|
|
352
|
+
### List Contacts
|
|
353
|
+
|
|
354
|
+
```ruby
|
|
355
|
+
data, error = client.contacts.list('book_123',
|
|
356
|
+
page: 1,
|
|
357
|
+
limit: 10,
|
|
358
|
+
search: 'john@example.com'
|
|
359
|
+
)
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## Campaigns
|
|
363
|
+
|
|
364
|
+
### List Campaigns
|
|
365
|
+
|
|
366
|
+
```ruby
|
|
367
|
+
campaigns, error = client.campaigns.list
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
## Analytics
|
|
371
|
+
|
|
372
|
+
Get insights into your email sending performance.
|
|
373
|
+
|
|
374
|
+
### Overall Analytics
|
|
375
|
+
|
|
376
|
+
```ruby
|
|
377
|
+
data, error = client.analytics.get
|
|
378
|
+
puts "Sent: #{data['sent']}, Delivered: #{data['delivered']}"
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Time Series Data
|
|
382
|
+
|
|
383
|
+
```ruby
|
|
384
|
+
data, error = client.analytics.get_time_series(
|
|
385
|
+
days: 30,
|
|
386
|
+
domain: 'yourdomain.com'
|
|
387
|
+
)
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Reputation Score
|
|
391
|
+
|
|
392
|
+
```ruby
|
|
393
|
+
data, error = client.analytics.get_reputation(domain: 'yourdomain.com')
|
|
394
|
+
puts "Reputation Score: #{data['score']}"
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
## Templates
|
|
398
|
+
|
|
399
|
+
Manage reusable email templates.
|
|
400
|
+
|
|
401
|
+
### Create Template
|
|
402
|
+
|
|
403
|
+
```ruby
|
|
404
|
+
data, error = client.templates.create(
|
|
405
|
+
name: 'Welcome Email',
|
|
406
|
+
subject: 'Welcome to {{companyName}}!',
|
|
407
|
+
html: '<h1>Welcome {{firstName}}!</h1>'
|
|
408
|
+
)
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### List Templates
|
|
412
|
+
|
|
413
|
+
```ruby
|
|
414
|
+
templates, error = client.templates.list
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### Get Template
|
|
418
|
+
|
|
419
|
+
```ruby
|
|
420
|
+
template, error = client.templates.get('template_123')
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Update Template
|
|
424
|
+
|
|
425
|
+
```ruby
|
|
426
|
+
data, error = client.templates.update('template_123',
|
|
427
|
+
subject: 'Updated Subject'
|
|
428
|
+
)
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Delete Template
|
|
432
|
+
|
|
433
|
+
```ruby
|
|
434
|
+
data, error = client.templates.delete('template_123')
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
## Suppressions
|
|
438
|
+
|
|
439
|
+
Manage your email suppression list.
|
|
440
|
+
|
|
441
|
+
### List Suppressions
|
|
442
|
+
|
|
443
|
+
```ruby
|
|
444
|
+
data, error = client.suppressions.list(
|
|
445
|
+
page: 1,
|
|
446
|
+
limit: 10,
|
|
447
|
+
reason: 'MANUAL',
|
|
448
|
+
search: 'user@'
|
|
449
|
+
)
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### Add to Suppression List
|
|
453
|
+
|
|
454
|
+
```ruby
|
|
455
|
+
data, error = client.suppressions.add(
|
|
456
|
+
email: 'blocked@example.com',
|
|
457
|
+
reason: 'MANUAL'
|
|
458
|
+
)
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
### Remove from Suppression List
|
|
462
|
+
|
|
463
|
+
```ruby
|
|
464
|
+
data, error = client.suppressions.delete('blocked@example.com')
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
## API Keys
|
|
468
|
+
|
|
469
|
+
Manage your API keys programmatically.
|
|
470
|
+
|
|
471
|
+
### List API Keys
|
|
472
|
+
|
|
473
|
+
```ruby
|
|
474
|
+
keys, error = client.api_keys.list
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### Create API Key
|
|
478
|
+
|
|
479
|
+
```ruby
|
|
480
|
+
data, error = client.api_keys.create(
|
|
481
|
+
name: 'Production Key',
|
|
482
|
+
permission: 'SENDING'
|
|
483
|
+
)
|
|
484
|
+
puts "New key: #{data['key']}"
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
### Delete API Key
|
|
488
|
+
|
|
489
|
+
```ruby
|
|
490
|
+
data, error = client.api_keys.delete('key_123')
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
## Webhooks
|
|
494
|
+
|
|
495
|
+
> **Note**: Webhooks are currently a future feature and are documented here for reference.
|
|
496
|
+
|
|
497
|
+
Configure webhooks to receive real-time notifications.
|
|
498
|
+
|
|
499
|
+
### List Webhooks
|
|
500
|
+
|
|
501
|
+
```ruby
|
|
502
|
+
webhooks, error = client.webhooks.list
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
### Create Webhook
|
|
506
|
+
|
|
507
|
+
```ruby
|
|
508
|
+
data, error = client.webhooks.create(
|
|
509
|
+
url: 'https://yourdomain.com/webhooks',
|
|
510
|
+
events: ['email.sent', 'email.delivered', 'email.bounced']
|
|
511
|
+
)
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### Update Webhook
|
|
515
|
+
|
|
516
|
+
```ruby
|
|
517
|
+
data, error = client.webhooks.update('webhook_123',
|
|
518
|
+
url: 'https://yourdomain.com/updated-webhook'
|
|
519
|
+
)
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
### Delete Webhook
|
|
523
|
+
|
|
524
|
+
```ruby
|
|
525
|
+
data, error = client.webhooks.delete('webhook_123')
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
## Settings
|
|
529
|
+
|
|
530
|
+
Retrieve account settings.
|
|
531
|
+
|
|
532
|
+
```ruby
|
|
533
|
+
settings, error = client.settings.get
|
|
534
|
+
```
|
|
535
|
+
|
|
280
536
|
## Development
|
|
281
537
|
|
|
282
538
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Unsent
|
|
4
|
+
class Analytics
|
|
5
|
+
def initialize(client)
|
|
6
|
+
@client = client
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def get
|
|
10
|
+
@client.get('/analytics')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def get_time_series(query = {})
|
|
14
|
+
params = []
|
|
15
|
+
params << "days=#{query[:days]}" if query[:days]
|
|
16
|
+
params << "domain=#{query[:domain]}" if query[:domain]
|
|
17
|
+
|
|
18
|
+
query_string = params.empty? ? '' : "?#{params.join('&')}"
|
|
19
|
+
@client.get("/analytics/time-series#{query_string}")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def get_reputation(query = {})
|
|
23
|
+
params = []
|
|
24
|
+
params << "domain=#{query[:domain]}" if query[:domain]
|
|
25
|
+
|
|
26
|
+
query_string = params.empty? ? '' : "?#{params.join('&')}"
|
|
27
|
+
@client.get("/analytics/reputation#{query_string}")
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Unsent
|
|
4
|
+
class ApiKeys
|
|
5
|
+
def initialize(client)
|
|
6
|
+
@client = client
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def list
|
|
10
|
+
@client.get('/api-keys')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def create(payload)
|
|
14
|
+
@client.post('/api-keys', payload)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def delete(id)
|
|
18
|
+
@client.delete("/api-keys/#{id}")
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/lib/unsent/campaigns.rb
CHANGED
data/lib/unsent/client.rb
CHANGED
|
@@ -9,7 +9,7 @@ module Unsent
|
|
|
9
9
|
DEFAULT_BASE_URL = "https://api.unsent.dev"
|
|
10
10
|
|
|
11
11
|
attr_reader :key, :url, :raise_on_error
|
|
12
|
-
attr_accessor :emails, :contacts, :campaigns, :domains
|
|
12
|
+
attr_accessor :emails, :contacts, :campaigns, :domains, :analytics, :api_keys, :contact_books, :settings, :suppressions, :templates, :webhooks
|
|
13
13
|
|
|
14
14
|
def initialize(key = nil, url: nil, raise_on_error: true)
|
|
15
15
|
@key = key || ENV["UNSENT_API_KEY"] || ENV["UNSENT_API_KEY"]
|
|
@@ -24,6 +24,13 @@ module Unsent
|
|
|
24
24
|
@contacts = Contacts.new(self)
|
|
25
25
|
@campaigns = Campaigns.new(self)
|
|
26
26
|
@domains = Domains.new(self)
|
|
27
|
+
@analytics = Analytics.new(self)
|
|
28
|
+
@api_keys = ApiKeys.new(self)
|
|
29
|
+
@contact_books = ContactBooks.new(self)
|
|
30
|
+
@settings = Settings.new(self)
|
|
31
|
+
@suppressions = Suppressions.new(self)
|
|
32
|
+
@templates = Templates.new(self)
|
|
33
|
+
@webhooks = Webhooks.new(self)
|
|
27
34
|
end
|
|
28
35
|
|
|
29
36
|
def request(method, path, body = nil, headers = {})
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Unsent
|
|
4
|
+
class ContactBooks
|
|
5
|
+
def initialize(client)
|
|
6
|
+
@client = client
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def list
|
|
10
|
+
@client.get('/contactBooks')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def create(payload)
|
|
14
|
+
@client.post('/contactBooks', payload)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def get(id)
|
|
18
|
+
@client.get("/contactBooks/#{id}")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def update(id, payload)
|
|
22
|
+
@client.patch("/contactBooks/#{id}", payload)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def delete(id)
|
|
26
|
+
@client.delete("/contactBooks/#{id}")
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
data/lib/unsent/contacts.rb
CHANGED
|
@@ -6,6 +6,17 @@ module Unsent
|
|
|
6
6
|
@client = client
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
+
def list(book_id, query = {})
|
|
10
|
+
params = []
|
|
11
|
+
params << "emails=#{query[:emails]}" if query[:emails]
|
|
12
|
+
params << "page=#{query[:page]}" if query[:page]
|
|
13
|
+
params << "limit=#{query[:limit]}" if query[:limit]
|
|
14
|
+
params << "ids=#{query[:ids]}" if query[:ids]
|
|
15
|
+
|
|
16
|
+
query_string = params.empty? ? '' : "?#{params.join('&')}"
|
|
17
|
+
@client.get("/contactBooks/#{book_id}/contacts#{query_string}")
|
|
18
|
+
end
|
|
19
|
+
|
|
9
20
|
def create(book_id, payload)
|
|
10
21
|
@client.post("/contactBooks/#{book_id}/contacts", payload)
|
|
11
22
|
end
|
data/lib/unsent/emails.rb
CHANGED
|
@@ -53,5 +53,52 @@ module Unsent
|
|
|
53
53
|
def cancel(email_id)
|
|
54
54
|
@client.post("/emails/#{email_id}/cancel", {})
|
|
55
55
|
end
|
|
56
|
+
|
|
57
|
+
def list(query = {})
|
|
58
|
+
params = []
|
|
59
|
+
params << "page=#{query[:page]}" if query[:page]
|
|
60
|
+
params << "limit=#{query[:limit]}" if query[:limit]
|
|
61
|
+
params << "startDate=#{query[:startDate]}" if query[:startDate]
|
|
62
|
+
params << "endDate=#{query[:endDate]}" if query[:endDate]
|
|
63
|
+
|
|
64
|
+
# Handle domainId as both string and array
|
|
65
|
+
if query[:domainId]
|
|
66
|
+
if query[:domainId].is_a?(Array)
|
|
67
|
+
query[:domainId].each { |id| params << "domainId=#{id}" }
|
|
68
|
+
else
|
|
69
|
+
params << "domainId=#{query[:domainId]}"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
query_string = params.empty? ? '' : "?#{params.join('&')}"
|
|
74
|
+
@client.get("/emails#{query_string}")
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def get_complaints(query = {})
|
|
78
|
+
params = []
|
|
79
|
+
params << "page=#{query[:page]}" if query[:page]
|
|
80
|
+
params << "limit=#{query[:limit]}" if query[:limit]
|
|
81
|
+
|
|
82
|
+
query_string = params.empty? ? '' : "?#{params.join('&')}"
|
|
83
|
+
@client.get("/emails/complaints#{query_string}")
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def get_bounces(query = {})
|
|
87
|
+
params = []
|
|
88
|
+
params << "page=#{query[:page]}" if query[:page]
|
|
89
|
+
params << "limit=#{query[:limit]}" if query[:limit]
|
|
90
|
+
|
|
91
|
+
query_string = params.empty? ? '' : "?#{params.join('&')}"
|
|
92
|
+
@client.get("/emails/bounces#{query_string}")
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def get_unsubscribes(query = {})
|
|
96
|
+
params = []
|
|
97
|
+
params << "page=#{query[:page]}" if query[:page]
|
|
98
|
+
params << "limit=#{query[:limit]}" if query[:limit]
|
|
99
|
+
|
|
100
|
+
query_string = params.empty? ? '' : "?#{params.join('&')}"
|
|
101
|
+
@client.get("/emails/unsubscribes#{query_string}")
|
|
102
|
+
end
|
|
56
103
|
end
|
|
57
104
|
end
|