How to identify mandrill webhook - ruby-on-rails

I have a Rails 4 application which sends emails using Mandrill. I am trying to detect weather a mail was opened or bounced, so I am using webhooks for this. I successfully receive the webhooks, but I can't tell which of them identify a particular email from my database.
I've tried using this
def send_message(email)
mail( from: ...,
to: ...,
subject: ...)
headers["X-MC-AutoHtml"] = "true"
headers["X-MC-Track"] = "opens"
headers['X-MC-MergeVars'] = { "id" => some_id }.to_json
end
but I'm not sure if I'm supposed to receive the X-MC-MergeVars back ( this is what I've understand from the docs)
Unfortunately, it's not working.
Do you have any ideas or an alternative solution? Thanks

I've figured it out by myself.
This is the line that needs to be there
headers['X-MC-Metadata'] = { "user_id" => user.id}.to_json
Here are the further details: http://help.mandrill.com/entries/21786413-Using-Custom-Message-Metadata
Hope it helps someone since it cost me several hours.

Related

The application goes offline when trying to send more than thousands of emails in Rails with AWS SES

I have implemented a platform using rails, and the goal is to send thousands of emails to customers with one click. The concept is that an email array runs each loop and inside each loop runs send email functionality like below.
#emails = ['abc#gmai.com', 'abc#example.com'] # More than 3 thousands
#emails.each do |email|
aws_email_sender(email, #email_subject, #email_body_html)
end
And the email function is like below:
def aws_email_sender(recipient, subject, htmlbody)
sender = "hello#example.com"
awsregion = "ap-west-1"
# The HTML body of the email.
htmlbodycontent = "#{htmlbody}"
# The email body for recipients with non-HTML email clients.
textbody = "This email was sent with Amazon SES using the AWS SDK for Ruby."
# Specify the text encoding scheme.
encoding = "UTF-8"
# Create a new SES resource and specify a region
ses = Aws::SES::Client.new(region: awsregion)
# Try to send the email.
begin
# Provide the contents of the email.
resp = ses.send_email({
destination: {
to_addresses: [recipient]
},
message: {
body: {
html: {
charset: encoding,
data: htmlbodycontent
},
text: {
charset: encoding,
data: textbody,
},
},
subject: {
charset: encoding,
data: subject,
},
},
source: sender,
});
# If something goes wrong, display an error message.
rescue Aws::SES::Errors::ServiceError => error
puts "Email not sent. Error message: #{error}"
end
end
The email is sending well by AWS but my rails application has gone down like
A timeout occurred, error code 524
I couldn't get the breaking point, why has my application gone down every time?
Thanks in Advance
If 524 is an HTTP status code then it means...
Cloudflare was able to make a TCP connection to the website behind them, but it did not reply with an HTTP response before the connection timed out.
Meaning your Rails app is behind a Cloudflare proxy. Cloudflare received an HTTP request, forwarded it to your app, waited around for your app to respond, but your app never did. A more detailed explanation can be found here.
Probably because it's trying to send emails to 3000 people one-by-one.
There's two strategies to fix this.
Use Bulk Email
Since the content of the email is the same for everyone, use an email template to send bulk email using the #send_bulk_templated_email method.
You can send to up to 50 addresses at a time, so use #each_slice to loop through emails in slices of 50.
This will be more efficient, but your app will still be waiting around for 3000/50 = 60 AWS API calls. At worst it will still time out. At best the user will be waiting around for a form submission.
Use A Background Job
Anytime your app needs to do something that might take a lot of time, like using a service or a large database query, consider putting it into a background job. The Rails app queues up a job to send the emails, and then it can respond to the web request while the mailing is handled in the background. This has other advantages: errors calling the service won't cause an error for the user, and failed jobs due to a temporary service outage can automatically be retried.
In Rails this is done with ActiveJob and you could write a job class to send your mail.
Use ActionMailer
However, Rails also offers a class specifically for sending email in the background: ActionMailer. You can have ActionMailer use AWS with the aws-sdk-rails gem.
config.action_mailer.delivery_method = :ses

shopify application charge failing to save

Below is my code for a Shopify one-time-application-charge in Ruby. I followed the shopify "add billing to your app" page (https://help.shopify.com/api/tutorials/adding-billing-to-your-app) for the code, except didn't need a recurring charge. I have also found someone else who posted their one-time-charge code which looks very similar to mine (https://ecommerce.shopify.com/c/shopify-apis-and-technology/t/one-time-application-charge-example-for-shopify-rails-app-489347).
def create_application_charge
application_charge = ShopifyAPI::ApplicationCharge.new(
name: "MyApp",
price: 0.09,
return_url: "https:\/\/myapp.herokuapp.com\/activatecharge",
test: true)
save = application_charge.save
if save
redirect application_charge.confirmation_url
return
end
flash[:error] = "The save worked: #{save}"
end
The flash always responds as false. Is there a failure at authentication that would prevent this? Or something to get the store to accept an application charge? I'm at a loss as to why this does not work.
Any help would be greatly appreciated, thank you.
The primary issue appears to be that the minimum charge you can request is $0.50, for which I wasn't meeting with my choice of using $0.09 for my test.

Mad Mimi Error when Trying to Send an e-mail to a list

I put this into my terminal
uri = URI('https://api.madmimi.com/mailer/to_list')
res = Net::HTTP.post_form(uri,'username'=>'test#example.com',
'api_key' => 'xxxxxx2ce1ac9eb91c75f5933283eb6c ', 'promotion_name' =>
'bulletin', 'subject' => 'Your Daily Bulletin Update', 'from' =>
'noreply#matsu-namibiaflood.opensciencedatacloud.org/', 'list_name' => 'bulletin')
The result was
#<Net::HTTPBadRequest 400 Bad Request readbody=true>
On the Mad Mimi API they talk about putting in your user name and API key https://madmimi.com/developer/mailer/methods
What am I doing wrong? Should I put the username and API key elsewhere?
James here from Mad Mimi, would you mind popping an email to us and I can have a look at your account and check the settings, list names and the promotion.
I would say remove the / at the end of the your "from" email and just check there are no spaces in your API key.
If that doesn't work, I would need to check the promotion but make sure there are no {placeholder} in your bull
Thank you,
James

Rails not sending (ical) attachments in emails

I'm trying to send an email with an ical attachment, I'm running rails v.3.2.13 and using the icalendar gem (to generate the ical string) see. (In development mode in case that might be a problem).
The relevant mailer code looks like this:
def mailme
ical = Icalendar::Calendar.new
...
attachments["meetings.ics"] = { mime_type: "text/calendar", content: ical.to_ical }
mail(from: email, to: recipient, ...)
end
there is also template file with the same name (mailme.html.erb)
The problem is the mail (html) is send without the attachment.
As usual any help would be much appreciated.
Thank you.
I've gotten them working with something like below:
mail.attachments['meeting.ics'] = { mime_type: 'application/ics',
content: ical.to_ical }
mail(from: email, to: recipient, ...)
So it's possible you need to call it on #attachments on the mail object instead of calling it on the current context. I'm not sure if your mime type needs to be application/ics, but that's worked fine for me in my systems.
In case someone else stumbles upon this.
If you are using delayed_job check out https://github.com/collectiveidea/delayed_job/wiki/Common-problems#wiki-Sending_emails_with_attachments
To fix this, remember to add this line to your mailer:
content_type "multipart/mixed"

Using Google's Audit API to monitor google apps email

I need to get some admin users using google apps gmail the ability to monitor their employees email. Have you used Google's Audit API to do this.
I wish there there was a way for the admins to just click a view my users email but that doesn't be the case.
If it matters the application is a rails app. The email is completely done on googles mail through google apps. Anyone that has done this any advice would be helpful.
Update! 500 points for this one!
I'm using ruby on rails hosting an app on heroku. The email is completely hosted with google apps standard, not business so we will have to upgrade, and the DNS is with zerigo which you already know if you use heroku.
Well, I hadn't planned on extending the gdata-ruby-util gem :), but here's some code that could be used for the Google Audit API based on Google's documentation. I only wrote a create_monitor_on method, but the rest are pretty easy to get.
Let me know if it works or needs any rewrites and I'll update it here:
class Audit < GData::Client::Base
attr_accessor :store_at
def initialize(options = {})
options[:clientlogin_service] ||= 'apps'
options[:authsub_scope] ||= 'https://apps-apis.google.com/a/feeds/compliance/audit/'
super(options)
end
def create_monitor_on(email_address)
user_name, domain_name = email_address.split('#')
entry = <<-EOF
<atom:entry xmlns:atom='http://www.w3.org/2005/Atom' xmlns:apps='http://schemas.google.com/apps/2006'>
<apps:property name='destUserName' value='#{#store_at}'/>
<apps:property name='beginDate' value=''/>
<apps:property name='endDate' value='2019-06-30 23:20'/>
<apps:property name='incomingEmailMonitorLevel' value='FULL_MESSAGE'/>
<apps:property name='outgoingEmailMonitorLevel' value='FULL_MESSAGE'/>
<apps:property name='draftMonitorLevel' value='FULL_MESSAGE'/>
<apps:property name='chatMonitorLevel' value='FULL_MESSAGE'/>
</atom:entry>
EOF
return true if post('https://apps-apis.google.com/a/feeds/compliance/audit/mail/monitor/'+domain_name+'/'+user_name, entry).status_code == 201
false
end
end
Then use it elsewhere like this:
auditor = Audit.new
auditor.store_at = 'this-username'
auditor.clientlogin(username, password)
render :success if auditor.create_monitor_on('email-address#my-domain.com')
My suggestion is to create one core email address that all the email monitors are sent to, so your admins' inboxes aren't slammed with everyone else's mail. Then in your Rails app, use Net::IMAP to download the messages you want from that master email account. i.e., you can create a link that says "View Joe's Email" and the method does something like this:
require 'net/imap'
imap = Net::IMAP.new('imap.gmail.com', 993, true)
imap.login('this-username#my-domain.com', password)
imap.select('INBOX')
messages = []
imap.search(["TO", "joe#email.com").each do |msg_id|
msg = imap.fetch(msg_id, "(UID RFC822.SIZE ENVELOPE BODY[TEXT])")[0]
body = msg.attr["BODY[TEXT]"]
env = imap.fetch(msg_id, "ENVELOPE")[0].attr["ENVELOPE"]
messages << {:subject => env.subject, :from => env.from[0].name, :body => body }
end
imap.logout
imap.disconnect
Then you can put those messages in your view -- or send them all in one bulk email, or whatever you want to do.

Resources