yadirGetReportFun <- function(ReportType = "CUSTOM_REPORT",
DateRangeType = "LAST_30_DAYS",
DateFrom = NULL,
DateTo = NULL,
FieldNames = c("CampaignName","Impressions","Clicks","Cost"),
FilterList = NULL,
Goals = NULL,
AttributionModels = NULL,
IncludeVAT = "YES",
IncludeDiscount = "NO",
Login = NULL,
AgencyAccount = NULL,
Token = NULL,
TokenPath = getwd()){
# start time
proc_start <- Sys.time()
# field names
Fields <- paste0("<FieldNames>",FieldNames, "</FieldNames>", collapse = "")
# filters
if(!is.null(FilterList)){
fil_list <- NA
filt <- FilterList
for(fil in filt){
val <- strsplit(paste0(strsplit(fil ," ")[[1]][3:length(strsplit(fil ," ")[[1]])], collapse = ""), split = ",| |;")[[1]]
fil_list <- paste0(fil_list[!is.na(fil_list)],
paste0("<Filter>",
paste0("<Field>",strsplit(fil ," ")[[1]][1], "</Field>"),
paste0("<Operator>",strsplit(fil ," ")[[1]][2], "</Operator>"),
paste0(paste0("<Values>",val, "</Values>"), collapse = ""),"</Filter>"))
}}
Goals <- ifelse(is.null(Goals), "", paste0("<Goals>",Goals, "</Goals>", collapse = ""))
AttributionModels <- ifelse(is.null(AttributionModels), "", paste0("<AttributionModels>",AttributionModels, "</AttributionModels>", collapse = ""))
# compose request body
queryBody <- paste0('
<ReportDefinition xmlns="http://api.direct.yandex.com/v5/reports">
<SelectionCriteria>',
ifelse(DateRangeType == "CUSTOM_DATE",paste0("<DateFrom>",DateFrom,"</DateFrom>","<DateTo>",DateTo,"</DateTo>") ,"" ),
ifelse(is.null(FilterList),"",fil_list),
'
</SelectionCriteria>',
Goals,AttributionModels,Fields,'
<ReportName>',paste0("MyReport ", Sys.time()),'</ReportName>
<ReportType>',ReportType,'</ReportType>
<DateRangeType>',DateRangeType ,'</DateRangeType>
<Format>TSV</Format>
<IncludeVAT>',IncludeVAT,'</IncludeVAT>
<IncludeDiscount>',IncludeDiscount,'</IncludeDiscount>
</ReportDefinition>')
# <Page><Limit>',10000,'</Limit></Page>
# result frame
result <- data.frame()
for(login in Login){
# auth
Token <- tech_auth(login = Login, token = Token, AgencyAccount = AgencyAccount, TokenPath = TokenPath)
# time counter
parsing_time <- 0
server_time <- 0
# start message
packageStartupMessage("-----------------------------------------------------------")
packageStartupMessage(paste0("Loading data of ",login))
# send request to API
serv_start_time <- Sys.time()
answer <- POST("https://api.direct.yandex.com/v5/reports", body = queryBody, add_headers(Authorization = paste0("Bearer ",Token), 'Accept-Language' = "ru", skipReportHeader = "true" ,skipReportSummary = "true" , 'Client-Login' = login, returnMoneyInMicros = "false", processingMode = "auto"))
if(substr(answer$status_code,1,1) == 4){
packageStartupMessage("Error in request parameters or limit on the number of requests or reports in the queue is exceeded. In this case, analyze the error message, correct the request and send it again.")
# parse error
content(answer, "parsed","text/xml",encoding = "UTF-8") %>%
xml_find_all(., xpath = ".//reports:ApiError//reports:requestId") %>%
xml_text() %>%
message("Request Id: ", .)
content(answer, "parsed","text/xml",encoding = "UTF-8") %>%
xml_find_all(., xpath = ".//reports:ApiError//reports:errorCode") %>%
xml_text() %>%
message("Error Code: ", .)
content(answer, "parsed","text/xml",encoding = "UTF-8") %>%
xml_find_all(., xpath = ".//reports:ApiError//reports:errorMessage") %>%
xml_text() %>%
message("Error Message: ", .)
content(answer, "parsed","text/xml",encoding = "UTF-8") %>%
xml_find_all(., xpath = ".//reports:ApiError//reports:errorDetail") %>%
xml_text() %>%
message("Error Detail: ", .)
next
}
if(answer$status_code == 500){
packageStartupMessage(paste0(login," - ",xml_text(content(answer, "parsed","text/xml",encoding = "UTF-8"))))
packageStartupMessage("While generating the report an error occurred on the server. If for this report the error on the server occurred for the first time, try to generate a report again. If the error persists, contact support.")
next
}
if(answer$status_code == 201){
packageStartupMessage("The report from ", DateFrom, " to ", DateTo, " has been successfully queued for offline generation.", appendLF = T)
packageStartupMessage("Proccesing", appendLF = F)
packageStartupMessage("|", appendLF = F)
}
if(answer$status_code == 202){
packageStartupMessage("Report generation is not completed yet.", appendLF = F)
}
while(answer$status_code != 200){
answer <- POST("https://api.direct.yandex.com/v5/reports", body = queryBody, add_headers(Authorization = paste0("Bearer ",Token), 'Accept-Language' = "ru", skipReportHeader = "true" ,skipReportSummary = "true" , 'Client-Login' = login, returnMoneyInMicros = "false", processingMode = "auto"))
packageStartupMessage("=", appendLF = F)
if(answer$status_code == 500){
stop("While generating the report an error occurred on the server. If for this report the error on the server occurred for the first time, try to generate a report again. If the error persists, contact support.")
}
if(answer$status_code == 502){
stop("Request processing time exceeded server limit.")
}
Sys.sleep(5)
}
packageStartupMessage("|", appendLF = T)
# succes message
server_time <- round(difftime(Sys.time(), serv_start_time , units ="secs"),0)
packageStartupMessage("Report successfully generated and transmitted in response body.", appendLF = T)
packageStartupMessage(paste0("Server time: ",server_time , " sec."), appendLF = T)
# pars start time
pasr_start_time <- Sys.time()
if(answer$status_code == 200){
df_new <- suppressMessages(content(answer, "parsed", "text/tab-separated-values", encoding = "UTF-8"))
# check data
if(nrow(df_new) == 0){
packageStartupMessage("Your request did not return any data, carefully check the specified filter and report period, and then try again.")
next
}
# check if there are APi limits
if (nrow(df_new) >= 1000000) {
stop('You have reached the limits of Yandex.Direct API. Try to use "FetchBy" parameter with DateRangeType = "CUSTOM_DATE", "DateFrom" and "DateTo". If you are already using it, try to choose a smaller value.')
}
# timing message
parsing_time <- round(difftime(Sys.time(), pasr_start_time , units ="secs"),0)
packageStartupMessage(paste0("Parsing time: ", parsing_time, " sec."), appendLF = T)
# request id
packageStartupMessage(paste0("RequestID: ",answer$headers$requestid), appendLF = T)
# add login
if(length(Login) > 1){
df_new$Login <- login}
# add to result
result <- rbind(result, df_new)
# end of cycle
}
}
# tech messages
total_work_time <- round(difftime(Sys.time(), proc_start , units ="secs"),0)
packageStartupMessage(paste0("Total time: ",total_work_time, " sec."))
packageStartupMessage(paste0(round(as.integer(server_time) / as.integer(total_work_time) * 100, 0), "% server time rate."))
packageStartupMessage(paste0(round(as.integer(parsing_time) / as.integer(total_work_time) * 100, 0), "% parsing time rate."))
packageStartupMessage(paste0("RequestID: ",answer$headers$requestid))
packageStartupMessage("Number of rows is ", nrow(result))
packageStartupMessage("-----------------------------------------------------------")
packageStartupMessage()
# limits checker
# return result
return(result)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.