Google Ads API Authentication using service account

1,844 views
Skip to first unread message

Phil Lachmann

unread,
Feb 19, 2021, 10:18:59 AM2/19/21
to AdWords API and Google Ads API Forum
I am creating an Azure function (C# using dotnet core 3.1) that will call the Google Ads API. Since this application has no UI I believe that I need to use a service account to authenticate.

The code runs and returns an error "authenticationError": "NOT_ADS_USER"

The login that I used to create the service account is a google ads user in the ads portal with a role of Admin.

The developer token used has basic access and the manager account is linked to the customers account.

The full code and error message is listed below.
What am I missing?

GoogleAdsConfig config = new GoogleAdsConfig()
            {
           OAuth2Mode = Google.Ads.GoogleAds.Config.OAuth2Flow.SERVICE_ACCOUNT,
           OAuth2SecretsJsonPath = pathtojsonfile,
           OAuth2PrnEmail = "some...@somethingelse.iam.gserviceaccount.com",
           OAuth2Scope = "https://www.googleapis.com/auth/adwords",
           DeveloperToken = "********"
        };
        
        var responseMessage = "";
        var client = new GoogleAdsClient(config);
        

        // Get the GoogleAdsService.
        GoogleAdsServiceClient googleAdsService = client.GetService(Services.V6.GoogleAdsService);

        // Create the query.
        string query =
            @"SELECT
             campaign.id,
             campaign.name,
             ad_group.id,
             ad_group.name,
             ad_group_criterion.criterion_id,
             ad_group_criterion.keyword.text,
             ad_group_criterion.keyword.match_type,
             metrics.impressions,
             metrics.clicks,
             metrics.cost_micros
         FROM keyword_view
         WHERE segments.date DURING LAST_7_DAYS
             AND campaign.advertising_channel_type = 'SEARCH'
             AND ad_group.status = 'ENABLED'
             AND ad_group_criterion.status IN ('ENABLED','PAUSED')
         ORDER BY metrics.impressions DESC
         LIMIT 50";

        try
        {
            // Issue a search request.
            await googleAdsService.SearchStreamAsync(customerId.ToString(), query,
                delegate (SearchGoogleAdsStreamResponse resp)
                {
                    // Display the results.
                    foreach (GoogleAdsRow criterionRow in resp.Results)
                    {
                        responseMessage +=
                            "Keyword with text " +
                            $"'{criterionRow.AdGroupCriterion.Keyword.Text}', match type " +
                            $"'{criterionRow.AdGroupCriterion.Keyword.MatchType}' and ID " +
                            $"{criterionRow.AdGroupCriterion.CriterionId} in ad group " +
                            $"'{criterionRow.AdGroup.Name}' with ID " +
                            $"{criterionRow.AdGroup.Id} in campaign " +
                            $"'{criterionRow.Campaign.Name}' with ID " +
                            $"{criterionRow.Campaign.Id} had " +
                            $"{criterionRow.Metrics.Impressions.ToString()} impressions, " +
                            $"{criterionRow.Metrics.Clicks} clicks, and " +
                            $"{criterionRow.Metrics.CostMicros} cost (in micros) during the " +
                            "last 7 days.";
                    }
                }
            );
        }
        catch (GoogleAdsException e)
        {
            responseMessage += "Failure:\n";
            responseMessage += $"Message: {e.Message}\n";
            responseMessage += $"Failure: {e.Failure}\n";
            responseMessage += $"Request ID: {e.RequestId}\n";
            throw;
        }

        return responseMessage;

------------------------------------------------------------------
{  
  "StatusCode": 16,  
  "Details": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",  
  "RequestId": "0Yk2OYrUATjwftZ5I0qi2g",  
  "Failure": {  
    "errors": [  
      {  
        "errorCode": {  
          "authenticationError": "NOT_ADS_USER"  
        },  
        "message": "User in the cookie is not a valid Ads user."  
      }  
    ]  
  }  
}  




Google Ads API Forum Advisor Prod

unread,
Feb 21, 2021, 9:47:56 PM2/21/21
to phil.l...@ingagepartners.com, adwor...@googlegroups.com
Hi Phil,

Thanks for posting your concern.

Could you confirm if you already followed the instruction discussed on this document especially the prerequisite about using a G Suite domain that you own? If yes and the issue still persists, then could you provide the following details via Reply privately to author option to further investigate?
  • User account / email address that you've used in setting up service account through API
  • Customer ID
  • Complete  request and response logs with request ID generated on your end where we can see the issue

If you haven't enabled the logging of the API transactions for the specific client library that you are using, then please refer to the guide below:
.Net - https://developers.google.com/google-ads/api/docs/client-libs/dotnet/logging

Regards,
Google Logo
Ernie John Blanca Tacata
Google Ads API Team
 


ref:_00D1U1174p._5004Q2CSvqt:ref

Phil Lachmann

unread,
Feb 26, 2021, 4:11:45 PM2/26/21
to AdWords API and Google Ads API Forum
Hello.

I have followed all instructions "discussed on this document " and I still have the same error.

I don't have access to the 'Reply to Author' option. ("You do not have permission to reply to author in this group")   How do I get this permission?

Thanks,
Phil.

Google Ads API Forum Advisor Prod

unread,
Mar 1, 2021, 1:00:17 PM3/1/21
to phil.l...@ingagepartners.com, adwor...@googlegroups.com

Hi Phil,

Thank you for reaching out. I work with Ernie. If this is the case, please send the requested information directly to our email alias at googleadsa...@google.com.

Thanks and regards,
Xiaoming, Google Ads API Team
 


Google Logo
Xiaoming
Google Ads API Team
 


ref:_00D1U1174p._5004Q2CSvqt:ref

Phil Lachmann

unread,
Mar 1, 2021, 2:45:02 PM3/1/21
to AdWords API and Google Ads API Forum
Xiaoming,

  Thank you. I have sent an email to the address you provided with the information that Ernie requested.

Thank,
Phil Lachmann

On Monday, March 1, 2021 at 1:00:17 PM UTC-5 adsapiforumadvisor wrote:

Hi Phil,

Thank you for reaching out. I work with Ernie. If this is the case, please send the requested information directly to our email alias at googleadsapi-support@google.com.



Thanks and regards,
Xiaoming, Google Ads API Team
 

Mohammad Ahmad

unread,
Mar 1, 2021, 3:24:16 PM3/1/21
to phil.l...@ingagepartners.com, AdWords API and Google Ads API Forum
Hi all i am also getting permission denied problem here is the code i am using to pause campaign. I will really appreciate if you can have any comment

def pauseCampaign(client='someid.apps.googleusercontent.com', customer_id='someid', campaign_id='campaignid'):
campaign_service = client.get_service("CampaignService", version="v6")
# Create campaign operation.
campaign_operation = client.get_type("CampaignOperation", version="v6")
campaign = campaign_operation.update
campaign.resource_name = campaign_service.campaign_path(
customer_id, campaign_id
)
campaign.status = client.get_type("CampaignStatusEnum", version="v6").PAUSED
campaign.network_settings.target_search_network = False
# Retrieve a FieldMask for the fields configured in the campaign.
fm = protobuf_helpers.field_mask(None, campaign)
campaign_operation.update_mask.CopyFrom(fm)

# Update the campaign.
try:
campaign_response = campaign_service.mutate_campaigns(
customer_id, [campaign_operation]
)
except google.ads.google_ads.errors.GoogleAdsException as ex:
print(
'Request with ID "%s" failed with status "%s" and includes the '
"following errors:" % (ex.request_id, ex.error.code().name)
)
for error in ex.failure.errors:
print('\tError with message "%s".' % error.message)
if error.location:
for field_path_element in error.location.field_path_elements:
print("\t\tOn field: %s" % field_path_element.field_name)
sys.exit(1)

print("Updated campaign %s." % campaign_response.results[0].resource_name)

On Tue, Mar 2, 2021 at 12:45 AM Phil Lachmann <phil.l...@ingagepartners.com> wrote:
Xiaoming,

  Thank you. I have sent an email to the address you provided with the information that Ernie requested.

Thank,
Phil Lachmann

On Monday, March 1, 2021 at 1:00:17 PM UTC-5 adsapiforumadvisor wrote:

Hi Phil,

Thank you for reaching out. I work with Ernie. If this is the case, please send the requested information directly to our email alias at googleadsa...@google.com.



Thanks and regards,
Xiaoming, Google Ads API Team
 


Google Logo
Xiaoming
Google Ads API Team
 


ref:_00D1U1174p._5004Q2CSvqt:ref


The content of this message is confidential. If you have received it by mistake, please inform us by an email reply, delete the message, and do not forward the contents of this message to anyone. The integrity and security of this email cannot be guaranteed over the Internet. Therefore, the sender and company will not be held liable for any damage caused by the message. Finally, the opinions disclosed by the sender do not have to reflect those of the company, therefore the company refuses to take any liability for the damage caused by the content of this email.

If it is not necessary to print this email, please help us keep the environment litter-free

--
--
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
Also find us on our blog:
https://googleadsdeveloper.blogspot.com/
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 
You received this message because you are subscribed to the Google
Groups "AdWords API and Google Ads API Forum" group.
To post to this group, send email to adwor...@googlegroups.com
To unsubscribe from this group, send email to
adwords-api...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/adwords-api?hl=en
---
You received this message because you are subscribed to the Google Groups "AdWords API and Google Ads API Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to adwords-api...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/adwords-api/6b7ff554-afc0-45e9-b6ea-70ac7c81b6bbn%40googlegroups.com.

Google Ads API Forum Advisor Prod

unread,
Mar 1, 2021, 4:03:19 PM3/1/21
to phil.l...@ingagepartners.com, adwor...@googlegroups.com
Hi Phil,

Thank you for reaching out. Let's continue our discussion in the other thread.

Google Ads API Forum Advisor Prod

unread,
Mar 1, 2021, 4:08:24 PM3/1/21
to forlo...@gmail.com, adwor...@googlegroups.com

Hi Mohammad,

Thank you for reaching out. Could you share the complete request and response logs for us to further investigate?



Thanks and regards,
Xiaoming, Google Ads API Team
 

Shafali Kapoor

unread,
Mar 8, 2024, 2:23:09 PM3/8/24
to Google Ads API and AdWords API Forum
Hello All,

I am looking to use the FieldMask attribute to overwrite the conversion threshold values that are preset for a customer ID and associated Campaign ID inorder to pause the campaign. Can you please help with the script that I can use for this?
I feel the script shared in this mail trail may be relevant, but I am unsure

Shafali

Google Ads API Forum Advisor

unread,
Mar 11, 2024, 3:33:44 AM3/11/24
to shafali...@us.411locals.com, adwor...@googlegroups.com
Hi,

Thank you for reaching out to the Google Ads API support team.

Kindly note that you can update campaigns using a field mask. The field mask lists all the fields you intend to change with the update, and any specified fields that are not in the field mask will be ignored, even if sent to the server.

The recommended way to generate field masks is using the field_mask helper function included in the google.api_core package. It accepts two protobuf objects and returns a field mask object with a list field that contains all of the fields that are different between the two objects.If None is passed as the first parameter then the field mask list will just contain all of the fields on the second protobuf object that are not set to their default value. I would recommend you to check this documentation on Updates Using Field Masks for more information.

You can use CamapignService to set the status of those Campaigns to 'PAUSED'.

Also, this guide on sample update campaign programs provides information regarding the example code that demonstrates the update of a campaign to pause via the Google Ads API.

 
This message is in relation to case "ref:!00D1U01174p.!5004Q02CSvqt:ref"

Thanks,
 
Google Logo Google Ads API Team


Reply all
Reply to author
Forward
0 new messages