Based on your current .env file, you have:
vcq_TYSpAeWx3XR0BAZaDQ (approved!)You need to add your Google Ads Customer ID to your .env file.
623-323-9884 (your MCC ID).env:# Add this line to your .env file
GOOGLE_ADS_CUSTOMER_ID="623-323-9884"
Note: The API will automatically remove the dashes, so you can include them or not.
The Google Ads API requires OAuth 2.0 authentication. You need to authorize your application.
If you've already authorized Search Console, you might be able to reuse those credentials IF:
You'll need to set up an OAuth flow similar to Search Console:
Update OAuth Scope in Google Cloud Console:
https://www.googleapis.com/auth/adwordsCreate Authorization Route (following Search Console pattern):
# Add to config/routes.rb
namespace :admin do
namespace :oauth do
get 'authorize/google_ads', to: 'oauth#authorize_google_ads'
get 'callback/google_ads', to: 'oauth#callback_google_ads'
end
end
Update OAuth Controller (mirror Search Console implementation)
Authorize the Application:
oauth_credentials tableCreate and run this test script:
# test/verify_google_ads_credentials.rb
require_relative '../config/environment'
require 'google/ads/google_ads'
puts "=" * 60
puts "Google Ads API Credentials Verification"
puts "=" * 60
puts ""
# Check environment variables
puts "Checking environment variables..."
required_vars = %w[
GOOGLE_OAUTH_CLIENT_ID
GOOGLE_OAUTH_CLIENT_SECRET
GOOGLE_ADS_DEVELOPER_TOKEN
GOOGLE_ADS_CUSTOMER_ID
]
required_vars.each do |var|
value = ENV[var]
if value.present?
puts " โ #{var}: #{value[0..15]}..." # Show first 16 chars
else
puts " โ #{var}: MISSING!"
end
end
puts ""
puts "Checking OAuth credentials in database..."
oauth_cred = OauthCredential.for_provider_and_user(
provider: "google_ads",
user_id: "default"
)
if oauth_cred.persisted?
puts " โ OAuth record found"
puts " - Has refresh token: #{oauth_cred.refresh_token.present?}"
puts " - Token expires at: #{oauth_cred.expires_at}"
puts " - Is expired: #{oauth_cred.expired?}"
else
puts " โ No OAuth credentials found"
puts " โ You need to authorize at: /admin/oauth/authorize/google_ads"
end
puts ""
puts "=" * 60
Run it:
ruby test/verify_google_ads_credentials.rb
Once credentials are verified, test actual API access:
# test/test_google_ads_api_connection.rb
require_relative '../config/environment'
require 'google/ads/google_ads'
puts "=" * 60
puts "Google Ads API Connection Test"
puts "=" * 60
puts ""
begin
# Get OAuth credentials
oauth_cred = OauthCredential.for_provider_and_user(
provider: "google_ads",
user_id: "default"
)
unless oauth_cred.persisted? && oauth_cred.refresh_token.present?
puts "โ No OAuth credentials found!"
puts " โ Authorize at: /admin/oauth/authorize/google_ads"
exit 1
end
puts "Creating Google Ads client..."
client = Google::Ads::GoogleAds::GoogleAdsClient.new do |config|
config.client_id = ENV.fetch('GOOGLE_OAUTH_CLIENT_ID')
config.client_secret = ENV.fetch('GOOGLE_OAUTH_CLIENT_SECRET')
config.developer_token = ENV.fetch('GOOGLE_ADS_DEVELOPER_TOKEN')
config.refresh_token = oauth_cred.refresh_token
config.login_customer_id = ENV.fetch('GOOGLE_ADS_CUSTOMER_ID').delete('-')
end
puts "โ Client created successfully"
puts ""
# Test 1: List accessible customers
puts "Test 1: Listing accessible customer accounts..."
customer_service = client.service.customer
customer_id = ENV.fetch('GOOGLE_ADS_CUSTOMER_ID').delete('-')
query = <<~QUERY
SELECT
customer.id,
customer.descriptive_name,
customer.currency_code,
customer.time_zone
FROM customer
WHERE customer.id = #{customer_id}
QUERY
response = client.service.google_ads.search(
customer_id: customer_id,
query: query
)
if response.any?
puts "โ Successfully connected to Google Ads API!"
response.each do |row|
customer = row.customer
puts ""
puts " Account Details:"
puts " Customer ID: #{customer.id}"
puts " Name: #{customer.descriptive_name}"
puts " Currency: #{customer.currency_code}"
puts " Timezone: #{customer.time_zone}"
end
else
puts "โ No customer data returned"
end
puts ""
puts "Test 2: Fetching campaign data..."
query = <<~QUERY
SELECT
campaign.id,
campaign.name,
campaign.status,
campaign.advertising_channel_type
FROM campaign
ORDER BY campaign.name
LIMIT 5
QUERY
response = client.service.google_ads.search(
customer_id: customer_id,
query: query
)
if response.any?
puts "โ Successfully fetched campaign data!"
puts ""
puts " Your Campaigns:"
response.each do |row|
campaign = row.campaign
puts " - #{campaign.name} (#{campaign.status})"
puts " ID: #{campaign.id}"
puts " Type: #{campaign.advertising_channel_type}"
end
else
puts " โ No campaigns found (account might be empty)"
end
puts ""
puts "=" * 60
puts "โ
ALL TESTS PASSED!"
puts "=" * 60
rescue Google::Ads::GoogleAds::Errors::GoogleAdsError => e
puts ""
puts "=" * 60
puts "โ Google Ads API Error"
puts "=" * 60
puts ""
puts "Error: #{e.message}"
puts ""
e.failure.errors.each do |error|
puts "Error code: #{error.error_code.error_code}"
puts "Error message: #{error.message}"
puts ""
end
rescue => e
puts ""
puts "=" * 60
puts "โ Unexpected Error"
puts "=" * 60
puts ""
puts "#{e.class}: #{e.message}"
puts ""
puts e.backtrace.first(5)
end
Run it:
ruby test/test_google_ads_api_connection.rb
==============================================================
Google Ads API Connection Test
==============================================================
Creating Google Ads client...
โ Client created successfully
Test 1: Listing accessible customer accounts...
โ Successfully connected to Google Ads API!
Account Details:
Customer ID: 6233239884
Name: Quarry Rentals
Currency: USD
Timezone: America/Los_Angeles
Test 2: Fetching campaign data...
โ Successfully fetched campaign data!
Your Campaigns:
- LA Dumpster Rental - Search (ENABLED)
ID: 12345678901
Type: SEARCH
- OC Roll-Off Service (ENABLED)
ID: 12345678902
Type: SEARCH
==============================================================
โ
ALL TESTS PASSED!
==============================================================
Error: "AUTHENTICATION_ERROR - User doesn't have permission to access customer"
Error: "DEVELOPER_TOKEN_NOT_APPROVED"
Error: "INVALID_CUSTOMER_ID"
6233239884 not 623-323-9884).delete('-')Error: "No OAuth credentials found"
Once tests pass, you're ready to:
Run database migrations:
bin/rails db:migrate
Create the models, services, and controllers (as outlined in google_ads_implementation_guide.md)
Test data sync:
service = GoogleAdsService.new
result = service.sync_all(start_date: 7.days.ago, end_date: Date.yesterday)
puts result.inspect
Deploy to production with updated environment variables
Before deploying:
config/deploy.yml secretsYour Google Ads Credentials:
vcq_TYSpAeWx3XR0BAZaDQ623-323-9884API Scopes Required:
https://www.googleapis.com/auth/adwords (for Google Ads)Useful Links:
Need Help? If you encounter issues, check: