amply-ruby 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/LICENSE +21 -0
- data/README.md +107 -0
- data/amply-ruby.gemspec +21 -0
- data/lib/amply/client.rb +55 -0
- data/lib/amply/email.rb +12 -0
- data/lib/amply/exceptions/api_exception.rb +18 -0
- data/lib/amply/exceptions/resource_not_found_exception.rb +19 -0
- data/lib/amply/exceptions/validation_exception.rb +19 -0
- data/lib/amply/exceptions.rb +3 -0
- data/lib/amply/helpers/email.rb +247 -0
- data/lib/amply/helpers/email_address.rb +84 -0
- data/lib/amply/version.rb +3 -0
- data/lib/amply.rb +12 -0
- metadata +57 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4277fb080efe8030459c1e5c6f837738b224e368ace142d33875a41926cf8f7e
|
4
|
+
data.tar.gz: fbd25ca786496e8dba524ea98cc4c5bce9c650200201a0f1a1286da0d6e18f89
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 76066fdb26b96a85bb8628f29585e855113459ffaff974262f0ffce09eedf2fb20e637c31661e50d414b7e537e6e64bc2acba2cfd11fd11efd4eda3502b00fa6
|
7
|
+
data.tar.gz: 07b11ae389c464c513413734743f53fd912e8d9a0469e28629b181a0d2d65cdc5d36599ce776115242cc93cd50fb249dbacf5891b48b1d7b389e9297fd7e8e22
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (C) 2020, Send Amply Inc. <support@sendamply.com>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
9
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
10
|
+
so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
# Amply
|
2
|
+
|
3
|
+
This is the Amply Ruby SDK that integrates with the [v1 API](https://docs.sendamply.com/docs/api/docs/Introduction.md).
|
4
|
+
|
5
|
+
__Table of Contents__
|
6
|
+
|
7
|
+
- [Install](#install)
|
8
|
+
- [Quick Start](#quick-start)
|
9
|
+
- [Classes](#classes)
|
10
|
+
- [Email](#Email)
|
11
|
+
|
12
|
+
## Install
|
13
|
+
|
14
|
+
### Prerequisites
|
15
|
+
- Ruby 2.4+
|
16
|
+
- Amply account, [sign up here.](https://sendamply.com/plans)
|
17
|
+
|
18
|
+
### Access Token
|
19
|
+
|
20
|
+
Obtain your access token from the [Amply UI.](https://sendamply.com/home/settings/access_tokens)
|
21
|
+
|
22
|
+
### Install Package
|
23
|
+
```
|
24
|
+
gem install amply-ruby
|
25
|
+
```
|
26
|
+
|
27
|
+
### Domain Verification
|
28
|
+
Add domains you want to send `from` via the [Verified Domains](https://sendamply.com/home/settings/verified_domains) tab on your dashboard.
|
29
|
+
|
30
|
+
Any emails you attempt to send from an unverified domain will be rejected. Once verified, Amply immediately starts warming up your domain and IP reputation. This warmup process will take approximately one week before maximal deliverability has been reached.
|
31
|
+
|
32
|
+
## Quick Start
|
33
|
+
The following is the minimum needed code to send a simple email. Use this example, and modify the `to` and `from` variables:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
require 'amply'
|
37
|
+
|
38
|
+
Amply.set_access_token(ENV['AMPLY_ACCESS_TOKEN'])
|
39
|
+
|
40
|
+
begin
|
41
|
+
Amply::Email.create(to: 'test@example.com',
|
42
|
+
from: 'test@verifieddomain.com',
|
43
|
+
subject: 'My first Amply email!',
|
44
|
+
text: 'This is easy',
|
45
|
+
html: '<strong>and fun :)</strong>')
|
46
|
+
|
47
|
+
rescue Amply::Exceptions::APIException => e
|
48
|
+
# Most likely invalid access token
|
49
|
+
puts e.status
|
50
|
+
puts e.text
|
51
|
+
rescue Amply::Exceptions::ValidationException => e
|
52
|
+
puts e.message
|
53
|
+
puts e.errors
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
Once you execute this code, you should have an email in the inbox of the recipient. You can check the status of your email in the UI from the [Search](https://sendamply.com/home/analytics/searches/basic/new), [SQL](https://sendamply.com/home/analytics/searches/sql/new), or [Users](https://sendamply.com/home/analytics/users) page.
|
58
|
+
|
59
|
+
## Methods
|
60
|
+
|
61
|
+
### email
|
62
|
+
|
63
|
+
Parameter(s) | Description
|
64
|
+
:---------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
65
|
+
to, cc, bcc | Email address of the recipient(s). This may be a string `Test <test@example.com>`, a hash `{ name: 'Test', email: 'test@example.com' }`, or an array of strings and hashes.
|
66
|
+
personalizations | For fine tuned access, you may override the to, cc, and bcc keys and use advanced personalizations. See the API guide [here](https://docs.sendamply.com/docs/api/Mail-Send.v1.yaml/paths/~1email/post).
|
67
|
+
from | Email address of the sender. This may be formatted as a string or hash. An array of senders is not allowed.
|
68
|
+
subject | Subject of the message.
|
69
|
+
html | HTML portion of the message.
|
70
|
+
text | Text portion of the message.
|
71
|
+
content | An array of hashes containing the following keys: `type` (required), `value` (required).
|
72
|
+
template | The template to use. This may be a string (the UUID of the template), an array of UUID's (useful for A/B/... testing where one is randomly selected), or a hash of the format `{ template1Uuid: 0.25, template2Uuid: 0.75 }` (useful for weighted A/B/... testing).
|
73
|
+
dynamic_template_data | The dynamic data to be replaced in your template. This is an hash of the format `{ variable1: 'replacement1', ... }`. Variables should be defined in your template body as `${variable1}`.
|
74
|
+
reply_to |Email address of who should receive replies. This may be a string or a hash with `name` and `email` keys.
|
75
|
+
headers | A hash where the header name is the key and header value is the value.
|
76
|
+
ip_or_pool_uuid | The UUID of the IP address or IP pool you want to send from. Default is your Global pool.
|
77
|
+
unsubscribe_group_uuid | The UUID of the unsubscribe group you want to associate with this email.
|
78
|
+
attachments[][content] | A base64 encoded string of your attachment's content.
|
79
|
+
attachments[][type] | The MIME type of your attachment.
|
80
|
+
attachments[][filename] | The filename of your attachment.
|
81
|
+
attachments[][disposition] | The disposition of your attachment (`inline` or `attachment`).
|
82
|
+
attachments[][content_id] | The content ID of your attachment.
|
83
|
+
clicktracking | Enable or disable clicktracking.
|
84
|
+
categories | An array of email categories you can associate with your message.
|
85
|
+
substitutions | A hash of the format `{ sub_from: 'sub_to', ...}` of substitutions.
|
86
|
+
|
87
|
+
__Example__
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
Amply::Email.create(to: 'example@test.com',
|
91
|
+
from: 'From <example@verifieddomain.com>',
|
92
|
+
text: 'Text part',
|
93
|
+
html: 'HTML part',
|
94
|
+
personalizations: [{ to: [{ name: 'Override To', email: 'test@example.com' }] }],
|
95
|
+
content: [{ type: 'text/testing', value: 'some custom content type' }],
|
96
|
+
subject: 'A new email!',
|
97
|
+
reply_to: 'Reply To <test@example.com>',
|
98
|
+
template: 'faecb75b-371e-4062-89d5-372b8ff0effd',
|
99
|
+
dynamic_template_data: { name: 'Jimmy' },
|
100
|
+
unsubscribe_group_uuid: '5ac48b43-6e7e-4c51-817d-f81ea0a09816',
|
101
|
+
ip_or_pool_uuid: '2e378fc9-3e23-4853-bccb-2990fda83ca9',
|
102
|
+
attachments: [{'content': 'dGVzdA==', 'filename': 'test.txt', 'type': 'text/plain', 'disposition': 'inline'}],
|
103
|
+
headers: {'X-Testing': 'Test'},
|
104
|
+
categories: ['Test'],
|
105
|
+
clicktracking: true,
|
106
|
+
substitutions: { sub1: 'replacement1' })
|
107
|
+
```
|
data/amply-ruby.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'amply/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'amply-ruby'
|
7
|
+
spec.version = Amply::VERSION
|
8
|
+
spec.email = 'support@sendamply.com'
|
9
|
+
spec.authors = ['Amply']
|
10
|
+
spec.summary = 'Amply Gem'
|
11
|
+
spec.description = 'Amply Gem to Interact with Amply\'s API in native Ruby'
|
12
|
+
spec.homepage = 'https://github.com/sendamply/amply-ruby'
|
13
|
+
|
14
|
+
spec.required_ruby_version = '>= 2.4'
|
15
|
+
|
16
|
+
spec.license = 'MIT'
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.executables = spec.files.grep(/^bin/) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(/^(test|spec|features)/)
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
end
|
data/lib/amply/client.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Amply
|
5
|
+
class Client
|
6
|
+
DEFAULT_HEADERS = {
|
7
|
+
Accept: 'application/json',
|
8
|
+
'Content-Type': 'application/json'
|
9
|
+
}
|
10
|
+
|
11
|
+
class << self
|
12
|
+
@@access_token = ''
|
13
|
+
@@url = 'https://sendamply.com/api/v1'
|
14
|
+
|
15
|
+
def set_access_token(token)
|
16
|
+
@@access_token = token
|
17
|
+
end
|
18
|
+
|
19
|
+
def post(path, body, options = {})
|
20
|
+
uri = URI("#{@@url}#{path}")
|
21
|
+
headers = [
|
22
|
+
DEFAULT_HEADERS,
|
23
|
+
options[:headers] || {},
|
24
|
+
auth_header
|
25
|
+
].inject(&:merge)
|
26
|
+
|
27
|
+
|
28
|
+
resp = Net::HTTP.post(uri, body.to_json, headers)
|
29
|
+
parse_response(resp)
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse_response(resp)
|
33
|
+
code = resp.code.to_i
|
34
|
+
|
35
|
+
if [301, 302].include?(code)
|
36
|
+
return resp['location']
|
37
|
+
elsif [401, 403].include?(code)
|
38
|
+
raise Exceptions::APIException, resp
|
39
|
+
elsif code == 404
|
40
|
+
raise Exceptions::ResourcNotFoundException, resp
|
41
|
+
elsif code == 422
|
42
|
+
raise Exceptions::ValidationException, resp
|
43
|
+
elsif code < 200 || code >= 300
|
44
|
+
raise Exceptions::APIException, resp
|
45
|
+
end
|
46
|
+
|
47
|
+
JSON.parse(resp.body, symbolize_names: true)
|
48
|
+
end
|
49
|
+
|
50
|
+
def auth_header
|
51
|
+
{ Authorization: "Bearer #{@@access_token}" }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/amply/email.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Amply
|
2
|
+
module Exceptions
|
3
|
+
class APIException < StandardError
|
4
|
+
attr_reader :status, :text
|
5
|
+
|
6
|
+
def initialize(response)
|
7
|
+
@status = response.code.to_i
|
8
|
+
@text = response.message
|
9
|
+
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
def message
|
14
|
+
'An error occurred while making an API request'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Amply
|
4
|
+
module Exceptions
|
5
|
+
class ResourceNotFoundException < StandardError
|
6
|
+
attr_reader :errors
|
7
|
+
|
8
|
+
def initialize(response)
|
9
|
+
@errors = JSON.parse(response.body, symbolize_names: true)[:errors]
|
10
|
+
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def message
|
15
|
+
'The resource was not found while making an API request'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Amply
|
4
|
+
module Exceptions
|
5
|
+
class ValidationException < StandardError
|
6
|
+
attr_reader :errors
|
7
|
+
|
8
|
+
def initialize(response)
|
9
|
+
@errors = JSON.parse(response.body, symbolize_names: true)[:errors]
|
10
|
+
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def message
|
15
|
+
'A validation error occurred while making an API request'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,247 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
require_relative './email_address'
|
4
|
+
|
5
|
+
module Amply
|
6
|
+
module Helpers
|
7
|
+
class Email
|
8
|
+
def initialize(data)
|
9
|
+
@data = data
|
10
|
+
@request_data = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def parsed_data
|
14
|
+
unless @data.is_a?(Hash)
|
15
|
+
raise 'Expecting hash for email data'
|
16
|
+
end
|
17
|
+
|
18
|
+
data_sym = JSON.parse(JSON.dump(@data), symbolize_names: true)
|
19
|
+
|
20
|
+
set_from(data_sym[:from])
|
21
|
+
set_subject(data_sym[:subject])
|
22
|
+
set_text(data_sym[:text])
|
23
|
+
set_html(data_sym[:html])
|
24
|
+
set_content(data_sym[:content])
|
25
|
+
set_reply_to(data_sym[:reply_to])
|
26
|
+
set_template(data_sym[:template])
|
27
|
+
set_dynamic_template_data(data_sym[:dynamic_template_data])
|
28
|
+
set_unsubscribe_group_uuid(data_sym[:unsubscribe_group_uuid])
|
29
|
+
set_ip_or_pool_uuid(data_sym[:ip_or_pool_uuid])
|
30
|
+
set_attachments(data_sym[:attachments])
|
31
|
+
set_headers(data_sym[:headers])
|
32
|
+
set_categories(data_sym[:categories])
|
33
|
+
set_clicktracking(data_sym[:clicktracking])
|
34
|
+
set_substitutions(data_sym[:substitutions])
|
35
|
+
|
36
|
+
if data_sym[:personalizations].nil?
|
37
|
+
set_personalizations_from_to(data_sym[:to], data_sym[:cc], data_sym[:bcc])
|
38
|
+
else
|
39
|
+
set_personalizations(data_sym[:personalizations])
|
40
|
+
end
|
41
|
+
|
42
|
+
@request_data
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def set_from(from)
|
48
|
+
return if from.nil?
|
49
|
+
@request_data[:from] = format_emails(from)[0]
|
50
|
+
end
|
51
|
+
|
52
|
+
def set_subject(subject)
|
53
|
+
unless subject.is_a?(String)
|
54
|
+
raise 'String expected for `subject`'
|
55
|
+
end
|
56
|
+
|
57
|
+
@request_data[:subject] = subject
|
58
|
+
end
|
59
|
+
|
60
|
+
def set_text(text)
|
61
|
+
return if text.nil?
|
62
|
+
|
63
|
+
@request_data[:content] ||= []
|
64
|
+
@request_data[:content].push(type: 'text/plain', value: text)
|
65
|
+
end
|
66
|
+
|
67
|
+
def set_html(html)
|
68
|
+
return if html.nil?
|
69
|
+
|
70
|
+
@request_data[:content] ||= []
|
71
|
+
@request_data[:content].push(type: 'text/html', value: html)
|
72
|
+
end
|
73
|
+
|
74
|
+
def set_content(content)
|
75
|
+
return if content.nil?
|
76
|
+
|
77
|
+
unless content.is_a?(Array)
|
78
|
+
raise 'Array expected for `content`'
|
79
|
+
end
|
80
|
+
|
81
|
+
@request_data[:content] ||= []
|
82
|
+
|
83
|
+
content.each_with_index do |part, i|
|
84
|
+
unless part.is_a?(Hash)
|
85
|
+
raise "Hash expected for `content[#{i}]`"
|
86
|
+
end
|
87
|
+
|
88
|
+
type = part[:type] || part['type']
|
89
|
+
value = part[:value] || part['value']
|
90
|
+
|
91
|
+
if type.nil?
|
92
|
+
raise "`type` must be defined for `content[#{i}][type]`"
|
93
|
+
end
|
94
|
+
|
95
|
+
if value.nil?
|
96
|
+
raise "`value` must be defined for `content[#{i}][type]`"
|
97
|
+
end
|
98
|
+
|
99
|
+
@request_data[:content].push(type: type, value: value)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def set_reply_to(reply_to)
|
104
|
+
return if reply_to.nil?
|
105
|
+
@request_data[:reply_to] = format_emails(reply_to)[0]
|
106
|
+
end
|
107
|
+
|
108
|
+
def set_template(template)
|
109
|
+
return if template.nil?
|
110
|
+
@request_data[:template] = template
|
111
|
+
end
|
112
|
+
|
113
|
+
def set_dynamic_template_data(dynamic_template_data)
|
114
|
+
return if dynamic_template_data.nil?
|
115
|
+
|
116
|
+
unless dynamic_template_data.is_a?(Hash)
|
117
|
+
raise 'Hash expected for `dynamic_template_data`'
|
118
|
+
end
|
119
|
+
|
120
|
+
@request_data[:substitutions] ||= {}
|
121
|
+
|
122
|
+
dynamic_template_data.each do |sub_from, sub_to|
|
123
|
+
@request_data[:substitutions]["${#{sub_from}}"] = sub_to.to_s
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def set_unsubscribe_group_uuid(unsubscribe_group_uuid)
|
128
|
+
return if unsubscribe_group_uuid.nil?
|
129
|
+
@request_data[:unsubscribe_group_uuid] = unsubscribe_group_uuid
|
130
|
+
end
|
131
|
+
|
132
|
+
def set_ip_or_pool_uuid(ip_or_pool_uuid)
|
133
|
+
return if ip_or_pool_uuid.nil?
|
134
|
+
@request_data[:ip_or_pool_uuid] = ip_or_pool_uuid
|
135
|
+
end
|
136
|
+
|
137
|
+
def set_attachments(attachments)
|
138
|
+
return if attachments.nil?
|
139
|
+
|
140
|
+
unless attachments.is_a?(Array)
|
141
|
+
raise 'Array expected for `attachments`'
|
142
|
+
end
|
143
|
+
|
144
|
+
@request_data[:attachments] ||= []
|
145
|
+
|
146
|
+
attachments.each_with_index do |attachment, i|
|
147
|
+
unless attachment.is_a?(Hash)
|
148
|
+
raise "Hash expected for `attachments[#{i}]`"
|
149
|
+
end
|
150
|
+
|
151
|
+
content = attachment[:content] || attachment['content']
|
152
|
+
filename = attachment[:filename] || attachment['filename']
|
153
|
+
type = attachment[:type] || attachment['type']
|
154
|
+
disposition = attachment[:disposition] || attachment['disposition']
|
155
|
+
|
156
|
+
if content.nil?
|
157
|
+
raise "`content` must be defined for `attachments[#{i}][content]`"
|
158
|
+
end
|
159
|
+
|
160
|
+
if filename.nil?
|
161
|
+
raise "`filename` must be defined for `attachments[#{i}][filename]`"
|
162
|
+
end
|
163
|
+
|
164
|
+
data = { content: content, filename: filename }
|
165
|
+
data.merge!(type: type) unless type.nil?
|
166
|
+
data.merge!(disposition: disposition) unless disposition.nil?
|
167
|
+
|
168
|
+
@request_data[:attachments].push(data)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def set_headers(headers)
|
173
|
+
return if headers.nil?
|
174
|
+
|
175
|
+
unless headers.is_a?(Hash)
|
176
|
+
raise 'Hash expected for `headers`'
|
177
|
+
end
|
178
|
+
|
179
|
+
@request_data[:headers] ||= {}
|
180
|
+
|
181
|
+
headers.each do |name, value|
|
182
|
+
@request_data[:headers][name] = value.to_s
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def set_categories(categories)
|
187
|
+
return if categories.nil?
|
188
|
+
|
189
|
+
unless categories.is_a?(Array)
|
190
|
+
raise 'Array expected for `categories`'
|
191
|
+
end
|
192
|
+
|
193
|
+
@request_data[:analytics] ||= {}
|
194
|
+
@request_data[:analytics][:categories] = categories.map { |category| category.to_s }
|
195
|
+
end
|
196
|
+
|
197
|
+
def set_clicktracking(clicktracking)
|
198
|
+
return if clicktracking.nil?
|
199
|
+
|
200
|
+
unless [TrueClass, FalseClass].include?(clicktracking.class)
|
201
|
+
raise 'Expecting TrueClass or FalseClass for `clicktracking`'
|
202
|
+
end
|
203
|
+
|
204
|
+
@request_data[:analytics] ||= {}
|
205
|
+
@request_data[:analytics][:clicktracking] = clicktracking
|
206
|
+
end
|
207
|
+
|
208
|
+
def set_substitutions(substitutions)
|
209
|
+
return if substitutions.nil?
|
210
|
+
|
211
|
+
unless substitutions.is_a?(Hash)
|
212
|
+
raise 'Hash expected for `substitutions`'
|
213
|
+
end
|
214
|
+
|
215
|
+
@request_data[:substitutions] ||= {}
|
216
|
+
|
217
|
+
substitutions.each do |sub_from, sub_to|
|
218
|
+
@request_data[:substitutions][sub_from] = sub_to.to_s
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def set_personalizations_from_to(to, cc, bcc)
|
223
|
+
@request_data[:personalizations] = [{}]
|
224
|
+
|
225
|
+
if to.nil? && cc.nil? && bcc.nil?
|
226
|
+
raise 'Provide at least one of `to`, `cc` or `bcc`'
|
227
|
+
end
|
228
|
+
|
229
|
+
@request_data[:personalizations][0][:to] = format_emails(to) unless to.nil?
|
230
|
+
@request_data[:personalizations][0][:cc] = format_emails(cc) unless cc.nil?
|
231
|
+
@request_data[:personalizations][0][:bcc] = format_emails(bcc) unless bcc.nil?
|
232
|
+
end
|
233
|
+
|
234
|
+
def set_personalizations(personalizations)
|
235
|
+
@request_data[:personalizations] = personalizations
|
236
|
+
end
|
237
|
+
|
238
|
+
def format_emails(emails)
|
239
|
+
if emails.is_a?(Array)
|
240
|
+
return emails.map { |email| EmailAddress.new(email).to_json }
|
241
|
+
end
|
242
|
+
|
243
|
+
[EmailAddress.new(emails).to_json]
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Amply
|
2
|
+
module Helpers
|
3
|
+
class EmailAddress
|
4
|
+
class << self
|
5
|
+
def create(data)
|
6
|
+
if data.is_a?(Array)
|
7
|
+
return data.reject { |el| el.nil? || el == '' }
|
8
|
+
.map { |el| self.class.create(el) }
|
9
|
+
end
|
10
|
+
|
11
|
+
if data.is_a?(EmailAddress)
|
12
|
+
return data
|
13
|
+
end
|
14
|
+
|
15
|
+
self.class.create(data)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(data)
|
20
|
+
if data.is_a?(String)
|
21
|
+
data = from_string(data)
|
22
|
+
end
|
23
|
+
|
24
|
+
unless data.is_a?(Hash)
|
25
|
+
raise 'Expecting hash or string for email address data'
|
26
|
+
end
|
27
|
+
|
28
|
+
name = data[:name] || data['name']
|
29
|
+
email = data[:email] || data['email']
|
30
|
+
|
31
|
+
set_name(name)
|
32
|
+
set_email(email)
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_json
|
36
|
+
json = { email: @email }
|
37
|
+
|
38
|
+
unless @name.nil?
|
39
|
+
json[:name] = @name
|
40
|
+
end
|
41
|
+
|
42
|
+
json
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def set_name(name)
|
48
|
+
return if name.nil?
|
49
|
+
|
50
|
+
unless name.is_a?(String)
|
51
|
+
raise 'String expected for `name`'
|
52
|
+
end
|
53
|
+
|
54
|
+
@name = name
|
55
|
+
end
|
56
|
+
|
57
|
+
def set_email(email)
|
58
|
+
if email.nil?
|
59
|
+
raise 'Must provide `email`'
|
60
|
+
end
|
61
|
+
|
62
|
+
unless email.is_a?(String)
|
63
|
+
raise 'String expected for `email`'
|
64
|
+
end
|
65
|
+
|
66
|
+
@email = email
|
67
|
+
end
|
68
|
+
|
69
|
+
def from_string(data)
|
70
|
+
if data.index('<').nil?
|
71
|
+
return { name: nil, email: data }
|
72
|
+
end
|
73
|
+
|
74
|
+
name, email = data.split('<')
|
75
|
+
|
76
|
+
name.strip!
|
77
|
+
email.gsub!('>', '')
|
78
|
+
email.strip!
|
79
|
+
|
80
|
+
{ name: name, email: email }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/lib/amply.rb
ADDED
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: amply-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Amply
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-12-28 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Amply Gem to Interact with Amply's API in native Ruby
|
14
|
+
email: support@sendamply.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- ".gitignore"
|
20
|
+
- LICENSE
|
21
|
+
- README.md
|
22
|
+
- amply-ruby.gemspec
|
23
|
+
- lib/amply.rb
|
24
|
+
- lib/amply/client.rb
|
25
|
+
- lib/amply/email.rb
|
26
|
+
- lib/amply/exceptions.rb
|
27
|
+
- lib/amply/exceptions/api_exception.rb
|
28
|
+
- lib/amply/exceptions/resource_not_found_exception.rb
|
29
|
+
- lib/amply/exceptions/validation_exception.rb
|
30
|
+
- lib/amply/helpers/email.rb
|
31
|
+
- lib/amply/helpers/email_address.rb
|
32
|
+
- lib/amply/version.rb
|
33
|
+
homepage: https://github.com/sendamply/amply-ruby
|
34
|
+
licenses:
|
35
|
+
- MIT
|
36
|
+
metadata: {}
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options: []
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '2.4'
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
requirements: []
|
52
|
+
rubyforge_project:
|
53
|
+
rubygems_version: 2.7.6
|
54
|
+
signing_key:
|
55
|
+
specification_version: 4
|
56
|
+
summary: Amply Gem
|
57
|
+
test_files: []
|