1

I've successfully built a controller in my Rails app that connects to the Constant Contact v3 API and adds the current user's email address to a list in Constant Contact. But, this only works if the user is logged in and triggers the process by clicking a link in the browser.

I can't figure out how to refactor this (with an after_create callback in the User model, for instance) or a background Job. I'd prefer for this to happen behind the scenes when a new user signs up. I'm following the OAuth2.0 Server Flow from the Constant Contact API docs.

Here's how it's currently working:

  1. User signs up and visits constant_contact#index page (/constant-contact) where they click a link to send my Constant Contact API Key to Constant Contact.
  2. Constant Contact responds with an authorization code to the redirect URL I've set up at constant_contact#callback (/constant-contact/callback)
  3. On my constant_contact#callback action I grab the authorization code from the params and use it to construct a JSON post that then sends the authorization code back to the Constant Contact API so that Constant Contact knows it's talking to the correct domain.
  4. Constant Contact then responds with a token back at my /constant-contact/callback url, and I can then use this token to interact with the Constant Contact API.

Here's the controller I'm using to do all of that (gist version if that's easier to read):

require 'oauth2'

class ConstantContactController < ApplicationController

  before_action :set_constant_contact

  def index

    # Build the authorization url to request the authorization code

    auth_request_base_url = "https://api.cc.email/v3/idfed"
    auth_url = auth_request_base_url + "?client_id=" + @client_id + "&scope=account_read+contact_data&response_type=code" + "&redirect_uri=" + @redirect_uri

    # Send the authorization url by clicking link. Could also use HTTParty.get(auth_url)

    @send_auth_url = auth_url

  end

  def callback

    # Receive the initial response from Constant Contact at /constant-contact

    auth_code = params[:code]
    @auth_code = auth_code

    # Now build the authorization code url that we'll use to request a token

    auth_code_base_url = "https://idfed.constantcontact.com/as/token.oauth2"
    auth_code_request_url = auth_code_base_url + '?code=' + auth_code + '&redirect_uri=' + @redirect_uri + '&grant_type=authorization_code&scope=contact_data'

    # Build the token request with the authorization code request url
    # First, set up the Header (make string of "API_KEY:SECRET")

    auth = @client_id + ':' + @secret

    # Base64 encode it

    credentials = Base64.strict_encode64(auth)

    # Build and set the Authorization header to use the encoded credentials

    authorization = "Basic " + credentials

    # Send the request for a token

    token_response = HTTParty.post("#{auth_code_request_url}",
      :headers => {
                 "Content-Type" => 'application/json',
                 "Authorization" => "#{authorization}"
                }
    )

    # Parse the token response

    token_body = JSON.parse(token_response.body)
    token = token_body["access_token"]
    token_auth = "Bearer " + token

    @account_summary = HTTParty.get("https://api.cc.email/v3/account/summary",
      :headers => {
                 "Accept" => 'application/json',
                 "Authorization" => "#{token_auth}"
                }
    )

    # Add the current user's email to Constant Contact list

    list_uuid = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"

    @successful_response = HTTParty.post("https://api.cc.email/v3/contacts/sign_up_form",
      :headers => {
                 'Content-Type' => 'application/json',
                 "Authorization" => "#{token_auth}",
              },
      :body => {
        "email_address": "#{current_user.email}",
        "list_memberships": [ "#{list_uuid}" ],
      }.to_json
    )

  end

  private

  def set_constant_contact
    # set the constant contact account
    if Rails.env == "development"
      @redirect_uri = "https://xxxxxxxxx.ngrok.io/constant-contact/callback"
    elsif Rails.env == "production" # => "production"
      @redirect_uri = "https://xxxxxxx.herokuapp.com/constant-contact/callback"
    end

    @client_id = Rails.application.credentials.dig(:constant_contact, :api_key)
    @secret  = Rails.application.credentials.dig(:constant_contact, :app_secret)
  end
end

Now all of that works manually in the browser, but how would I refactor it so it triggers a background job that does all of this automatically when the user signs up?

The Constant Contact account will never change. I just want to add new users to a specific list in my Constant Contact account when they sign up.

Lee McAlilly
  • 9,084
  • 12
  • 60
  • 94

0 Answers0