hubspot-mailer 0.0.1
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/lib/hubspot-mailer.rb +8 -0
- data/lib/hubspot/mailer.rb +179 -0
- data/lib/hubspot/mailer/delivery.rb +17 -0
- data/lib/hubspot/mailer/exceptions.rb +21 -0
- data/lib/hubspot/mailer/hubspot_preview_interceptor.rb +48 -0
- data/lib/hubspot/mailer/message.rb +10 -0
- metadata +98 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 84be921dddd2279d24cd15c9a4f0a182bba57e58
|
|
4
|
+
data.tar.gz: 27960c36c5cccfeb6a0a02835c3af5ef4fa3c4c6
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: c825a4740b1758e896823f147d7298b453163247753d863049604d9555cfb53b62f9e9679e6efaa0aa6e7bbf21e2dd55a80b460d50a0002ac33265874c49dfab
|
|
7
|
+
data.tar.gz: f3f538cdc9547886dec6ec50b6fb4a8ed77fe0ff6bc7dfc397112e0f0462e3f7b348b7e75a2a73f162afd1536f4ce2f970d3fed65dcb21866ed830a5e2857562
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
module Hubspot
|
|
2
|
+
class Mailer < ActionMailer::Base
|
|
3
|
+
abstract!
|
|
4
|
+
|
|
5
|
+
register_preview_interceptor(HubspotPreviewInterceptor)
|
|
6
|
+
|
|
7
|
+
# Register our own delivery method
|
|
8
|
+
add_delivery_method :hubspot, Delivery
|
|
9
|
+
|
|
10
|
+
# Set hubspot as a default delivery method
|
|
11
|
+
self.delivery_method = :hubspot
|
|
12
|
+
|
|
13
|
+
# Set credentials
|
|
14
|
+
# self.hubspot_settings = { :hapikey => ENV.fetch("HUBSPOT_API_KEY") }
|
|
15
|
+
|
|
16
|
+
self.default_params = {}.freeze
|
|
17
|
+
|
|
18
|
+
SINGLE_SEND_PATH = '/email/public/v1/singleEmail/send'.freeze
|
|
19
|
+
|
|
20
|
+
class << self
|
|
21
|
+
# Wraps an email delivery inside of <tt>ActiveSupport::Notifications</tt> instrumentation.
|
|
22
|
+
#
|
|
23
|
+
# This method is actually called by the <tt>Mail::Message</tt> object itself
|
|
24
|
+
# through a callback when you call <tt>:deliver</tt> on the <tt>Mail::Message</tt>,
|
|
25
|
+
# calling +deliver_mail+ directly and passing a <tt>Mail::Message</tt> will do
|
|
26
|
+
# nothing except tell the logger you sent the email.
|
|
27
|
+
def deliver_mail(mail) #:nodoc:
|
|
28
|
+
ActiveSupport::Notifications.instrument("deliver.hubspot_mailer") do |payload|
|
|
29
|
+
set_payload_for_mail(payload, mail)
|
|
30
|
+
yield # Let Mail do the delivery actions
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Perform the delivery by calling Hubspot's API
|
|
35
|
+
#
|
|
36
|
+
# Receives regular mail object that contains additional template details.
|
|
37
|
+
def single_send(mail)
|
|
38
|
+
# Format the request data
|
|
39
|
+
data = single_send_params(mail)
|
|
40
|
+
|
|
41
|
+
# Call the API
|
|
42
|
+
response = Hubspot::Connection.post_json(SINGLE_SEND_PATH, params: {}, body: data)
|
|
43
|
+
|
|
44
|
+
# Parse response and either raise or return event details
|
|
45
|
+
parse_response(response)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def set_payload_for_mail(payload, mail)
|
|
51
|
+
payload[:mailer] = name
|
|
52
|
+
payload[:message_id] = mail.message_id
|
|
53
|
+
payload[:subject] = mail.subject
|
|
54
|
+
payload[:to] = mail.to
|
|
55
|
+
payload[:from] = mail.from if mail.from.present?
|
|
56
|
+
payload[:send_id] = mail.send_id if mail.send_id.present?
|
|
57
|
+
payload[:reply_to] = mail.reply_to if mail.reply_to.present?
|
|
58
|
+
payload[:cc] = mail.cc if mail.cc.present?
|
|
59
|
+
payload[:bcc] = mail.bcc if mail.bcc.present?
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def single_send_params(mail)
|
|
63
|
+
raise MissingTemplateError, "Missing emailId parameter." unless mail.email_id.present?
|
|
64
|
+
raise MissingRecipientError, "Missing recipient emaul." unless mail.to.present?
|
|
65
|
+
|
|
66
|
+
data = {
|
|
67
|
+
emailId: mail.email_id,
|
|
68
|
+
message: { to: mail.to.first }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
data[:message][:from] = mail.from.first if mail.from.present?
|
|
72
|
+
data[:message][:cc] = mail.cc if mail.cc.present?
|
|
73
|
+
data[:message][:bcc] = mail.bcc if mail.bcc.present?
|
|
74
|
+
data[:message][:sendId] = mail.send_id if mail.send_id.present?
|
|
75
|
+
|
|
76
|
+
if mail.reply_to.present?
|
|
77
|
+
if mail.reply_to.size > 1
|
|
78
|
+
data[:message][:replyToList] = mail.reply_to
|
|
79
|
+
else
|
|
80
|
+
data[:message][:replyTo] = mail.reply_to.first
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Copy subject from header to custom property
|
|
85
|
+
if mail.subject.present? and not mail.custom_properties.try(:[], :subject)
|
|
86
|
+
mail.custom_properties ||= {}
|
|
87
|
+
mail.custom_properties[:subject] = mail.subject
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
if mail.contact_properties.present?
|
|
91
|
+
data[:contactProperties] =
|
|
92
|
+
Hubspot::Utils.hash_to_properties(mail.contact_properties, :key_name => :name)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
if mail.custom_properties.present?
|
|
96
|
+
data[:customProperties] =
|
|
97
|
+
Hubspot::Utils.hash_to_properties(mail.custom_properties, :key_name => :name)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
data
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def parse_response(response)
|
|
104
|
+
status_code = response["sendResult"]
|
|
105
|
+
|
|
106
|
+
case status_code
|
|
107
|
+
when "SENT", "QUEUED"
|
|
108
|
+
response["eventId"]
|
|
109
|
+
when "INVALID_TO_ADDRESS"
|
|
110
|
+
raise RecipientAddressError.new(response), "The TO address is invalid: #{status_code}"
|
|
111
|
+
when "INVALID_FROM_ADDRESS"
|
|
112
|
+
raise SenderAddressError.new(response), "The FROM address is invalid: #{status_code}"
|
|
113
|
+
when "BLOCKED_DOMAIN", "PORTAL_SUSPENDED"
|
|
114
|
+
raise SendingError.new(response), "Message can't be sent: #{status_code}"
|
|
115
|
+
when "PREVIOUSLY_BOUNCED", "PREVIOUS_SPAM"
|
|
116
|
+
raise DeliveryError.new(response), "Message can't be delivered: #{status_code}"
|
|
117
|
+
when "MISSING_CONTENT"
|
|
118
|
+
raise InvalidTemplateError.new(response), "The emailId is invalid, or the emailId is an email that is not set up for Single Send: #{status_code}"
|
|
119
|
+
else
|
|
120
|
+
raise UnknownResponseError.new(response), "Unrecognized status code: #{status_code}"
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
attr_internal :message
|
|
126
|
+
|
|
127
|
+
def initialize
|
|
128
|
+
super()
|
|
129
|
+
@_mail_was_called = false
|
|
130
|
+
@_message = Message.new
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def process(method_name, *args) #:nodoc:
|
|
134
|
+
payload = {
|
|
135
|
+
mailer: self.class.name,
|
|
136
|
+
action: method_name,
|
|
137
|
+
args: args
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
ActiveSupport::Notifications.instrument("process.hubspot_mailer", payload) do
|
|
141
|
+
super
|
|
142
|
+
@_message = ActionMailer::Base::NullMail.new unless @_mail_was_called
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def mail(headers = {}, &block)
|
|
147
|
+
return message if @_mail_was_called && headers.blank? && !block
|
|
148
|
+
|
|
149
|
+
headers = apply_defaults(headers)
|
|
150
|
+
|
|
151
|
+
# Set configure delivery behavior
|
|
152
|
+
wrap_delivery_behavior!(headers[:delivery_method], headers[:delivery_method_options])
|
|
153
|
+
|
|
154
|
+
# Hubspot-specific attributes, e.g. emailId (template ID)
|
|
155
|
+
assign_attributes_to_message(message, headers)
|
|
156
|
+
|
|
157
|
+
# Default headers
|
|
158
|
+
assign_headers_to_message(message, headers)
|
|
159
|
+
|
|
160
|
+
@_mail_was_called = true
|
|
161
|
+
|
|
162
|
+
message
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
private
|
|
166
|
+
|
|
167
|
+
def assign_attributes_to_message(message, headers)
|
|
168
|
+
hubspot_props = %i[email_id send_id contact_properties custom_properties]
|
|
169
|
+
|
|
170
|
+
headers.slice(*hubspot_props).each { |k, v| message.try("#{k}=", v) }
|
|
171
|
+
headers.except!(*hubspot_props)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def assign_headers_to_message(message, headers)
|
|
175
|
+
headers.except(:parts_order, :content_type, :body, :template_name,
|
|
176
|
+
:template_path, :delivery_method, :delivery_method_options).each { |k, v| message[k] = v }
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Hubspot
|
|
2
|
+
class Mailer < ActionMailer::Base
|
|
3
|
+
class Delivery
|
|
4
|
+
attr_accessor :settings
|
|
5
|
+
|
|
6
|
+
DEFAULTS = {}
|
|
7
|
+
|
|
8
|
+
def initialize(values)
|
|
9
|
+
self.settings = DEFAULTS.merge(values)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def deliver!(mail)
|
|
13
|
+
Hubspot::Mailer.single_send(mail)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Hubspot
|
|
2
|
+
class Mailer < ActionMailer::Base
|
|
3
|
+
class MissingTemplateError < StandardError; end
|
|
4
|
+
class MissingRecipientError < StandardError; end
|
|
5
|
+
|
|
6
|
+
class RequestError < StandardError
|
|
7
|
+
attr_reader :response
|
|
8
|
+
|
|
9
|
+
def initialize(response = nil)
|
|
10
|
+
@response = response
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class RecipientAddressError < RequestError; end
|
|
15
|
+
class SenderAddressError < RequestError; end
|
|
16
|
+
class SendingError < RequestError; end
|
|
17
|
+
class DeliveryError < RequestError; end
|
|
18
|
+
class InvalidTemplateError < RequestError; end
|
|
19
|
+
class UnknownResponseError < RequestError; end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Hubspot
|
|
2
|
+
class Mailer < ActionMailer::Base
|
|
3
|
+
class HubspotPreviewInterceptor
|
|
4
|
+
class << self
|
|
5
|
+
def previewing_email(message)
|
|
6
|
+
new(message).transform!
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
attr_reader :message
|
|
11
|
+
|
|
12
|
+
def initialize(message)
|
|
13
|
+
@message = message
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def transform!
|
|
17
|
+
build_preview
|
|
18
|
+
message
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def build_preview
|
|
24
|
+
html_part = "<b>Email ID (template)</b>: #{message.email_id}<br/><br/>"
|
|
25
|
+
|
|
26
|
+
html_part << list_properties("Contact Properties (use via {{contact.propertyname}})", message.contact_properties)
|
|
27
|
+
html_part << list_properties("Custom Properties (use via {{custom.property_name}})", message.custom_properties)
|
|
28
|
+
|
|
29
|
+
message.html_part = html_part
|
|
30
|
+
|
|
31
|
+
message
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def list_properties(label, list)
|
|
35
|
+
buffer = ""
|
|
36
|
+
return buffer unless list.present?
|
|
37
|
+
|
|
38
|
+
buffer << "<b>#{label}</b>:<ul>"
|
|
39
|
+
|
|
40
|
+
list.each_pair do |property, value|
|
|
41
|
+
buffer << "<li><i>#{property}</i>: #{value}</li>"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
buffer << "</ul>"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: hubspot-mailer
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- heaven
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2018-12-09 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: hubspot-ruby
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0.4'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0.4'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: actionmailer
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '5.1'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '5.1'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: bundler
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '1.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '1.0'
|
|
55
|
+
description: Create beautiful transactional emails right within HubSpot using the
|
|
56
|
+
email editor with all the benefits of smart content, personalization and templates
|
|
57
|
+
- just like regular HubSpot emails. Create beautiful transactional emails right
|
|
58
|
+
within HubSpot using the email editor with all the benefits of smart content, personalization
|
|
59
|
+
and templates - just like regular HubSpot emails. Create beautiful transactional
|
|
60
|
+
emails right within HubSpot using the email editor with all the benefits of smart
|
|
61
|
+
content, personalization and templates - just like regular HubSpot emails.
|
|
62
|
+
email:
|
|
63
|
+
- hello@codeart.us
|
|
64
|
+
executables: []
|
|
65
|
+
extensions: []
|
|
66
|
+
extra_rdoc_files: []
|
|
67
|
+
files:
|
|
68
|
+
- lib/hubspot-mailer.rb
|
|
69
|
+
- lib/hubspot/mailer.rb
|
|
70
|
+
- lib/hubspot/mailer/delivery.rb
|
|
71
|
+
- lib/hubspot/mailer/exceptions.rb
|
|
72
|
+
- lib/hubspot/mailer/hubspot_preview_interceptor.rb
|
|
73
|
+
- lib/hubspot/mailer/message.rb
|
|
74
|
+
homepage: https://github.com/heaven/hubspot-mailer
|
|
75
|
+
licenses:
|
|
76
|
+
- MIT
|
|
77
|
+
metadata: {}
|
|
78
|
+
post_install_message:
|
|
79
|
+
rdoc_options: []
|
|
80
|
+
require_paths:
|
|
81
|
+
- lib
|
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
83
|
+
requirements:
|
|
84
|
+
- - ">="
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
86
|
+
version: '0'
|
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
|
+
requirements:
|
|
89
|
+
- - ">="
|
|
90
|
+
- !ruby/object:Gem::Version
|
|
91
|
+
version: '0'
|
|
92
|
+
requirements: []
|
|
93
|
+
rubyforge_project:
|
|
94
|
+
rubygems_version: 2.6.14
|
|
95
|
+
signing_key:
|
|
96
|
+
specification_version: 3
|
|
97
|
+
summary: HubSpot Single Send API SDK for use with Ruby on Rails
|
|
98
|
+
test_files: []
|