Greetings to all, I have an Authentication issue using the AdWords API:
Currently I have a MCC account (499-xxx-xxx) with two sub-accounts:
1. Sub-account 1: 476-xxx-xxx
2. Sub-account 2: 120-xxx-xxx
At the MCC, we have a developer token inside the AdWords API Center with “Basic access”. The developer token starts KiPxxxxxxxxxxxxxxxxx. Client manager API, 818-xxx-xxxx that is linked to the MCC. Access type is “User interface and API”.
We are using the AdWords API to ingest campaign data for each account into our internal business reporting solution.
The issue is that I am only able to get data from one of the two accounts. Account 476-xxx-xxx returns back data when running on its own. When trying to capture data from 120-xxx-xxx, the ingestion process fails.
The error message we are receiving are:
AdWordsReportsException: Report download errors occurred.
Error: AuthorizationError.USER_PERMISSION_DENIED, Trigger: <null>
We contacted Google AdWords support on 7/6 to see they could understand why. The Google AdWords rep was super-helpful, and spent more than an hour reviewing. She analyzed the differences between the two AdWords accounts: 476-xxx-xxx and 120-xxx-xxx, to see if there were any obvious differences between the two. 476-xxx-xxx is the older account, created before the MCC account was created. Account 120-xxx-xxx, on the other hand, was created via the MCC account. One noticeable difference between account is that 120-xxx-xxx did not have an login email address associated with it, and so at the suggestion of the support rep, we subsequently added a new user to 120-xxx-xxx. This did not resolve the issue.
So we’re stuck on what the issue could be. Possibly it’s something related to how we’re pulling the data.
The piece of code I am using it is very straight forward:
General Configurations:
private const string DeveloperTokenHealth = "KiPZxxxxxxxxxxxxxx";
private const string CustomerIdHealth = "476-XXX-XXXX";
private const string CustomerIdMedicare = "120-XXX-XXXX";
const String ClientId = "XXXXXXXXXXXX-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com";
const String ClientSecret = "WDZOxxxxxxxxxxxxxxxxxx";
Authentication Method:
{
var scopes = new[]
{
"https://www.googleapis.com/auth/adwords"
};
UserCredential credential =
GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets
{
ClientId = GetClientId(Subvertical),
ClientSecret = GetClientSecret(Subvertical)
},
scopes,
Environment.UserName,
CancellationToken.None,
new FileDataStore("localhost.GoogleAdWords.Auth.Store")).Result;
return credential;
}
Main Method for returning API Data:
var userCredential = Authentication(subVertical);
var config = new Dictionary<string, string>
{
{"DeveloperToken", GetDeveloperToken(subVertical)},
{"ClientCustomerId", GetCustomerId(subVertical)},
{"OAuth2ClientSecret", GetClientSecret(subVertical)},
{"OAuth2AccessToken", userCredential.Token.AccessToken},
{"OAuth2ClientId", GetClientId(subVertical)},
{"OAuth2RefreshToken", userCredential.Token.RefreshToken},
{"OAuth2Scope","https://www.googleapis.com/auth/adwords"}
};
var user = new AdWordsUser(config);
return Run(user, dateFrom, dateTo, CustomerId[subVertical]);
Method for running API Data:
private static bool Run(AdWordsUser user, DateTime dateFrom, DateTime dateTo, String customerId)
{
var definition = new ReportDefinition
{
reportName = "CAMPAIGN_PERFORMANCE_REPORT",
reportType = ReportDefinitionReportType.CAMPAIGN_PERFORMANCE_REPORT,
downloadFormat = DownloadFormat.CSV,
dateRangeType = ReportDefinitionDateRangeType.CUSTOM_DATE
};
var selector = new Selector
{
fields = new[]
{
"Date", "CampaignStatus", "CampaignName", "CampaignId", "TotalBudget", "ServingStatus", "Clicks",
"Impressions", "Ctr", "AverageCpc", "Cost", "AveragePosition","ConversionsManyPerClick",
"CostPerConversionManyPerClick", "ConversionRateManyPerClick","ViewThroughConversions", "Labels"
}
};
selector.predicates = new Predicate[] { };
var daterange = new DateRange {min = dateFrom.ToString("yyyyMMdd"), max = dateTo.ToString("yyyyMMdd")};
selector.dateRange = daterange;
definition.selector = selector;
definition.includeZeroImpressions = true;
string filePath = String.Format("c:\\adwords_campaign-{0}.csv",customerId);
try
{
var utilities = new ReportUtilities(user, "v201502", definition);
var response = utilities.GetResponse())
catch (Exception ex)
{
}
So always when I use CustomerIdMedicare = "120-XXX-XXXX"; the application goes by Exception
Any suggestions or ideas of what the issue might be?