hubspot-mailer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,8 @@
1
+ require 'action_mailer'
2
+ require 'hubspot-ruby'
3
+ require 'hubspot/mailer/delivery'
4
+ require 'hubspot/mailer/exceptions'
5
+ require 'hubspot/mailer/hubspot_preview_interceptor'
6
+ require 'hubspot/mailer/message'
7
+ require 'hubspot/mailer'
8
+
@@ -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
@@ -0,0 +1,10 @@
1
+ module Hubspot
2
+ class Mailer < ActionMailer::Base
3
+ class Message < Mail::Message
4
+ attr_accessor :email_id
5
+ attr_accessor :send_id
6
+ attr_accessor :contact_properties
7
+ attr_accessor :custom_properties
8
+ end
9
+ end
10
+ 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: []