Skip to content

Instantly share code, notes, and snippets.

@aarondicks
Created October 25, 2017 01:33
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aarondicks/cba3dfefca68139a2ce38676109dc2fb to your computer and use it in GitHub Desktop.
Save aarondicks/cba3dfefca68139a2ce38676109dc2fb to your computer and use it in GitHub Desktop.
/**
* ABOUT THIS CODE
* This file, along with a manifest appsscript.json comprises a
* Google Data Studio Community Connector.
* Maintained aaron@impression.co.uk | www.impression.co.uk
*/
/**
* This is one of the four requisites of a Data Studio connector.
* This function sends the Data Studio configuration parameters upon request.
* Note that this example does not use a date range selector - where
* dateRangeRequired would be set to true
* See: https://developers.google.com/datastudio/connector/build
*
* @param {string} request - The configuration request from Data Studio.
* @returns {object}
*/
function getConfig(request) {
var config = {
"configParams": [
{
"type": "INFO",
"name": "welcomeMessage",
"text": "Full instructions tbc"
},
{
"type": "TEXTINPUT",
"name": "apiKey",
"displayName": "STAT API Key",
"helpText": "You'll be provided with this :)",
"placeholder": "STAT API Key"
},
{
"type": "TEXTINPUT",
"name": "siteId",
"displayName": "STAT Site ID",
"helpText": "We need to retrieve this through the API",
"placeholder": "STAT Site ID"
},
{
"type": "TEXTINPUT",
"name": "siteName",
"displayName": "STAT Site subdomain",
"helpText": "The subdomain of your stat login url.",
"placeholder": "STAT Site subdomain"
}
]
};
return config;
}
/**
* This is one of the four requisites of a Data Studio connector.
* Store this in the global scope for reference across the Script.
* See: https://developers.google.com/datastudio/connector/build
*/
var dataSchema = [
{
name: 'keyword',
label: 'Keyword',
dataType: 'STRING',
semantics: {
conceptType: 'DIMENSION'
}
},
{
name: 'regionalSearchVolume',
label: 'Regional Search Volume',
dataType: 'NUMBER',
semantics: {
conceptType: 'METRIC',
isReaggregatable: true
}
},
{
name: 'googleRank',
label: 'Google Rank',
dataType: 'NUMBER',
semantics: {
conceptType: 'METRIC',
isReaggregatable: false
}
}
];
/**
* This is one of the four requisites of a Data Studio connector.
* This function sends the Data Studio schema upon request.
* See: https://developers.google.com/datastudio/connector/build
*
* @param {string} request - The request from Data Studio.
* @returns {object}
*/
function getSchema(request) {
return {schema: dataSchema};
}
/**
* This is one of the four requisites of a Data Studio connector.
* This function specifies the required authentication for this Script.
* In this example, no OAuth authentication is required
* as the API key is a configParam
* For OAuth see: https://developers.google.com/datastudio/connector/oauth2
*
* @returns {object}
*/
function getAuthType() {
var response = {
"type": "NONE"
};
return response;
}
/**
* This is one of the four requisites of a Data Studio connector.
* This function is the main one called once a table or chart has been placed on
* to the canvas. The request object includes all configParams with values,
* as well as a fields array of the selected dimensions and metrics (in order)
* so that that the appropriate headers and rows can be returned to satisfy
* the request.
*
* See: https://developers.google.com/datastudio/connector/build
*
* @param {string} request - The request from Data Studio.
* @returns {object}
*/
function getData(request) {
var header_rows = [];
for (var i = 0; i < request.fields.length; i++) {
for (var j = 0; j < dataSchema.length; j++) {
if (dataSchema[j].name == request.fields[i].name) {
header_rows.push(dataSchema[i]);
}
}
}
var url_parts = [
'https://',
request.configParams.siteName,
'.getstat.com/api/v2/',
request.configParams.apiKey,
'/keywords/list?site_id=',
request.configParams.siteId,
'&format=json'
];
var all_results = get_keywords_recursive(request.configParams);
if (all_results.length > 0) {
var rankings_rows = [];
for (var i = 0; i < all_results.length; i++) {
var keyword_obj = all_results[i];
var rankings_row = [];
for (var j = 0; j < header_rows.length; j++) {
switch (header_rows[j].name) {
case 'keyword':
rankings_row.push(keyword_obj.Keyword);
break;
case 'regionalSearchVolume':
rankings_row.push(keyword_obj.KeywordStats.RegionalSearchVolume);
break;
case 'googleRank':
rankings_row.push(keyword_obj.KeywordRanking.Google.Rank || 101);
break;
}
}
rankings_rows.push({
'values': rankings_row
});
}
var return_data = {
schema: header_rows,
rows: rankings_rows,
cachedData: false
};
return return_data;
} else {
console.info('The STAT API returned a non-200 response. Please check your settings and try again');
throw ("The STAT API returned a non-200 response. Please check your settings and try again. ");
}
}
/**
* Keywords are called from the STAT API one page at a time. This recursively allows for
* pagination of these results into sequential requests to the API endpoint.
* Each request results are then appended to the existing results and then eventually returned
* back to the getData() function.
*
* @param {object} settings - This is the configParams from the Data Studio request.
* @param {array} existing_results - The request from Data Studio.
* @param {string} request - The request from Data Studio.
* @returns {array}
*/
function get_keywords_recursive( settings, existing_results, next_url ) {
existing_results = existing_results || [];
next_url = next_url || false;
var url_parts = ['https://', settings.siteName, '.getstat.com/api/v2/', settings.apiKey];
if (existing_results.length == 0) {
url_parts.push('/keywords/list?site_id=');
url_parts.push(settings.siteId);
url_parts.push('&format=json');
} else {
url_parts.push(next_url);
}
var request_url = url_parts.join('');
var response = UrlFetchApp.fetch( request_url );
var results = JSON.parse( response.getContentText() );
if (results.Response.nextpage) {
existing_results = existing_results.concat(results.Response.Result);
return existing_results.concat( get_keywords_recursive( settings, existing_results, results.Response.nextpage ) );
} else {
return results.Response.Result;
}
}
@bchandel0810
Copy link

How to create field grouping, ordering in schema? can you please also tell me purpose of it ?
I am fetching the data from my API and this API have nested arrays in response, i am able to do mapping but not able to create the report for it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment