How can I get a response from Sparkpost?
bajalovic opened this issue · 12 comments
After I send an email using:
result = MyMailer.some_message(some_var).deliver!
how can I get this response?
{"total_rejected_recipients"=>0, "total_accepted_recipients"=>1, "id"=>"00000000000000"}
The result
variable is an instance of Mail::Message
, so I can not get these values from that.
I need an id
as I am using webhooks to track delivery, opens/clicks and so on...
Greetings @bajalovic!
Are you able to send the contents of your MyMailer#some_message method?
Basically I have some business logic and at the end:
sparkpost_options = {substitution_data: merge_vars, api_key: api_key}
result = mail(to: to_email,
from: "#{from_name} <#{from_email}>",
subject: subject,
body: message,
date: schedule_at,
sparkpost_data: sparkpost_options)
Out of curiosity, did you set up the ActionMailer's delivery_method to use:sparkpost
, as exampled by https://github.com/the-refinery/sparkpost_rails#getting-started ?
The reason I ask is because I was able to kinda replicate what you're doing by sending a non-SparkPost delivery method message (such as using ActionMailer through Google Mail) using roughly the same Mailer code as you. The result for me when using a non-SparkPost delivery method was that #deliver!
(and variants such as #deliver_now!
) method returned a Mail::Message
instead of a hash when the message was successfully delivered through Google Mail.
@BradyBonnette
I did setup delivery_method to use :sparkpost
Are you setting the delivery_method in all relevant config/environments/*.rb files? For example, if you have delivery_method set to :sparkpost
in config/environments/production.rb, and you don't have it set in config/environments/development.rb, and you're currently testing your Mailer code out in development, then the SparkPost backend would not get picked up.
I have this setup in development.rb
:
config.action_mailer.delivery_method = :sparkpost
In your MyMailer#some_message method, what happens if you try this:
sparkpost_options = {substitution_data: merge_vars, api_key: api_key}
result = mail(to: to_email,
from: "#{from_name} <#{from_email}>",
subject: subject,
body: message,
date: schedule_at,
sparkpost_data: sparkpost_options,
delivery_method: :sparkpost)
Note the last option for delivery_method: :sparkpost
.
@BradyBonnette result is still an instance of Mail::Message
This is the result from puts result.inspect
#<Mail::Message:70095412235940, Multipart: false, Headers: <Date: Wed, 20 Jul 2016 22:26:17 +0000> .........
What was the return value of #deliver! being called on that new result where you supplied the delivery_method: :sparkpost
option to #mail?
In other words, did the result of MyMailer.some_message(some_var).deliver!
change when you supplied the delivery_method
option?
EDIT: Oh, I think I got confused. when you say puts result.inspect
, are you referring to the result coming from result = mail(to: ...)
, or are you referring to the result coming from MyMailer.some_message(some_var).deliver!
This might be related: There are different behaviors when calling deliver_now!
/deliver!
vs deliver_now
/deliver
. deliver_now!
and deliver!
will return the response, while deliver_now
and deliver
will return the Mail::Message
instance.
I tracked it down to a difference in how the mail
gem supports the return_response
option (it's honored when calling deliver!
but ignored for calls to deliver
).
A potential workaround if you need to use the deliver
/deliver_now
option would be to retrieve the response by calling mail.delivery_method.response
. Something like this:
mail = MyMailer.some_message(some_var)
mail.deliver_now
result = mail.delivery_method.response
Thanks for that insight! I checked it out in my test environment, and sure enough you are right.
Using #deliver
/ #deliver_now
, I saw:
2.1.5 :001 > message = MyMailer.send_test.deliver
DEPRECATION WARNING: `#deliver` is deprecated and will be removed in Rails 5. Use `#deliver_now` to deliver immediately or `#deliver_later` to deliver through Active Job. (called from irb_binding at (irb):1)
Rendered text template (0.0ms)
MyMailer#send_test: processed outbound mail in 3373.3ms
Sent mail to <redacted> (473.0ms)
Date: Fri, 22 Jul 2016 10:17:22 -0400
From: from@example.com
To: <redacted>
Message-ID: <57922af2e1a84_328ddd72f095cc@redacted.mail>
Subject: Send test
Mime-Version: 1.0
Content-Type: text/plain;
charset=UTF-8
Content-Transfer-Encoding: 7bit
sparkpost-data: {:template_id=>"my-first-email"}
=> #<Mail::Message:55283580, Multipart: false, Headers: <Date: Fri, 22 Jul 2016 10:17:22 -0400>, <From: from@example.com>, <To: redacted>, <Message-ID: <57922af2e1a84_328ddd72f095cc@redacted.mail>>, <Subject: Send test>, <Mime-Version: 1.0>, <Content-Type: text/plain>, <Content-Transfer-Encoding: 7bit>, <sparkpost-data: {:template_id=>"my-first-email"}>>
2.1.5 :002 >
2.1.5 :022 > message.delivery_method.response
=> {"total_rejected_recipients"=>0, "total_accepted_recipients"=>1, "id"=>"48352743735133856"}
2.1.5 :023 >
Using #deliver!
/ #deliver_now!
, I saw:
2.1.5 :036 > message = MyMailer.send_test.deliver!
DEPRECATION WARNING: `#deliver!` is deprecated and will be removed in Rails 5. Use `#deliver_now!` to deliver immediately or `#deliver_later!` to deliver through Active Job. (called from irb_binding at (irb):36)
Rendered text template (0.0ms)
MyMailer#send_test: processed outbound mail in 1611.0ms
=> {"total_rejected_recipients"=>0, "total_accepted_recipients"=>1, "id"=>"48352743735165983"}
2.1.5 :037 >
This is really good to know. The only thing that is still confusing me is that @bajalovic is using #deliver!
and still getting a Mail::Message
returned from his Mailer method.
Ah i tested and tested and then noticed a problem.
The json
{"total_rejected_recipients"=>0, "total_accepted_recipients"=>1, "id"=>"48352743735165983"}
is the result of deliver_now!
method and not the result of mail()
method (if you see my first comment, i expected that mail
method returns a json, but it always returns a Mail::Message
object instance.
I had to refactor a so to expect the result json not inside a mailer, and it is working fine.
Thank you both @BradyBonnette and @petesharum for your efforts.