My app pipes incoming emails to the \incoming_emails route via a POST request from Sendgrid. From what I can gather, the POST request includes a params hash including including these fields:
params["to"]
params["from"]
params["subject"]
For testing, what's the best way to peruse the params hash? I could easily just use the logger to post the content of params, but how do I do that locally (I can easily send an email to myself on production, but not sure how to do that locally)? Is there a list of params for a regular email somewhere?
Create an email somewhere on the system (Desktop, easiest). Email format taken from Railscasts.
~/Desktop/email.eml
Date: Fri, 30 Dec 2011 14:00:00 -0800
From: foo#example.com
Subject: Mailman Test
To: support#example.com
This is a test email for use with Mailman.
Does this work?
Then use curl to send the email locally. Taken from this Stackoverflow question.
curl -X POST -d ~/Desktop/email.eml http://localhost:3000/incoming_emails
Related
I'm trying to send myself an email with the details of a post request received from a webhook
p = params.permit!
selfMailer.send_myself_an_email(p).deliver_later
However this only send me an email with the content:
{"controller"=>"custom/send", "action"=>"create"}
I tried to call .inspect on the params but not much changed, this is what I got:
"#<ActionController::Parameters {\"controller\"=>\"custom/send\", \"action\"=>\"create\"} permitted: true>"
In the log I can see clearly the parameters passed, there are many, but above is all I get! so how can I access them?
wow! I haven't thought about it, it seems that I made my app to redirect www.example.com to example.com, so basically when the webhook request arrived to the www url it was redirected, that's why I wasn't seeing the post params!
I just adjusted the webhook url by removing the www and now it's working
In my webapp I have instances where I want to let users send an email to their local representative. But I don't want to expose that user's email so I'd like to have the email sent from a_user_name#mydomain.com, where a_user_name is different depending on who sends it.
Where I'm lost is how to handle the situation where somebody replies to that email, and I need to deliver it to the original author. I'd like to be able to catch that email, look up the user in our database, and send them an email notifying them of the reply. How do I complete this last part?
Using Rails + Amazon SES
Thanks!
You can integrate with a transactional email provider like Mandrill (or others). There's various mandrill rails gems to help.
See: https://mandrill.zendesk.com/hc/en-us/articles/205583197-Inbound-Email-Processing-Overview
The inbound email gets picked up in a controller like:
class InboxController < ApplicationController
include Mandrill::Rails::WebHookProcessor
def handle_inbound(event_payload)
#parse event_payload and take appropriate action
end
end
You can then parse that email to get the sender validate it against your user table and pass the message on or whatever.
You probably want to set a subdomain of your domain or a totally separate domain so you can route your normal email traffic to your mydomain.com mailservers and pick up the emails to be parsed by rails / processed by the webhook from mail.mydomain.com or whatever.
you can use Base64.encode64
2.0.0-p481 :029 > encrypted_email=Base64.encode64('mike#gmail.com')
=> "bWlrZUBnbWFpbC5jb20=\n"
2.0.0-p481 :030 > Base64.decode64(encrypted_email)
=> "mike#gmail.com"
OR MessageEncryptor
2.0.0-p481 :037 > crypt = ActiveSupport::MessageEncryptor.new(Rails.configuration.secret_token)
=> #<ActiveSupport::MessageEncryptor:0xcd4d6fc #secret="c07692942cde247c96ea3da23a4d6406ebdad7c37f63c13e100731ce03ce24088dbe419da154fb7e504e777c60c7f6f8850d27f8cb8b7968602244ce5c21bfb3", #cipher="aes-256-cbc", #verifier=#<ActiveSupport::MessageVerifier:0xcd4d4e0 #secret="c07692942cde247c96ea3da23a4d6406ebdad7c37f63c13e100731ce03ce24088dbe419da154fb7e504e777c60c7f6f8850d27f8cb8b7968602244ce5c21bfb3", #digest="SHA1", #serializer=ActiveSupport::MessageEncryptor::NullSerializer>, #serializer=Marshal>
2.0.0-p481 :038 > encrypted_data = crypt.encrypt_and_sign('mike#gmail.com')
=> "UjF4VFRnRnF1RVJnZXhUUm1KakJZcDFMN1ZoZXVzSmFvLzUwdFkydXNjYz0tLTlsbFI3Vlo4RUNVK2pMZVEzS2tSOWc9PQ==--710d4fcdc202e1b1143e12661d8b40831525f158"
2.0.0-p481 :039 > decrypted_back = crypt.decrypt_and_verify(encrypted_data)
=> "mike#gmail.com"
So.you may use a dedicated table to store both encrypted and original emails and then use it in the FROM section of mail as well as to refer it for future use .So you must use a Generic email id that users can use to reply and then you may send this encrypted hidden field which will identify which email id was intended to send and again send to that email.
i know it would be a two way process like:-
Encrypt email in From part and use Generic email where users can reply back
Use hidden field containing encrypted mail
So,if the user replies back to the Generic mail,check the encrypted mail from hidden field and then again resend it to the decrypted email.
HOPE THIS HELPS.
I just learned/started using Sidekiq today to handle background processing of incoming email messages and attachments, but am a bit lost on the best way to get the email body and attachments into the worker for processing.
My RoR app is hosted on Heroku and receives incoming emails via Mailgun to a controller, which then kicks off my worker. Within the worker is a call to a 3rd party API to upload my email messages and attachments (think DropBox.)
Mailgun pre-parses everything and sends it over as parameters, but from what I understand about Sidekiq, I don't want to pass along entire objects such as the email body and/or attachments as shown here.
#attach_count = params["attachment-count"]
#from = params["from"]
#subject = params["subject"]
#msgbody = params["body-html"]
ProcessEmailWorker.perform_async(#id, #attach_count, #from, #subject, #msgbody)
What's the best practice for getting these items over to my worker?
I assume Mailgun is POSTing to your controller.
You can send the POST body as a single string parameter to Sidekiq and have it re-parse everything.
You can save the data to Redis or your database for processing in Sidekiq.
You can send the email content as a Hash of Strings:
{ 'subject' => ..., 'body' => ... }
After speaking with another developer I chose to do the following:
Set up a route in Mailgun to store the incoming email message, but to post a notification to my controller
Have my controller grab the incoming message ID and pass that along to my worker
From within my worker, use the message ID to perform a GET to Mailgun to retrieve the stored message (and its attachments)
Process the message/attachments and upload them to my cloud storage provider.
I will be sending bulk emails from a Rails app and plan on using SendGrid. I am assuming that it is best to send a separate email to each recipient (as opposed to using BCC for all the recipients). If that is true, should I be using something like DelayedJob to queue the messages going over to SendGrid, or would it be safe to throw 500 messages at it all at once? Thanks!
500 messages really isn't that much to SendGrid. It's not even a blip on their radar. I worked for a company that sent out 2.7 million emails in a single month, and even then it's only just a blip.
With the SendGrid API's capabilities, you wouldn't be sending out 500 emails, you would send one email which has a specific SendGrid API header set. Why? Because have you ever tried to send 500 individual email messages and timed how long that takes? How about a single email? The single email's going to be quicker.
The SendGrid API has a Ruby example which is here:
https://sendgrid.com/docs/Integrate/Code_Examples/SMTP_API_Header_Examples/ruby.html.
That's quite long winded and messy, so let me simplify it for you. Basically, you set this in your email:
headers["X-SMTPAPI"] = { :to => array_of_recipients }.to_json
SendGrid will then parse this and then send that one email you sent it out to that array of recipients. I seem to recall that they ask you to limit this to about 1000 recipients per email, so it would be wise to split it up over multiple emails if you wanted that. That is when you would bring in something like the delayed_job or resque gems to deal with it.
Oh, and by the way you'll still need to specify a to address for this email just to make the Mail gem happy. We had info#ourcompany.com for that.
The SendGrid API will also support filters in their emails, so you can have placeholder strings such as {{ firstname }} and, assuming you send it through with the SMTPAPI header, it will do the "mail merge" on the email and customize them.
It would do you a great deal of good if you read the SendGrid API documentation. It's really useful and what they provide is super powerful.
I recommend using the sendgrid gem ( https://github.com/stephenb/sendgrid ) as it simplifies your calling code.
Here's an example rails 3 action mailer example:
class UserAnnouncementMailer < ActionMailer::Base
include SendGrid
default reply_to: "test#test.com", return_path: "test#test.com", from: "Test"
# bulk emailer
# params - opts a hash of
# emails: array of emails
#
def notice(opts={})
raise "email is nil" unless opts[:emails]
sendgrid_category :use_subject_lines
sendgrid_recipients opts[:emails]
name = "The Man"
to = "test#test.com"
from_name = "#{name} <theman#test.com>"
subject = "Important"
mail({from: from_name, to: to, subject: subject})
end
end
And the corresponding calling code. It's recommended to have the emails array to be < 1000 emails.
emails = ["alice#test.com", "bob#test.com"]
UserAnnouncementMailer.notice({:emails => emails}).deliver
See the sendgrid gem github readme for more details.
Delayed Job and SendGrid sound like the best option from what you say, but have you considered using one of the campaign mailers like Mailchimp instead? If you're sending out a lot of mails that are basically the same, they'll let you setup and campaign template and then fire a CSV of all the variables at it. They then effectively mail merge and fire them all out.
If however, you're only talking a few hundred you're on the right lines. SendGrid can easily handle the load, and you want to use Delayed Job so that you're not impacted by the performance of the SendGrid API should it not be favorable. Alternatively, look at Resque instead for sending mail as it may be more efficient.
I would imagine SendGrid can handle that kind of load. Most relay systems can. Also I would imagine if you sent the 500 in a CC API call, that their system would parse it and send them individually. I use Elastic Email (http://elasticemail.com) - and I know that this is how they handle it and it works great.
This is how I've done it in Rails 4
class NewsMailer < ApplicationMailer
include SendGrid
sendgrid_category :use_subject_lines
default from: 'My App! <support#myapp.com>'
def mass_mailer(news)
# Pass it in template
#news = news
# Custom method to get me an array of emails ['user1#email.com', 'user2#email.com',...]
array_of_emails = #news.recipients.pluck(:email)
# You can still use
# headers["X-SMTPAPI"] = { :to => array_of_emails }.to_json
sendgrid_recipients array_of_emails
mail to: 'this.will.be.ignored#ignore.me', subject: 'Weekly news'
end
end
I'm building a registration flow that allows a user to FB Connect to pre-populate the registration form. I'm also then capturing fb_uuid and fb_access_token.
When the user submits the registration form that is submitted as follows:
Started POST "/users" for 127.0.0.1 at Mon Jul 11 17:44:40 -0700 2011
Processing by Devise::RegistrationsController#create as HTML
Parameters: {"commit"=>"Create my account", "fb_access_token"=>"XXXXXXXXXXX", "authenticity_token"=>"XXXXXXXXXX", "utf8"=>"✓", "user"=>{"remember_me"=>"0", "lname"=>"NNNNNN", "fname"=>"BBBBBB", "password"=>"[FILTERED]", "email"=>"dadad#google.com"}, "fb_uuid"=>"50123190"}
notice the fb_access_token, fb_uuid
In the Registration#Create, how can I capture those values and populate the Authentications table? Do I have to override devise?
Thansk
Although you may not need this right now, here's a blog post that you can use to solver your problem:
Devise on rails: Prepopulating form data
You can use the method described there to capture and process the data you need.
Hope it helps.
You can use the koala gem to pull those fb parameters from the facebook cookie after the user does a FB_Connect. Take a look at this:
https://github.com/arsduo/koala/wiki/Koala-on-Rails
I'm curious on why you aren't creating the user right after the FB_Connect which is the more common and intuitive user experience, as opposed to just prepoulating the registration form.
Like this:
https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview