sendara 0.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 +7 -0
- data/README.md +313 -0
- data/lib/sendara/client.rb +240 -0
- data/lib/sendara/errors.rb +23 -0
- data/lib/sendara/generators/install_generator.rb +17 -0
- data/lib/sendara/generators/templates/sendara.rb +8 -0
- data/lib/sendara/message_page.rb +34 -0
- data/lib/sendara/railtie.rb +72 -0
- data/lib/sendara/resource.rb +26 -0
- data/lib/sendara/resources/api_keys.rb +28 -0
- data/lib/sendara/resources/billing.rb +22 -0
- data/lib/sendara/resources/broadcasts.rb +72 -0
- data/lib/sendara/resources/contacts.rb +121 -0
- data/lib/sendara/resources/domains.rb +44 -0
- data/lib/sendara/resources/emails.rb +49 -0
- data/lib/sendara/resources/lists.rb +56 -0
- data/lib/sendara/resources/messages.rb +42 -0
- data/lib/sendara/resources/suppressions.rb +29 -0
- data/lib/sendara/resources/templates.rb +54 -0
- data/lib/sendara/resources/usage.rb +12 -0
- data/lib/sendara/version.rb +5 -0
- data/lib/sendara/webhooks.rb +74 -0
- data/lib/sendara.rb +27 -0
- data/sendara.gemspec +30 -0
- metadata +86 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/railtie"
|
|
4
|
+
|
|
5
|
+
module Sendara
|
|
6
|
+
class Configuration
|
|
7
|
+
attr_accessor :api_key, :base_url, :timeout, :max_retries
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
@api_key = ENV["SENDARA_API_KEY"]
|
|
11
|
+
@base_url = ENV["SENDARA_BASE_URL"]
|
|
12
|
+
@timeout = nil
|
|
13
|
+
@max_retries = nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def client_options
|
|
17
|
+
options = {}
|
|
18
|
+
options[:base_url] = base_url unless base_url.nil? || base_url.to_s.empty?
|
|
19
|
+
options[:timeout] = timeout unless timeout.nil?
|
|
20
|
+
options[:max_retries] = max_retries unless max_retries.nil?
|
|
21
|
+
options
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class << self
|
|
26
|
+
def configuration
|
|
27
|
+
@configuration ||= Configuration.new
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def configure
|
|
31
|
+
yield(configuration) if block_given?
|
|
32
|
+
reset_client!
|
|
33
|
+
configuration
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def client
|
|
37
|
+
@client ||= build_client
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def reset_client!
|
|
41
|
+
@client = nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def build_client
|
|
47
|
+
key = configuration.api_key
|
|
48
|
+
raise Error, "Sendara API key is missing. Set ENV[\"SENDARA_API_KEY\"] or config.sendara.api_key." if key.nil? || key.to_s.empty?
|
|
49
|
+
|
|
50
|
+
Client.new(key, **configuration.client_options)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
class Railtie < ::Rails::Railtie
|
|
55
|
+
config.sendara = ActiveSupport::OrderedOptions.new
|
|
56
|
+
|
|
57
|
+
initializer "sendara.configure" do |app|
|
|
58
|
+
options = app.config.sendara
|
|
59
|
+
|
|
60
|
+
Sendara.configure do |sendara_config|
|
|
61
|
+
sendara_config.api_key = options.api_key unless options.api_key.nil?
|
|
62
|
+
sendara_config.base_url = options.base_url unless options.base_url.nil?
|
|
63
|
+
sendara_config.timeout = options.timeout unless options.timeout.nil?
|
|
64
|
+
sendara_config.max_retries = options.max_retries unless options.max_retries.nil?
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
generators do
|
|
69
|
+
require_relative "generators/install_generator"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sendara
|
|
4
|
+
class Resource
|
|
5
|
+
def initialize(client)
|
|
6
|
+
@client = client
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
protected
|
|
10
|
+
|
|
11
|
+
attr_reader :client
|
|
12
|
+
|
|
13
|
+
def request(method, path, body: nil, query: {})
|
|
14
|
+
client.request(method, path, body: body, query: query)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def compact_params(hash)
|
|
18
|
+
hash.reject { |_key, value| value.nil? }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def encode(segment)
|
|
22
|
+
require "erb"
|
|
23
|
+
ERB::Util.url_encode(segment.to_s)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sendara
|
|
4
|
+
module Resources
|
|
5
|
+
class ApiKeys < Resource
|
|
6
|
+
def list
|
|
7
|
+
response = request(:get, "/v1/keys") || {}
|
|
8
|
+
keys = response["keys"]
|
|
9
|
+
keys.is_a?(Array) ? keys : []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def create(scope: nil, test_mode: nil)
|
|
13
|
+
body = compact_params("scope" => scope, "test_mode" => test_mode)
|
|
14
|
+
request(:post, "/v1/keys", body: body) || {}
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def rotate(id)
|
|
18
|
+
response = request(:post, "/v1/keys/#{encode(id)}/rotate") || {}
|
|
19
|
+
response["key"].to_s
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def revoke(id)
|
|
23
|
+
request(:delete, "/v1/keys/#{encode(id)}")
|
|
24
|
+
nil
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sendara
|
|
4
|
+
module Resources
|
|
5
|
+
class Billing < Resource
|
|
6
|
+
def get
|
|
7
|
+
request(:get, "/v1/billing") || {}
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def checkout(plan: nil, period: nil)
|
|
11
|
+
body = compact_params("plan" => plan, "period" => period)
|
|
12
|
+
response = request(:post, "/v1/billing/checkout", body: body) || {}
|
|
13
|
+
response["url"].to_s
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def portal
|
|
17
|
+
response = request(:post, "/v1/billing/portal") || {}
|
|
18
|
+
response["url"].to_s
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sendara
|
|
4
|
+
module Resources
|
|
5
|
+
class Broadcasts < Resource
|
|
6
|
+
def list(limit: nil, offset: nil)
|
|
7
|
+
query = compact_params("limit" => limit, "offset" => offset)
|
|
8
|
+
response = request(:get, "/v1/broadcasts", query: query) || {}
|
|
9
|
+
broadcasts = response["broadcasts"]
|
|
10
|
+
broadcasts.is_a?(Array) ? broadcasts : []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def get(id)
|
|
14
|
+
request(:get, "/v1/broadcasts/#{encode(id)}") || {}
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def create(from_email:, name: nil, subject: nil, body_html: nil, body_text: nil,
|
|
18
|
+
template_id: nil, message_type: nil, audience_list_id: nil,
|
|
19
|
+
recipients: nil, scheduled_at: nil, send_now: nil)
|
|
20
|
+
request(:post, "/v1/broadcasts", body: broadcast_body(
|
|
21
|
+
from_email: from_email, name: name, subject: subject, body_html: body_html,
|
|
22
|
+
body_text: body_text, template_id: template_id, message_type: message_type,
|
|
23
|
+
audience_list_id: audience_list_id, recipients: recipients,
|
|
24
|
+
scheduled_at: scheduled_at, send_now: send_now
|
|
25
|
+
)) || {}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def send(id)
|
|
29
|
+
request(:post, "/v1/broadcasts/#{encode(id)}/send") || {}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def cancel(id)
|
|
33
|
+
request(:post, "/v1/broadcasts/#{encode(id)}/cancel") || {}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def delete(id)
|
|
37
|
+
request(:delete, "/v1/broadcasts/#{encode(id)}")
|
|
38
|
+
nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def bulk_send(from_email:, name: nil, subject: nil, body_html: nil, body_text: nil,
|
|
42
|
+
template_id: nil, message_type: nil, audience_list_id: nil,
|
|
43
|
+
recipients: nil, scheduled_at: nil, send_now: nil)
|
|
44
|
+
request(:post, "/v1/send/bulk", body: broadcast_body(
|
|
45
|
+
from_email: from_email, name: name, subject: subject, body_html: body_html,
|
|
46
|
+
body_text: body_text, template_id: template_id, message_type: message_type,
|
|
47
|
+
audience_list_id: audience_list_id, recipients: recipients,
|
|
48
|
+
scheduled_at: scheduled_at, send_now: send_now
|
|
49
|
+
)) || {}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def broadcast_body(from_email:, name:, subject:, body_html:, body_text:, template_id:,
|
|
55
|
+
message_type:, audience_list_id:, recipients:, scheduled_at:, send_now:)
|
|
56
|
+
compact_params(
|
|
57
|
+
"name" => name,
|
|
58
|
+
"from_email" => from_email,
|
|
59
|
+
"subject" => subject,
|
|
60
|
+
"body_html" => body_html,
|
|
61
|
+
"body_text" => body_text,
|
|
62
|
+
"template_id" => template_id,
|
|
63
|
+
"message_type" => message_type,
|
|
64
|
+
"audience_list_id" => audience_list_id,
|
|
65
|
+
"recipients" => recipients,
|
|
66
|
+
"scheduled_at" => scheduled_at,
|
|
67
|
+
"send_now" => send_now
|
|
68
|
+
)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sendara
|
|
4
|
+
module Resources
|
|
5
|
+
class Contacts < Resource
|
|
6
|
+
def lists
|
|
7
|
+
@lists ||= Lists.new(client)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def list(limit: nil, offset: nil)
|
|
11
|
+
query = compact_params("limit" => limit, "offset" => offset)
|
|
12
|
+
response = request(:get, "/v1/contacts", query: query) || {}
|
|
13
|
+
contacts = response["contacts"]
|
|
14
|
+
contacts.is_a?(Array) ? contacts : []
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def get(id)
|
|
18
|
+
request(:get, "/v1/contacts/#{encode(id)}") || {}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def create(email: nil, phone_number: nil, device_token: nil, first_name: nil,
|
|
22
|
+
last_name: nil, attributes: nil, tags: nil, email_consent: nil,
|
|
23
|
+
sms_consent: nil, push_consent: nil, voice_consent: nil)
|
|
24
|
+
body = contact_body(
|
|
25
|
+
email: email, phone_number: phone_number, device_token: device_token,
|
|
26
|
+
first_name: first_name, last_name: last_name, attributes: attributes,
|
|
27
|
+
tags: tags, email_consent: email_consent, sms_consent: sms_consent,
|
|
28
|
+
push_consent: push_consent, voice_consent: voice_consent
|
|
29
|
+
)
|
|
30
|
+
request(:post, "/v1/contacts", body: body) || {}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def update(id, email: nil, phone_number: nil, device_token: nil, first_name: nil,
|
|
34
|
+
last_name: nil, attributes: nil, tags: nil, email_consent: nil,
|
|
35
|
+
sms_consent: nil, push_consent: nil, voice_consent: nil)
|
|
36
|
+
body = contact_body(
|
|
37
|
+
email: email, phone_number: phone_number, device_token: device_token,
|
|
38
|
+
first_name: first_name, last_name: last_name, attributes: attributes,
|
|
39
|
+
tags: tags, email_consent: email_consent, sms_consent: sms_consent,
|
|
40
|
+
push_consent: push_consent, voice_consent: voice_consent
|
|
41
|
+
)
|
|
42
|
+
request(:put, "/v1/contacts/#{encode(id)}", body: body) || {}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def delete(id)
|
|
46
|
+
request(:delete, "/v1/contacts/#{encode(id)}")
|
|
47
|
+
nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def lists_for(id)
|
|
51
|
+
response = request(:get, "/v1/contacts/#{encode(id)}/lists") || {}
|
|
52
|
+
lists = response["lists"]
|
|
53
|
+
lists.is_a?(Array) ? lists : []
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def activity(id, limit: nil)
|
|
57
|
+
query = compact_params("limit" => limit)
|
|
58
|
+
response = request(:get, "/v1/contacts/#{encode(id)}/activity", query: query) || {}
|
|
59
|
+
events = response["events"]
|
|
60
|
+
events.is_a?(Array) ? events : []
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def import(s3_key:, format:)
|
|
64
|
+
body = { "s3_key" => s3_key, "format" => format }
|
|
65
|
+
request(:post, "/v1/contacts/import", body: body) || {}
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def import_inline(rows:, list_id: nil, dry_run: nil)
|
|
69
|
+
body = compact_params(
|
|
70
|
+
"rows" => rows,
|
|
71
|
+
"list_id" => list_id,
|
|
72
|
+
"dry_run" => dry_run
|
|
73
|
+
)
|
|
74
|
+
request(:post, "/v1/contacts/import/inline", body: body) || {}
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def bulk(ids:, action:, tag: nil, list_id: nil, channel: nil, consent: nil)
|
|
78
|
+
body = compact_params(
|
|
79
|
+
"ids" => ids,
|
|
80
|
+
"action" => action,
|
|
81
|
+
"tag" => tag,
|
|
82
|
+
"list_id" => list_id,
|
|
83
|
+
"channel" => channel,
|
|
84
|
+
"consent" => consent
|
|
85
|
+
)
|
|
86
|
+
response = request(:post, "/v1/contacts/bulk", body: body) || {}
|
|
87
|
+
(response["affected"] || 0).to_i
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def segments_preview(segment_rules)
|
|
91
|
+
response = request(:post, "/v1/contacts/segments/preview",
|
|
92
|
+
body: { "segment_rules" => segment_rules }) || {}
|
|
93
|
+
(response["count"] || 0).to_i
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def usage
|
|
97
|
+
request(:get, "/v1/contacts/usage") || {}
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
private
|
|
101
|
+
|
|
102
|
+
def contact_body(email:, phone_number:, device_token:, first_name:, last_name:,
|
|
103
|
+
attributes:, tags:, email_consent:, sms_consent:, push_consent:,
|
|
104
|
+
voice_consent:)
|
|
105
|
+
compact_params(
|
|
106
|
+
"email" => email,
|
|
107
|
+
"phone_number" => phone_number,
|
|
108
|
+
"device_token" => device_token,
|
|
109
|
+
"first_name" => first_name,
|
|
110
|
+
"last_name" => last_name,
|
|
111
|
+
"attributes" => attributes,
|
|
112
|
+
"tags" => tags,
|
|
113
|
+
"email_consent" => email_consent,
|
|
114
|
+
"sms_consent" => sms_consent,
|
|
115
|
+
"push_consent" => push_consent,
|
|
116
|
+
"voice_consent" => voice_consent
|
|
117
|
+
)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "base64"
|
|
4
|
+
|
|
5
|
+
module Sendara
|
|
6
|
+
module Resources
|
|
7
|
+
class Domains < Resource
|
|
8
|
+
def list
|
|
9
|
+
response = request(:get, "/v1/domains") || {}
|
|
10
|
+
domains = response["domains"]
|
|
11
|
+
domains.is_a?(Array) ? domains : []
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create(domain)
|
|
15
|
+
request(:post, "/v1/domains", body: { "domain" => domain }) || {}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def get(domain)
|
|
19
|
+
request(:get, "/v1/domains/#{encode(domain)}") || {}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def verify(domain)
|
|
23
|
+
request(:post, "/v1/domains/#{encode(domain)}/verify") || {}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def get_bimi(domain)
|
|
27
|
+
request(:get, "/v1/domains/#{encode(domain)}/bimi") || {}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def set_bimi(domain, logo_url)
|
|
31
|
+
request(:put, "/v1/domains/#{encode(domain)}/bimi", body: { "logo_url" => logo_url }) || {}
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def upload_bimi_logo(domain, svg, filename: "logo.svg")
|
|
35
|
+
body = {
|
|
36
|
+
"filename" => filename,
|
|
37
|
+
"content_type" => "image/svg+xml",
|
|
38
|
+
"data" => Base64.strict_encode64(svg)
|
|
39
|
+
}
|
|
40
|
+
request(:post, "/v1/domains/#{encode(domain)}/bimi/logo", body: body) || {}
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sendara
|
|
4
|
+
module Resources
|
|
5
|
+
class Emails < Resource
|
|
6
|
+
def send(to:, from: nil, subject: nil, html: nil, text: nil, message_type: nil,
|
|
7
|
+
template_id: nil, template_vars: nil, metadata: nil, store_payload: nil,
|
|
8
|
+
test_send: nil, idempotency_key: nil)
|
|
9
|
+
meta = metadata.nil? ? {} : metadata.dup
|
|
10
|
+
meta["from_email"] = from unless from.nil?
|
|
11
|
+
|
|
12
|
+
body = {
|
|
13
|
+
"channel" => "email",
|
|
14
|
+
"idempotency_key" => idempotency_key || Client.generate_idempotency_key,
|
|
15
|
+
"destination" => { "email" => to },
|
|
16
|
+
"payload" => {
|
|
17
|
+
"subject" => subject,
|
|
18
|
+
"body_html" => html,
|
|
19
|
+
"body_text" => text
|
|
20
|
+
},
|
|
21
|
+
"metadata" => meta
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
body["message_type"] = message_type unless message_type.nil?
|
|
25
|
+
body["template_id"] = template_id unless template_id.nil?
|
|
26
|
+
body["template_vars"] = template_vars unless template_vars.nil?
|
|
27
|
+
body["store_payload"] = store_payload unless store_payload.nil?
|
|
28
|
+
body["test_send"] = test_send unless test_send.nil?
|
|
29
|
+
|
|
30
|
+
send_raw(body)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def send_raw(request)
|
|
34
|
+
request = request.dup
|
|
35
|
+
request["idempotency_key"] ||= Client.generate_idempotency_key
|
|
36
|
+
request(:post, "/v1/send", body: request) || {}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def send_batch(requests)
|
|
40
|
+
body = requests.map do |req|
|
|
41
|
+
req = req.dup
|
|
42
|
+
req["idempotency_key"] ||= Client.generate_idempotency_key
|
|
43
|
+
req
|
|
44
|
+
end
|
|
45
|
+
request(:post, "/v1/send/batch", body: body) || []
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sendara
|
|
4
|
+
module Resources
|
|
5
|
+
class Lists < Resource
|
|
6
|
+
def list(limit: nil, offset: nil)
|
|
7
|
+
query = compact_params("limit" => limit, "offset" => offset)
|
|
8
|
+
response = request(:get, "/v1/contacts/lists", query: query) || {}
|
|
9
|
+
lists = response["lists"]
|
|
10
|
+
lists.is_a?(Array) ? lists : []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def get(id)
|
|
14
|
+
request(:get, "/v1/contacts/lists/#{encode(id)}") || {}
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def create(name:, list_type: nil, segment_rules: nil)
|
|
18
|
+
body = compact_params(
|
|
19
|
+
"name" => name,
|
|
20
|
+
"list_type" => list_type,
|
|
21
|
+
"segment_rules" => segment_rules
|
|
22
|
+
)
|
|
23
|
+
request(:post, "/v1/contacts/lists", body: body) || {}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def update(id, name: nil, segment_rules: nil)
|
|
27
|
+
body = compact_params(
|
|
28
|
+
"name" => name,
|
|
29
|
+
"segment_rules" => segment_rules
|
|
30
|
+
)
|
|
31
|
+
request(:put, "/v1/contacts/lists/#{encode(id)}", body: body) || {}
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def delete(id)
|
|
35
|
+
request(:delete, "/v1/contacts/lists/#{encode(id)}")
|
|
36
|
+
nil
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def add_member(id, contact_id)
|
|
40
|
+
request(:post, "/v1/contacts/lists/#{encode(id)}/members",
|
|
41
|
+
body: { "contact_id" => contact_id }) || {}
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def remove_member(id, contact_id)
|
|
45
|
+
request(:delete, "/v1/contacts/lists/#{encode(id)}/members/#{encode(contact_id)}")
|
|
46
|
+
nil
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def members(id)
|
|
50
|
+
response = request(:get, "/v1/contacts/lists/#{encode(id)}/members") || {}
|
|
51
|
+
members = response["members"]
|
|
52
|
+
members.is_a?(Array) ? members : []
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sendara
|
|
4
|
+
module Resources
|
|
5
|
+
class Messages < Resource
|
|
6
|
+
include Enumerable
|
|
7
|
+
|
|
8
|
+
def page(channel: nil, status: nil, from: nil, to: nil, limit: nil, cursor: nil)
|
|
9
|
+
query = compact_params(
|
|
10
|
+
"channel" => channel,
|
|
11
|
+
"status" => status,
|
|
12
|
+
"from" => from,
|
|
13
|
+
"to" => to,
|
|
14
|
+
"limit" => limit,
|
|
15
|
+
"cursor" => cursor
|
|
16
|
+
)
|
|
17
|
+
response = request(:get, "/v1/messages", query: query) || {}
|
|
18
|
+
MessagePage.from_response(response)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def each(channel: nil, status: nil, from: nil, to: nil, limit: nil, cursor: nil, &block)
|
|
22
|
+
unless block_given?
|
|
23
|
+
return enum_for(:each, channel: channel, status: status, from: from,
|
|
24
|
+
to: to, limit: limit, cursor: cursor)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
loop do
|
|
28
|
+
current = page(channel: channel, status: status, from: from,
|
|
29
|
+
to: to, limit: limit, cursor: cursor)
|
|
30
|
+
current.messages.each(&block)
|
|
31
|
+
break if current.next_cursor.nil?
|
|
32
|
+
|
|
33
|
+
cursor = current.next_cursor
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def get(id)
|
|
38
|
+
request(:get, "/v1/messages/#{encode(id)}") || {}
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sendara
|
|
4
|
+
module Resources
|
|
5
|
+
class Suppressions < Resource
|
|
6
|
+
def list(channel: nil)
|
|
7
|
+
query = compact_params("channel" => channel)
|
|
8
|
+
response = request(:get, "/v1/suppressions", query: query) || {}
|
|
9
|
+
suppressions = response["suppressions"]
|
|
10
|
+
suppressions.is_a?(Array) ? suppressions : []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def create(channel:, recipient:, reason: nil)
|
|
14
|
+
body = compact_params(
|
|
15
|
+
"channel" => channel,
|
|
16
|
+
"recipient" => recipient,
|
|
17
|
+
"reason" => reason
|
|
18
|
+
)
|
|
19
|
+
request(:post, "/v1/suppressions", body: body) || {}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def delete(channel, recipient)
|
|
23
|
+
request(:delete, "/v1/suppressions",
|
|
24
|
+
query: { "channel" => channel, "recipient" => recipient })
|
|
25
|
+
nil
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sendara
|
|
4
|
+
module Resources
|
|
5
|
+
class Templates < Resource
|
|
6
|
+
def list
|
|
7
|
+
response = request(:get, "/v1/templates") || {}
|
|
8
|
+
templates = response["templates"]
|
|
9
|
+
templates.is_a?(Array) ? templates : []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def get(id)
|
|
13
|
+
request(:get, "/v1/templates/#{encode(id)}") || {}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def create(name:, channel: "email", subject: nil, body_text: nil, body_html: nil,
|
|
17
|
+
body_json: nil, variables: nil)
|
|
18
|
+
body = compact_params(
|
|
19
|
+
"name" => name,
|
|
20
|
+
"channel" => channel,
|
|
21
|
+
"subject" => subject,
|
|
22
|
+
"body_text" => body_text,
|
|
23
|
+
"body_html" => body_html,
|
|
24
|
+
"body_json" => body_json,
|
|
25
|
+
"variables" => variables
|
|
26
|
+
)
|
|
27
|
+
request(:post, "/v1/templates", body: body) || {}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def update(id, name: nil, subject: nil, body_text: nil, body_html: nil,
|
|
31
|
+
body_json: nil, variables: nil, is_active: nil)
|
|
32
|
+
body = compact_params(
|
|
33
|
+
"name" => name,
|
|
34
|
+
"subject" => subject,
|
|
35
|
+
"body_text" => body_text,
|
|
36
|
+
"body_html" => body_html,
|
|
37
|
+
"body_json" => body_json,
|
|
38
|
+
"variables" => variables,
|
|
39
|
+
"is_active" => is_active
|
|
40
|
+
)
|
|
41
|
+
request(:put, "/v1/templates/#{encode(id)}", body: body) || {}
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def delete(id)
|
|
45
|
+
request(:delete, "/v1/templates/#{encode(id)}")
|
|
46
|
+
nil
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def render(id, vars = {})
|
|
50
|
+
request(:post, "/v1/templates/#{encode(id)}/render", body: { "vars" => vars || {} }) || {}
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|