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:
- 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. - Constant Contact responds with an authorization code to the redirect URL I've set up at
constant_contact#callback
(/constant-contact/callback) - 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. - 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.