An Email Contact Form in Sinatra

In this ditty, I’m going to go through the steps needed to create a simple contact form page that sends you an email. This could easily be adapted for sending other types of emails through a web interface. In this tutorial I’m going to use my gmail account to send the email.

We are going to use Pony to send the emails, so first of all you’ll need to install the pony gem.

sudo gem install pony

To start with, we will put together the contact page form. This will be at the url /contact, the handler is easy:

get '/contact' do
  erb :contact
end

The view code looks like this in erb (this should be saved in your views directory as contact.erb):

<p>Please fill in the following form if you would like to contact us.</p>
<form action="/contact" method="post">
  <label for="name">Your Name:</label>
  <input type="text" name="name">
  <label for="email">Your email address:</label>
  <input type="text" name="email">
  <label for="to">Your message:</label>
  <textarea name="message" rows="16" cols="28">
  <input type="submit" value="Send">
</form>

Next we have to deal with the form once it has been posted. We will use a post handler for this with the same url /contact (because we specified this in the form’s action attribute above):

post '/contact' do 
    require 'pony'
    Pony.mail(
      :from => params[:name] + "<" + params[:email] + ">",
      :to => 'daz@gmail.com',
      :subject => params[:name] + " has contacted you",
      :body => params[:message],
      :port => '587',
      :via => :smtp,
      :via_options => { 
        :address              => 'smtp.gmail.com', 
        :port                 => '587', 
        :enable_starttls_auto => true, 
        :user_name            => 'daz', 
        :password             => 'p@55w0rd', 
        :authentication       => :plain, 
        :domain               => 'localhost.localdomain'
      })
    redirect '/success' 
end

Basically all this does is fill in the fields required for Pony and sends the email using your own gmail account (make sure you put your own details in!). If this all works out you will get an email with the title ‘Daz has contacted you’.At the end of the code, the user is redirected to a success page, so that needs adding too:

get('/success'){"Thanks for your email. We'll be in touch soon."}

Obviously you will probably want to have a nicer page than that simple plaintext message, but you get the idea.

Heroku

Heroku allows you to use the Sendgrid addon to send emails. You can sign up for a free account (up to 200 emails a day) using the following code:

heroku addons:add sendgrid:free

You have to change the settings for Pony to the following:

post '/contact' do 
    require 'pony'
     Pony.mail(
      :from => params[:name] + "<" + params[:email] + ">",
      :to => 'daz@gmail.com',
      :subject => params[:name] + " has contacted you",
      :body => params[:message],
      :port => '587',
      :via => :smtp,
      :via_options => { 
        :address              => 'smtp.sendgrid.net', 
        :port                 => '587', 
        :enable_starttls_auto => true, 
        :user_name            => ENV['SENDGRID_USERNAME'], 
        :password             => ENV['SENDGRID_PASSWORD'], 
        :authentication       => :plain, 
        :domain               => ENV['SENDGRID_DOMAIN']
      })
    redirect '/success' 
end

ENV['SENDGRID_USERNAME],ENV['SENDGRID_PASSWORD'] and ENV['SENDGRID_DOMAIN'] are all Heroku Environment variables and are automatically set when you install the Sendgrid addon.

In fact it makes sense to set these values separately using Sinatra’s set command:

set :email_username, ENV['SENDGRID_USERNAME'] ||
set :email_password, ENV['SENDGRID_PASSWORD'] ||
set :email_address, 'daz@gmail.com'
set :email_service, ENV['EMAIL_SERVICE'] || 'gmail.com'
set :email_domain, ENV['SENDGRID_DOMAIN'] || 'localhost.localdomain'

Note that EMAIL_SERVICE is not set automatically, so you will have to set that up using the following command:

heroku config:add EMAIL_SERVICE=sendgrid.net

You can now use the following code to send the contact form email using Pony:

post '/contact' do 
    require 'pony'
     Pony.mail(
      :from => params[:name] + "<" + params[:email] + ">",
      :to => settings.email_address,
      :subject => params[:name] + " has contacted you",
      :body => params[:message],
      :port => '587',
      :via => :smtp,
      :via_options => { 
        :address              => 'smtp.' + settings.email_service, 
        :port                 => '587', 
        :enable_starttls_auto => true, 
        :user_name            => settings.email_username, 
        :password             => settings.email_password, 
        :authentication       => :plain, 
        :domain               => settings.email_domain
      })
    redirect '/success' 
end

This allows you to use your contact form locally (using your own gmail account) or on Heroku (using Sendgrid).

I hope you found this ditty useful. Post any comments about how you get on and any other tips about email in Sinatra.

blog comments powered by Disqus