Home > OS >  Emails with SendGrid Web API in Rails
Emails with SendGrid Web API in Rails

Time:02-01

I'm following this tutorial: https://github.com/sendgrid/sendgrid-ruby/. Very straightforward. However, I want to avoid having a big chunk of code in my controller to send an email. It currently looks like this:

from = Email.new(email: '[email protected]')
to = Email.new(email: '[email protected]')
subject = 'Sending with SendGrid is Fun'
content = Content.new(type: 'text/plain', value: 'and easy to do anywhere, even with Ruby')
mail = Mail.new(from, subject, to, content)

sg = SendGrid::API.new(api_key: 'key')
response = sg.client.mail._('send').post(request_body: mail.to_json)

Ideally, I'd like to be able to trigger it from a service like: SendMail.new.perform() or some nice one-liner in the controller.

How would I abstract this code away from the controller and how would I call that new service/abstraction?

CodePudding user response:

Twilio SendGrid developer evangelist here.

You can absolutely extract that from your controller, this is normally described as a service object.

I like to keep service objects in the app folder. You can do so by creating the directory app/services. Then create a file for the class, app/services/email_service.rb for example. In that file add the code to send the email, maybe something like this:

class EmailService
  def self.call(from:, to:, subject:, content:)
    self.new.send_email(from: from, to: to, subject: subject, content: 
  end

  def initialize()
    @sendgrid = SendGrid::API.new(api_key: Rails.application.credentials.sendgrid)
  end

  def send_email(from:, to:, subject:, content:)
    from = Email.new(email: from)
    to = Email.new(email: to)
    content = Content.new(type: 'text/plain', value: content)
    mail = Mail.new(from, subject, to, content)
    response = @sendgrid.client.mail._('send').post(request_body: mail.to_json)
  end
end

You can then call this service from your controller with the one liner:

EmailService.call(from: "[email protected]", to: "[email protected]", subject: "My new email service", content: "It's pretty wonderful")

As a bonus, it's also easier to unit test the EmailService separate to the controller and to mock it out in controller tests.

CodePudding user response:

If you are using rails, you can define it in your environment file and use one line code to send email from your controller.

production.rb

  config.action_mailer.delivery_method = :sendmail
   # Defaults to:
   # config.action_mailer.sendmail_settings = {
   #   location: '/usr/sbin/sendmail',
   #   arguments: '-i'
   # }
   config.action_mailer.perform_deliveries = true
   config.action_mailer.raise_delivery_errors = true
   config.action_mailer.default_options = {from: '[email protected]'}

and in your controller

   mail( :to => @user.email,
    :subject => 'Thanks for signing up for our amazing app' )

best case for using sendmail is using it with an ActionMailer class. You can look it up at rails documentation.

  •  Tags:  
  • Related