Search code examples
rubyemailherokusinatrasendgrid

Sending email from a Sinatra web app using the Heroku SendGrid add-on


I'm trying to set up SendGrid to send email via a simple web form in a Sinatra app.

I have enabled the SendGrid add-on in Heroku, and checked the environment vars via heroku config; both SENDGRID_USERNAME and SENDGRID_PASSWORD are set.

I have also created a Sender Identity on the SendGrid website, which has been verified.

When I submit the form I get:

"550 Unauthenticated senders not allowed"

When I click the "Twilio SendGrid" add-on link on the Heroku dashboard, I'm forwarded to a page on the SendGrid website, which says:

Access to sendgrid.com was denied. You don't have authorisation to view this page. HTTP ERROR 403

Methods & settings for sending email are below:

post '/contact' do
 configure_options
 Pony.mail(
    :from => [params[:name], "<", params[:email], ">"].join,
    :to => '[email protected]',
    :subject =>  ["Opt-in via /contact: ", params[:name]].join,
    :body => [params[:name], params[:email]].join(": ")
  )
  redirect '/'
end

def configure_options
  Pony.options = {
    :via => :smtp,
    :via_options => {
      :address              => 'smtp.sendgrid.net',
      :port                 => '587',
      :domain               => 'heroku.com',
      :user_name            => ENV['SENDGRID_USERNAME'],
      :password             => ENV['SENDGRID_PASSWORD'],
      :authentication       => :plain,
      :enable_starttls_auto => true
    }
  }
end

Thanks!


Solution

  • SendGrid does not receive any mail so any requests you are making to SendGrid would be to send mail.

    This means that you first need to set up an entity you control, and which can act as a sender even if the recipient is yourself.

    You do this by creating a Sender Identity. This is the procedure when sending mail via SMTP:

    https://sendgrid.com/docs/for-developers/sending-email/integrating-with-the-smtp-api/

    Next, you need to crate an API key. SendGrid no longer supports basic authentication, so this code will not work:

      :user_name            => ENV['SENDGRID_USERNAME'],
      :password             => ENV['SENDGRID_PASSWORD'],
    

    Instead, you need to use:

      :user_name            => 'apikey',
      :password             => 'your-api-key',
    

    where 'apikey' is the literal string 'apikey', and 'your-api-key' is the 69-character API key generated by SendGrid (and shown only once).

    Then, in your POST method:

        post '/contact' do
         configure_options
         Pony.mail(
    
            # the :from field below is the email address 
            # associated with your SendGrid Sender Identity:
            :from => '[email protected]',
            :to => '[email protected]',
    
            :subject =>  ["Opt-in via /contact: ", params[:name]].join,
            :body => [params[:name], params[:email]].join(": ")
          )
          redirect '/'
        end