As you’re probably aware, SendGrid is great at sending your email, but SendGrid can also help you process email using the Inbound Parse Webhook. The Inbound Parse Webhook processes all incoming email for a domain or subdomain, parses the contents and attachments of that email, then POSTs the multipart/form-data of the attachment and JSON-encoded content to the URL of your choosing.
To send an email to the application we use sendgrid services. Sendgrid provides different APIs for different purposes. For incoming email processing use inbound parse webhook API.
The API says that:
The Parse API will POST the parsed email to a URL that you specify.
Setup
To begin processing email using SendGrid’s Inbound Parse Webhook, you will have to setup MX Records, choose the hostname (or receiving domain) that will be receiving the emails you want to parse, and define the URL where you want to POST your parsed emails.
The following steps are required to begin parsing email:
- Point the MX Record of a Domain/Hostname or Subdomain to mx.sendgrid.net
- Associate the Domain/Hostname and the URL in the Parse API settings page.
To handle this incoming emails to the sendgrid in application we need an endpoint at application site which is Griddler Gem.
Griddler is a Rails engine that provides an endpoint for services that convert incoming emails to HTTP POST requests. It parses these POSTs and hands off a built email object to a class implemented by you.
Installation
-
Add griddler and an adapter gem to your application's Gemfile and then run bundle
install:gem 'griddler' gem 'griddler-sendgrid'
-
A route is needed for the endpoint which receives POST messages. To add the route, in config/routes.rb use the provided routing method mount_griddler. Examples:
config/routes.rb
# mount using default path: /email_processor
mount_griddler
Configuration Options
An initializer can be created to control some of the options in Griddler. In config/initializers/griddler.rb:
Griddler.configure do |config|
config.processor_class = EmailProcessor # CommentViaEmail
config.processor_method = :process # :create_comment (A method on CommentViaEmail)
config.reply_delimiter = '-- REPLY ABOVE THIS LINE --'
config.email_service = :sendgrid # :cloudmailin, :postmark, :mandrill, :mailgun
end
By default Griddler will look for a class named EmailProcessor. The class is initialized with a Griddler::Email instance
representing the incoming email, and has a process method to actually process the email. For example, in ./lib/email_processor.rb:
class EmailProcessor
def initialize(email)
@email = email
end
def process
user = User.find_by(email: @email.from[:email])
post_url_token = parse_post_url_token_from_response_email
begin
Post.find_by(url_token: post_url_token).
comments.create(user_id: user.id, comment: @email.body)
rescue StandardError => e
Rails.logger.error e.message
end
end
private
def parse_post_url_token_from_response_email
@email.to[0][:token].split('+').second
end
end
In above process method, we are creating a comment with the incoming email body as a comment to the post corresponding to the post-url-token inside the reply-to field shown in the below method. In this we were sending an E-mail to all other Users when any new Article is posted. So we added reply-to field to the mail so that other user can reply to that email.
def send_notification_on_new_post(users_list, post)
@post = Post.find(post["id"])
post_user = @post.user
user_name = post_user.name.titleize || post_user.email
headers "X-SMTPAPI" => {
"unique_args": {
"post_id": post.id
}
}.to_json
@subject = user_name + " posted a new article on KnowBuddy"
mail(
bcc: users_list,
subject: @subject,
reply_to: "reply+#{post.url_token}@#{KIPROSH_APP_DOMAIN}")
end
Now you are able to post a comment by replying to an email.
Griddler::Email attributes