0
votes

I'm trying to pull keyword ranking data into Data Studio by creating a community connector. The API method I'm using can be found here:

https://www.rankranger.com/documentation/api-method-rank

Essentially I'm trying to replicate the Google Code Labs tutorial as well as this similar script using a different API - however I'm unable to even connect to Data Studio when I try and publish via the manifest.

I was wondering whether anyone had any experience - or could tell me where I'm going wrong?

// Get Config Parameters

function getConfig(request) {
  var config = {
    "configParams": [
      {
        "type": "INFO",
        "name": "welcomeMessage",
        "text": "Full instructions tbc"
      },
      {
        "type": "TEXTINPUT",
        "name": "apiKey",
        "displayName": "API Key 1",
        "helpText": "You'll be provided with this :)",
        "placeholder": "API Key"
      },
      {
        "type": "TEXTINPUT",
        "name": "campaignId",
        "displayName": "Campaign ID",
        "helpText": "We need to retrieve this through the API",
        "placeholder": "Campaign ID"
      },
      {
        "type": "TEXTINPUT",
        "name": "domain",
        "displayName": "Root Domain",
        "helpText": "The root domain of the site you want rankings for.",
        "placeholder": "root domain"
      }
    ],
    dateRangeRequired: true
  };
  return config;
}

// Set the schema for the fields we'll need the data for

var dataSchema = [
 {
    name: 'date',
    label: 'Date',
    description: 'Date of parsedResponse to select in YYYY-MM-DD',
    group: 'Date',
    dataType: 'STRING',
    semantics: {
      conceptType: 'DIMENSION',
      semanticType: 'YEAR_MONTH_DAY',
      semanticGroup: 'DATE'
    }
  },
  {
    name: 'url',
    label: 'Domain',
    dataType: 'STRING',
    semantics: {
    conceptType: 'DIMENSION'
    }
  },
  {
    name: 'lp',
    label: 'Landing Page',
    dataType: 'URL',
    semantics: {
      conceptType: 'DIMENSION'
    }
  },
  {
    name: 'keyword',
    label: 'Keyword',
    dataType: 'STRING',
    semantics: {
      conceptType: 'DIMENSION'
    }
  },
  {
    name: 'se',
    label: 'Search Engine',
    dataType: 'STRING',
    semantics: {
      conceptType: 'DIMENSION'
    }
  },
  {
    name: 'se_name',
    label: 'Sarch Engine Name',
    dataType: 'STRING',
    semantics: {
      conceptType: 'DIMENSION'
    }
  },
  {
    name: 'rank',
    label: 'Rank',
    dataType: 'NUMBER',
    semantics: {
      conceptType: 'METRIC',
      isReaggregatable: false
    }
  }
];

// Function to return the data schema

function getSchema(request) {
  return {schema: dataSchema};
}

// OAuth function that we don't need

function getAuthType() {
  var response = {
    "type": "NONE"
  };
  return response;
}

// Most important - the get data request

function getData(request) {
  // Create schema for requested fields
  var requestedSchema = request.fields.map(function (field) {
    for (var i = 0; i < dataSchema.length; i++) {
      if (dataSchema[i].name == field.name) {
        return dataSchema[i];
      }
    }
  });

    var url = [
    'https://www.rankranger.com/api/v2/?rank&key=',
    request.configParams.apiKey,
    '&start_date=',
    request.dateRange.startDate,
    '&end_date=',
    request.dateRange.endDate,
    '&campaign_id=',
    request.configParams.campaignId,
    '&domain=',
    request.configParams.domain,
    '&output=json'
  ];

  var response = UrlFetchApp.fetch(url.join(''));
  var parsedResponse = JSON.parse(response.getContentText());


  // Prepare the tabular data.
  var requestedData = parsedResponse.map(function(rankings) {
    var values = [];
    // Provide values in the order defined by the schema.
    dataSchema.forEach(function(field) {
      switch(field.name) {
          case 'date':
            values.push(rankings.date.replace(/-/g, ''));
            break;
          case 'url':
            values.push(rankings.url);
            break;
          case 'lp':
            values.push(rankings.lp);
            break;
          case 'keyword':
            values.push(rankings.keyword);
            break;
          case 'se':
            values.push(rankings.se);
            break;
          case 'se_name':
            values.push(rankings.se_name);
            break;
          case 'rank':
            values.push(rankings.rank || 101);
            break;
      }
    });
    return {values: values};
  });
    // return the data for the request
    return {
    schema: requestedSchema,
    rows: requestedData
  };
}
1
Can you let us know exactly what error you are seeing and at which step? - Minhaz Kazi
TypeError: Cannot read property "fields" from undefined. (line 123) inside the getData() function - Oliver Hayman
It seems like getData() was not passed the request object. Can you please let us know when/where you are getting this error? A screenshot would be helpful. - Minhaz Kazi

1 Answers

0
votes

You aren't supposed to use quotes for "configParams". It should look like that;

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" } ] };