I'm new to Google APIs so My question deals with creating an AWS lambda python integration that will call Google Campaign Manager 360 DFA Reporting scope. It will take the report data and place it in an AWS S3 bucket for SA analysts to run BI and Qlik reports (I am not on Google Workspace so I can't do delegations).
Since this is an integration app calling a service, I decided to use Service Account because its used for server-to-server interactions.
I'm not sure what to do at this point and what could be wrong. Thanks much for your help. Let me know if you need any more images like my service account setup.
Here is my error message and code for the lambda python integration where execution fails at line 20 (I would expect an issue with OAuth2.0 credentials but not with Service Account. I'm new to all of this) :
import json
import os
from google.oauth2 import service_account
from googleapiclient.discovery import build
import googleapiclient.discovery
SCOPES = ['https://www.googleapis.com/auth/dfareporting', 'https://www.googleapis.com/auth/ddmconversions']
delegate = os.environ['DELEGATE_EMAIL']
profile_id = os.environ['PROFILEID']
def lambda_handler(event, context):
SERVICE_ACCOUNT_FILE = 'service.json'
print(SERVICE_ACCOUNT_FILE)
# Implement Credentials objects from the service account and scopes
credentials = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
print('<< CREDENTIAL >> ', credentials)
#delegated_credentials = credentials.with_subject(delegate)
gcm360_client = build('dfareporting', 'v4', credentials=credentials)
request =gcm360_client.campaigns().list(profileId=profile_id)
print('<< REQUEST >> ',request)
response = request.execute()
#print('<< RESPONSE >> ',response)
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
When I test ran it, I got the following
Error on Http.Request
Solved! Go to Solution.
After unsuccessfully trying to use the Service Account method, I had to use a mostly non-Google Rest-based alternative that incorporates some Google.
@Tonanate wrote:I'm new to Google APIs so My question deals with creating an AWS lambda python integration that will call Google Campaign Manager 360 DFA Reporting scope. It will take the report data and place it in an AWS S3 bucket for SA analysts to run BI and Qlik reports (I am not on Google Workspace so I can't do delegations).
Since this is an integration app calling a service, I decided to use Service Account because its used for server-to-server interactions.
- I Set up Service Account giving my self owner privileges and the account has user privileges.
- Copied the service account Json file to be used by Python and Google API.
I'm not sure what to do at this point and what could be wrong. Thanks much for your help. Let me know if you need any more images like my service account setup.
Here is my error message and code for the lambda python integration where execution fails at line 20 (I would expect an issue with OAuth2.0 credentials but not with Service Account. I'm new to all of this) :
{"error": {"code": 403,"message": "Request had insufficient authentication scopes.","errors": [{"message": "Insufficient Permission","domain": "global","reason": "insufficientPermissions"}],"status": "PERMISSION_DENIED","details": [{"@type": "type.googleapis.com/google.rpc.ErrorInfo","reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT","domain": "googleapis.com","metadata": {"service": "dfareporting.googleapis.com","method": "google.ads.xfa.dfareporting.op.v4.DfareportingCampaigns.List"}}]}}
import json
import os
from google.oauth2 import service_account
from googleapiclient.discovery import build
import googleapiclient.discovery
SCOPES = ['https://www.googleapis.com/auth/dfareporting', 'https://www.googleapis.com/auth/ddmconversions']
delegate = os.environ['DELEGATE_EMAIL']
profile_id = os.environ['PROFILEID']
def lambda_handler(event, context):
SERVICE_ACCOUNT_FILE = 'service.json'
print(SERVICE_ACCOUNT_FILE)
# Implement Credentials objects from the service account and scopes
credentials = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
print('<< CREDENTIAL >> ', credentials)
#delegated_credentials = credentials.with_subject(delegate)
gcm360_client = build('dfareporting', 'v4', credentials=credentials)
request =gcm360_client.campaigns().list(profileId=profile_id)
print('<< REQUEST >> ',request)
response = request.execute()
#print('<< RESPONSE >> ',response)
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
When I test ran it, I got the following
Error on Http.Request
I was able to pull data using a get request and load that data into an S3 bucket using the google API urls for Campaign Manager 360. However, I had to constantly use Postman to give me an access token. This code is going to run daily and I need to have a way to generate them for my Service Account.
Now, I need to generate tokens for my Service Account. So we requested from our client to give us domain-wide delegation to run this. I know that Google indicates that there are three approaches but the other 2 are the least desirable at this point.
It seems to use info from the Google Page here:
https://developers.google.com/identity/protocols/oauth2/service-account#jwt-auth
Hi there,
Based on the errors you referenced, the issue you're facing seems to be related to the authentication process using the Google Cloud service account. Here are a few things you can check and adjust in your code:
Verify the Service Account JSON File: Double-check that the service.json
file is correctly located in the same directory as your Python script. Confirm the file name and extension are accurate.
Check Environment Variables: Ensure that the DELEGATE_EMAIL
and PROFILEID
environment variables are correctly set and accessible within your Lambda function. Make sure they match the expected values for the delegate email and profile ID you want to use.
Adjust the SCOPES: Verify that the scopes you have specified (https://www.googleapis.com/auth/dfareporting
and https://www.googleapis.com/auth/ddmconversions
) are appropriate for your use case. Make sure they align with the permissions you have set for your service account.
Delegate Access (Optional): If you don't have access to delegate permissions within Google Workspace, you can remove the line related to delegated credentials (delegated_credentials = credentials.with_subject(delegate)
).
Enable Required APIs: Ensure that you have enabled the required APIs (Campaign Manager 360 and DDM Conversions) in the Google Cloud Console. This step is necessary for accessing the respective services.
Handle Dependencies: Make sure you have the necessary dependencies installed for the google.oauth2
and googleapiclient.discovery
modules. You can include them in your Lambda deployment package or use a package management system like pip
to manage dependencies.
Error Logging: Consider adding error logging statements to capture any potential exceptions or error messages. This can help you identify the specific issue causing the execution failure.
By checking and adjusting these aspects, you can troubleshoot and determine the root cause of the issue you're facing with the authentication and service account setup.
HI Roderick_G. Thanks for the response. I did find out something after
performing these checks:
1. I verified that the service.json file was located in the same
directory as my python script.
2. I checked my environment variables but I really don;t need the
Delegete_Email variable because I don't have delegate access.
3. The Delegate Access statement was already commented out.
4. I made sure that the scopes are all enabled because both of the two
mentioned are under the campaigns 360 API for campaigns method.
5. I tested the Profile ID when testing the Google Explorer for the
desired APIs for listing campaigns and that brought in data.
6. I should have all the google-api-python-client libraries available.
Here's what I did to see if I could verify accessing my scopes:
1. Set them to "readonly" (https://
www.googleapis.com/auth/dfareporting.readonly)
2. Reran the script and verified that I now saw this error:
"errorMessage": "('No access token in response.', {'id_token':
'eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg1YmE5MzEzZ.......'})",
"errorType": "*RefreshError*",
Q) Could it be that the server was trying to refresh the token and failed?
Q) Is there something that I'm missing concerning refreshing of tokens for
Google Service Accounts or has my current code accounted for that but I may
be missing something logically?
Thanks
After unsuccessfully trying to use the Service Account method, I had to use a mostly non-Google Rest-based alternative that incorporates some Google.
@Tonanate wrote:I'm new to Google APIs so My question deals with creating an AWS lambda python integration that will call Google Campaign Manager 360 DFA Reporting scope. It will take the report data and place it in an AWS S3 bucket for SA analysts to run BI and Qlik reports (I am not on Google Workspace so I can't do delegations).
Since this is an integration app calling a service, I decided to use Service Account because its used for server-to-server interactions.
- I Set up Service Account giving my self owner privileges and the account has user privileges.
- Copied the service account Json file to be used by Python and Google API.
I'm not sure what to do at this point and what could be wrong. Thanks much for your help. Let me know if you need any more images like my service account setup.
Here is my error message and code for the lambda python integration where execution fails at line 20 (I would expect an issue with OAuth2.0 credentials but not with Service Account. I'm new to all of this) :
{"error": {"code": 403,"message": "Request had insufficient authentication scopes.","errors": [{"message": "Insufficient Permission","domain": "global","reason": "insufficientPermissions"}],"status": "PERMISSION_DENIED","details": [{"@type": "type.googleapis.com/google.rpc.ErrorInfo","reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT","domain": "googleapis.com","metadata": {"service": "dfareporting.googleapis.com","method": "google.ads.xfa.dfareporting.op.v4.DfareportingCampaigns.List"}}]}}
import json
import os
from google.oauth2 import service_account
from googleapiclient.discovery import build
import googleapiclient.discovery
SCOPES = ['https://www.googleapis.com/auth/dfareporting', 'https://www.googleapis.com/auth/ddmconversions']
delegate = os.environ['DELEGATE_EMAIL']
profile_id = os.environ['PROFILEID']
def lambda_handler(event, context):
SERVICE_ACCOUNT_FILE = 'service.json'
print(SERVICE_ACCOUNT_FILE)
# Implement Credentials objects from the service account and scopes
credentials = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
print('<< CREDENTIAL >> ', credentials)
#delegated_credentials = credentials.with_subject(delegate)
gcm360_client = build('dfareporting', 'v4', credentials=credentials)
request =gcm360_client.campaigns().list(profileId=profile_id)
print('<< REQUEST >> ',request)
response = request.execute()
#print('<< RESPONSE >> ',response)
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
When I test ran it, I got the following
Error on Http.Request
I was able to pull data using a get request and load that data into an S3 bucket using the google API urls for Campaign Manager 360. However, I had to constantly use Postman to give me an access token. This code is going to run daily and I need to have a way to generate them for my Service Account.
Now, I need to generate tokens for my Service Account. So we requested from our client to give us domain-wide delegation to run this. I know that Google indicates that there are three approaches but the other 2 are the least desirable at this point.
It seems to use info from the Google Page here:
https://developers.google.com/identity/protocols/oauth2/service-account#jwt-auth
Hi @Tonanate It looks like you're on the right track with setting up your AWS Lambda function to call the Campaign Manager 360 API using a service account. The error you're encountering, "Request had insufficient authentication scopes", indicates that your service account lacks the necessary permissions to access the Campaign Manager 360 API.
Here's how you can resolve this issue:
Verify Scopes:
Service Account Permissions:
Delegate Account (Optional):
Testing:
Additional Suggestion:
If you find the integration process challenging or if you'd like a more streamlined way to access and analyze your marketing data, you might want to consider using a tool like Windsor.ai. It simplifies the process of aggregating data from multiple sources, including Campaign Manager 360, and could save you time on complex integrations.
Hope this helps!