Get full list of Adwords MCC with R - r

I need to get the list of all MCC with an Adwords account via Google API and R.
So far I've found some packages to get the list of all clientID within a single MCC but I've found no example to get the list of all MCC within an Adwords account.
Do someone have experience on this topic?
So far I've tried:
library(RAdwordsPlus)
library(RAdwords)
google_auth <- doAuth()
api_version <- "v201809"
customer_id <- "MCC-MAIN-CODE"
request <- RAdwordsPlus::managed.customer.request(fields = c("Name", "CustomerId"))
r <- RAdwordsPlus::get.service(request = request,
cid = customer_id,
auth = google_auth,
api.version = api_version,
user.agent = "r-adwordsplus-test",
verbose = FALSE,
raw = FALSE,
partial.failure = FALSE)
Code ended up with this error:
Warning message:
In parser(response) : x is not a valid managed.customer
My Account structure is something like:
Main MCC
Customer 1 (client_id_1)
Camp_#1
Camp_#2
Customer 2 (client_id_2)
Camp_#1
Camp_#2
Customer 3 (client_id_3)
Camp_#1
Camp_#2
As stated, my goal will be to get all the client_id in order to gathering data for every Customer in the account
Thanks.

Looks like JB already answered your question in his docs at:
https://jburkhardt.github.io/RAdwords/faq/#list-account-ids
List account IDs
How to list all AdWords account IDs which are in my MCC?
We would love to implement this feature! Unfortunately the Adwords API
reporting service does not allow to query the account information on
client center level.
However the good is, you only need to authenticate once in order to
access all accounts within your MCC. Best practice is to create a
vector containing the account IDs and loop over the vector.
Example of that would be something like:
load('.google.auth.RData')
adwords_accounts <- c(
"495-862-1111",
"613-408-2222",
"564-802-3333",
"902-758-4444",
"536-035-5555",
"708-304-6666",
"429-737-7777",
"532-474-8888")
#
account_performance <- statement(select= c('Date','AccountDescriptiveName','Cost','Clicks'),
report="ACCOUNT_PERFORMANCE_REPORT",
start="2019-01-01",
end=as.character(Sys.Date()))
#
list_of_data <- lapply(adwords_accounts, function(x) getData(clientCustomerId = x, google_auth = google_auth, statement = account_performance))
adwords_data <- do.call(rbind,list_of_data)

Related

Having problem with ggmap's mapdist() function

I have this code. I have my google API set up already, registered as well in R, Distance Matrix API has been initiated as well in the Google Cloud console.
Here is the dataframe I have, random 25 postal codes FROM and TO postal codes.
Dataset_test = data.frame(
FROM_POSTAL = c("V8A 0E5","T4G 6M4","V1N 8X3",
"C1B 5G1","R5H 2L4","H9S 8L4","L8E 4Y0","H2Y 7N6",
"K1B 7C0","G4A 5B0","E4P 3T2","E4V 5P4","H3J 1R5",
"G0B 4J7","E7A 6E7","E5B 2Y9","S4H 1T8","A2V 4G5",
"V8L 2A9","T9E 1M5","A5A 5M2","E4T 5B4","S2V 6C4",
"S9H 5P8","B1Y 0V0"),
TO_POSTAL = c("G0J 0B8","N0H 9N4","J9B 4Y4",
"L3Z 2Y7","E8K 4R4","B4P 7X9","S4H 2M0","A1Y 0B8",
"A1W 1E9","P9N 7X1","E4R 4B0","N0P 0M8","E1W 9Y7",
"T9W 8E2","G6X 4S9","A0E 0V4","J5X 7N8","N4N 8A1",
"V9K 0B9","L4G 3H7","E1W 0T2","G5R 9G3","L7C 9S2",
"E8P 2X6","E2A 2M1")
)
Here is the simple script I have to try to calculate the distance between the two postal codes by driving using Google's Distance Matrix API.
Driving_Distance = mapdist(from = Dataset_test[["FROM_POSTAL"]], to = Dataset_test[["TO_POSTAL"]], mode = c("driving")) %>% distinct()
When I run this, it throws an error in the Driving_Distance - says
Error: Argument 1 is a list, must contain atomic vectors
Your Canadian postal codes are hereby working with the mapdist() function.
The number of addresses used here were shortened for the sake of brevity.
A tibble was used instead of a dataframe so that the variables were character data types rather than factor data types. The actual Google API key that was used has been replaced with some text.
This was a good mapping question. The working code and output below:
library(ggmap)
library(plyr)
library(googleway)
library(tidyverse)
df = tibble(
FROM_POSTAL = c("V8A 0E5","T4G 6M4","V1N 8X3",
"C1B 5G1","R5H 2L4","H9S 8L4"),
TO_POSTAL = c("G0J 0B8","N0H 9N4","J9B 4Y4",
"L3Z 2Y7","E8K 4R4","B4P 7X9"))
dd <- apply(df, 1, function(x){
google_distance(origins = list(x["from"]),
destinations = list(x["to"]),
key="My_secret_key")
})
dd

Wait for rgbif download to complete before proceeding

I am developing a small application in R Shiny. Part of the application will need to query GBIF to download species occurrence data. This is possible using rgbif. The function rgbif::occ_download() will download the data and rgbif::occ_download_meta() will check whether GBIF has fulfilled your request. For example:
geometry <- "POLYGON((30.1 10.1,40 40,20 40,10 20,30.1 10.1))"
res <- occ_download(paste0("geometry within ", geometry), type = "within", format = "SPECIES_LIST")
occ_download_meta(res)
<<gbif download metadata>>
Status: RUNNING
Format: SPECIES_LIST
Download key: 0004089-190415153152247
Created: 2019-04-25T09:18:20.952+0000
Modified: 2019-04-25T09:18:21.045+0000
Download link: http://api.gbif.org/v1/occurrence/download/request/0004089-190415153152247.zip
Total records: 0
So far, so good. However, the following function rgbif::occ_download_get() can't download the data for downstream analysis until occ_download_meta(res) has completed (when Status = SUCCEEDED).
How can I make the session wait until the download from GBIF has been completed? I cannot hard code a wait time into the script as different sized extents will take GBIF longer or shorter amounts of time to process. Also, the number of other active users querying the service could also alter wait times. I therefore need some sort of flag where Status == Succeeded before proceeding.
I have copied some skeleton code with comments below.
library(rgbif)
geometry <- "POLYGON((30.1 10.1,40 40,20 40,10 20,30.1 10.1))" # Define boundary
res <- occ_download(paste0("geometry within ", geometry), type = "within", format = "SPECIES_LIST")
# WAIT HERE UNTIL Status == SUCCEEDED
occ_download_meta(res)
x <- occ_download_get(res, overwrite = TRUE) # Download data
data<-occ_download_import(x) # Import into R
rgbif maintainer here. You could do something like we have within the occ_download_queue() function:
res <- occ_download(paste0("geometry within ", geometry), type = "within", format = "SPECIES_LIST")
still_running <- TRUE
status_ping <- 3
while (still_running) {
meta <- occ_download_meta(res)
status <- meta$status
still_running <- status %in% c("succeeded", "killed")
Sys.sleep(status_ping) # sleep between pings
}
you probably want to check for succeeded and killed, and do something different if killed

Using the Adwords Traffic Estimator Service with R / ‘RAdwords’ packege

So I need to get Traffic estimation for some keywords via Google Adwords. I see that Google has a traffic estimator service API: https://developers.google.com/adwords/api/docs/guides/traffic-estimator-service .
I'm using R, which has quite a comprehensive RAdwords package, https://jburkhardt.github.io/RAdwords/faq/ , but one with which I failed miserably to find weather it provides access to this particular Adwords API service.
So did anyone use R to get keyword data from Google adwords via Traffic estimator? Is it possible with the RAdwords packege or does it need to be done via classic scripting ?
Thanks in advance.
you can use rgoogleads package.
Documentation: https://selesnow.github.io/rgoogleads/docs/
See Keywords Planing Data section: https://selesnow.github.io/rgoogleads/docs/reference/index.html#section-keywords-planing-data
There's a R package called RAdwordsPlus, which is built on top of RAdwords that will do just that.
devtools::install_github("adviso/RAdwordsPlus")
library(RAdwordsPlus)
google_auth <- doAuth() # requires user interaction the first time
api_version <- "v201809"
customer_id <- "xxx-xxx-xxxx"
# Build keyword request
k <- keyword(
text = c("mars cruise", "cheap cruise", "cruise"),
match.type = c("BROAD", "PHRASE", "EXACT"),
type = "Keyword"
)
# Keyword estimate request
ker <- keyword.estimate.request(
keyword = k,
max.cpc = 5000000, # 1 million == one unit (microamaounts)
is.negative = FALSE
)
# AdGroupEstimateRequest
aer <- adgroup.estimate.request(ker)
# Criteria for CampaignEstimateRequest
cer_criteria <- vector("list", length = 2)
cer_criteria[[1]] <- as.criterion(id = "2826", type = "Location") # united kingdom
cer_criteria[[2]] <- as.criterion(id = "1000", type = "Language") # english
# CampaignEstimateRequest
cer <- campaign.estimate.request(aer, campaign.id = NULL, criteria = cer_criteria)
# Build the request
request <- traffic.estimator.request(cer)
# Download data from the API
r <- get.service(request = request,
cid = customer_id,
auth = google_auth,
api.version = api_version,
user.agent = "r-adwordsplus-test",
verbose = TRUE)

googleAnalyticsR 403 user permission

I am cyciling through 50 GA accounts and there is one with user permission that I do not have access to the error I am getting is...
Error : API returned: User does not have sufficient permissions for this profile.
Error in error_check(out) :
API returned: User does not have sufficient permissions for this profile.
I new to R and am wondering if I can write a trycatch method to skip this account and continue the method. At the moment the process stops with a Teequest Status Code:403/
library(googleAnalyticsR)
library(tidyverse)
#settings
start_date <- as.character(Sys.Date()-31)
end_date <- as.character(Sys.Date()-1)
metrics <- c("sessions", "pageviews")
dimensions <- "year"
#Authorize Google Analytics R- this will open a webpage
#You must be logged into your Google Analytics account on your web browser
ga_auth()
account_summary <- ga_account_list()
#Add the start and end date to the date frame, as well as some columns to use to populate the metrics
account_summary$start_date <- start_date
account_summary$end_date <- end_date
# cycle through the list of views, pull the data, and add it to the
#account_summary
for (i in 1:nrow(account_summary)){
view_id <- account_summary$viewId[i]
ga_data <- google_analytics_4(viewId = view_id,
date_range = c(start_date,end_date),
metrics = metrics,
dimensions = dimensions)
# This query might return multiple rows (if it spans a year boundary), so
#collapse and clean up
ga_data <- summarise(ga_data,
sessions = sum(sessions),
pageviews = sum(pageviews))
#add the totals to the account summary
account_summary$sessions[i] <- ga_data$sessions
account_summary$pageviews[i] <- ga_data$pageviews
}
# Make a more compact set of data
clean_summary <- select(account_summary,
Account = accountName,
Property + webPropertyName,
View = viewName,
Type = type,
Level = level,
'Start Date' = start_date,
'End Date' = end_date,
Sessions = sessions,
Pageviews = pageviews)
write.csv (clean_summary, "summary_results.csv", row.names = FALSE)
You can use tryCatch like this:
...
ga_data <- tryCatch(google_analytics_4(viewId = view_id,
date_range = c(start_date,end_date),
metrics = metrics,
dimensions = dimensions),
error = function(ex){
warning(ex)
NULL
})
...
The example turns the error into a warning instead, and returns a NULL

Character string truncated when passed to function

I have a long list of Campaign names that I need to collapse to a character vector of length 1 and then pass as the "where" clause in a call to the Google AdWords API through the "RAdwords" package.
Creating this character string is not a problem until its length gets to a certain point that the values are truncated, which causes an error in AdWords API call.
Here is a sample of the setup that will not cause an error:
campaigns <- paste0("Campaign ", seq(1,5))
collapsed_campaigns <- paste0(campaigns, collapse = "','")
campaign_filter1 <- paste("CampaignName IN ['", collapsed_campaigns, "']")
And here is a setup that will cause an error:
campaigns <- paste0("Campaign ", seq(1,50))
collapsed_campaigns <- paste0(campaigns, collapse = "','")
campaign_filter2 <- paste("CampaignName IN ['", collapsed_campaigns, "']")
Inspecting the structure of each variable shows:
> str(campaign_filter1)
chr "CampaignName IN [' Campaign 1','Campaign 2','Campaign 3',
'Campaign 4','Campaign 5 ']"
> str(campaign_filter2)
chr "CampaignName IN [' Campaign 1','Campaign 2','Campaign 3',
'Campaign 4','Campaign 5','Campaign 6','Campaign 7','Campaign 8','Camp"| __truncated__
If I pass 'campaign_filter1' as my where clause in RAdwords, things run as expected.
If I pass 'campaign_filter2' as the where clause, I get this error:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><reportDownloadError>
<ApiError><type>QueryError.INVALID_WHERE_CLAUSE</type><trigger></trigger>
<fieldPath></fieldPath></ApiError></reportDownloadError>
It seems the "| truncated" is getting passed literally to the RAdwords function.
Here is the result of inspecting the structure of "traffic_data" in a failed call to RAdwords:
> str(traffic_data)
Classes ‘data.table’ and 'data.frame': 1 obs. of 1 variable:
$ ads: chr "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>
<reportDownloadError><ApiError><type>QueryError.INVALID_WHERE_CLAU"| __truncated__
- attr(*, ".internal.selfref")=<externalptr>
Obviously, I could get around this some sort of looping function and call the data from the API one campaign at a time, but that would be horribly inefficient. How can I get the entirety of the character string to be passed to RAdwords?
One question upfront: Why don´t you donwload all campaign data and filter the result dataframe in R? With this strategy the whole string campaign name pasting process would become superfluous. You could filter the dataframe based on vector operations in R. This approach probably is more rubust and less vulnerable.
However, if you want to filter campaigns explicitly in your API call you can do it with this code:
# 1. Download all campaigns
# query all campaign names
body1 <- statement(select=c('CampaignName'),
report="CAMPAIGN_PERFORMANCE_REPORT",
start="2017-11-01",
end="2017-11-02")
# download all campaign names
campaigns <- getData(clientCustomerId = "***-***-****",
google_auth = google_auth,
statement = body,
apiVersion = "201710",
transformation = T,
changeNames = T)
# 2. Build query with all campaigns in where clause
# build string for where clause
cmp_string <- paste0(campaigns$Campaign, collapse = "','")
cmp_string <- paste("CampaignName IN ['", cmp_string, "']", sep = "")
# query all campaigns with where condition
body2 <- statement(select = c('CampaignName'),
where = cmp_string,
report = "CAMPAIGN_PERFORMANCE_REPORT",
start = "2017-11-01",
end = "2017-11-02")
# download all campaigns using the where clause
campaigns2 <- getData(clientCustomerId = "***-***-****",
google_auth = google_auth,
statement = body,
apiVersion = "201710",
transformation = T,
changeNames = T)
In the first part I download all campaign names to have data for the where clause. In the second part I demonstrate how to download all campaigns again utilizing the where clause with all campaigns as filter.
I tested the code above with over 200 campaigns. Neither there were any issues with the RAdwords package nor with the Adwords API.
I suspect there are issues with the string you pass into campaign_filter2. Within paste() you miss to set sep = "". Otherwise you end up with a space in the beginning of the first campaign name.

Resources