How to subscribe users to SendGrid’s marketing emails using Rails

Learn how to subscribe users to SendGrid's marketing emails using Rails. Step-by-step guide on creating a SendGrid account, installing the Ruby gem, configuring API key, creating a marketing list, base class, and subscribe background job. Easy integration of SendGrid into your Rails web application.

How to subscribe users to SendGrid’s marketing emails using Rails
How to subscribe users to SendGrid’s marketing emails using Rails

SendGrid is a well-known email delivery platform enabling businesses to send and manage their email campaigns and transactional emails easily. Its APIs make integrating with a Rails web application a breeze. This article will guide you through how to subscribe users to SendGrid’s marketing emails using Rails.

Step 1: Create a SendGrid account:

To get started, you need to create a SendGrid account. Depending on your requirements, you can sign up for a free account or choose a paid plan. Once you have created your account, you will have access to the SendGrid Dashboard where you can manage your email campaigns and monitor the performance of your emails.

Step 2: Install the SendGrid Ruby gem:

To integrate SendGrid with your Rails application, you need to install the SendGrid Ruby gem. You can add the following line to your Gemfile and run the bundle install command.

gem 'sendgrid-ruby'

Step 3: Configure the SendGrid API key:

Once you have installed the SendGrid Ruby gem, you must configure your SendGrid API key. You can find your API key in the SendGrid Dashboard under “Settings” -> “API Keys”. To configure your API key in your Rails application, you can create a secret in credentials by running the following command:

EDITOR="nano" bin/rails credentials:edit

Then add the following code to the file:

sendgrid:
  api_key: "YOUR_API_KEY"

Save the file once you have added your API key.

Step 4: Create a new marketing list:

In SendGrid, go to “Marketing” -> “Contacts” -> “Create” -> “New List”. Enter the name of your list and save it. Once the list is created, open it, and copy the LIST ID from the URL lists/LIST_ID. Save the LIST ID in your initializer file or your Ruby code.

Step 5: SendGrid base class:

To make it easier to use SendGrid for various purposes, such as sending transactional emails, subscribing, and unsubscribing, it’s recommended to create a base class in the lib folder. This class will contain the constant LIST_ID, where you can add your default list ID and methods to get the model class, SendGrid API key, and SendGrid instance.

# lib/sendgrid/base.rb
require 'sendgrid-ruby'

module Sendgrid
  # @note: This class is used to define the base class for SendGrid.
  class Base
    include SendGrid

    LIST_ID = "YOUR_LIST_ID"

    # @note: This method is used to get the model class.
    # @param [String] model The model name.
    # @return [Class] The model class.
    def model_class(model)
      model.constantize
    end

    # @note: This method is used to get the SendGrid API key.
    # @return [String] The SendGrid API key.
    def sendgrid_api_key
      @sendgrid_api_key ||= Rails.application.credentials.dig(:sendgrid, :api_key)
    end

    # @note: This method is used to get the SendGrid instance.
    # @return [SendGrid::API] The SendGrid instance.
    def sg_instance
      @sg_instance ||= SendGrid::API.new(api_key: sendgrid_api_key)
    end
  end

  class Error < StandardError; end
end

This class contains the constant of LIST_ID, where you can add your default list id.

model_class is used for multiple models like polymorphism, so we can use it for the user and other contact models.

Step 6: Sendgrid subscribe background job:

Now to the important stuff of actually subscribing a model instance to the marketing list:

# lib/sendgrid/subscribe.rb
module Sendgrid
  # @note: This class defines the class for SendGrid subscription.
  class Subscribe < Sendgrid::Base
    include ::Sidekiq::Worker
    sidekiq_options queue: :low, retry: 1

    # @note: This method subscribes a user to a list in SendGrid.
    # @param [String] model The model name.
    # @param [Integer] id The model id.
    # @param [String] list_id The list id.
    # @return [Array] Job ID.
    # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
    def perform(model, id, list_id = Sendgrid::Base::LIST_ID)
      return if Rails.env.test?

      record = model_class(model).find_by(id:)
      return unless record

      data = {
        list_ids: [list_id],
        contacts: [
          {
            email: record.email,
            first_name: record.name
          }
        ]
      }
      # https://docs.sendgrid.com/api-reference/contacts/add-or-update-a-contact
      response = sg_instance.client.marketing.contacts.put(request_body: data)
      Rails.logger.info "'Sendgrid::Subscribe' response: #{response.status_code} - #{response.body}"
      raise Sendgrid::Error, response.body if response.status_code != '202'

    end

    # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
  end
end

The perform method is the main method that subscribes a user to a list in SendGrid. It takes three arguments: model, id, and list_id. model is the name of the model, id is the model's id, and list_id is the id of the list to subscribe the user to. If list_id is not specified, the LIST_ID constant from the Sendgrid::Base class is used.

The method first checks if the current environment is the test environment and returns if it is. It then retrieves the record of the specified model with the specified id and returns if it is not found. If the record is found, the data is prepared with the email and name of the user and the list id. This data is then sent to SendGrid's API to subscribe the user to the specified list.

The response from the API is logged, and an error is raised if the status code is not 202, which indicates a successful subscription.

Step 7: Call the Subscribe Job:

To subscribe a user to the marketing list, a method subscribe_to_sendgrid should be added to the user model. This method calls the perform_async method from the Sendgrid::Subscribe class, passing the class name of the user model and its id as arguments.

Finally, this method can be called in the after_create callback, so whenever a new user is created, they will be automatically subscribed to the marketing list.

# @note: This method is used to subscribe the user to SendGrid.
# @return [void]
def subscribe_to_sendgrid
  Sendgrid::Subscribe.perform_async(self.class.to_s, id)
end

Happy Coding!

Contact me at sulman@hey.com