Google Data Studio - нет ошибок и нет данных - PullRequest
0 голосов
/ 27 декабря 2018

Я создаю очень простой Data Connector, чтобы открыть изменяющийся JSON в Google Data Studio.Я отлаживал этот код в течение некоторого времени, и я не могу понять, почему он не отображается внутри Data Studio.

Вот текущая разбитая идея:

  • getSchema () -возвращать столбцы с неизвестной структурой JSON
  • getFlatten () - возвращать сглаженную структуру JSON, т.е. "parent.child"
  • getData () - возвращать свежие данные на основе обнаруженной структуры предыдущей схемы

Другие соображения включают в себя обнаружение типов значений при построении схемы и форматирование даты.

Обратите внимание, что это не самый умный код, и я не ищу оптимизации кода.

Код:

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

function getConfig(request) {
    var cc = DataStudioApp.createCommunityConnector();
    var config = cc.getConfig();

    config.newInfo()
    .setId('instructions')
    .setText('Enter JSON Url');

    config.newTextInput()
    .setId('json_url')
    .setName('Enter JSON Url')
    .setPlaceholder('https://example.com/2347ygsdegf.json');

    return config.build();
}

function getFields(request) {
    var cc = DataStudioApp.createCommunityConnector();
    var fields = cc.getFields();
    var types = cc.FieldType;
    var aggregations = cc.AggregationType;

    var response = UrlFetchApp.fetch(request.configParams.json_url);
    var parsedResponse = JSON.parse(response);

    var flattened = getFlattened(parsedResponse);

    var fieldsFound = [];

    for (var i =0; i < flattened.length; i++){
        for (entry in flattened[i]){

            if (!fieldsFound.indexOf(entry) == -1){
                continue;
            }
            else {
                fieldsFound.push(entry);
            }

            var value = flattened[i][entry];

            if (isDate(value)){
                fields.newDimension()
                .setId(entry)
                .setName(entry)
                .setType(types.YEAR_MONTH_DAY);
            }
            else if (typeof value == "number"){
                fields.newMetric()
                .setId(entry)
                .setName(entry)
                .setType(types.NUMBER);
            }
            else if (typeof value == "boolean") {
                fields.newMetric()
                .setId(entry)
                .setName(entry)
                .setType(types.BOOLEAN);
            }
            else {


                fields.newDimension()
                .setId(entry)
                .setName(entry)
                .setType(types.TEXT);  
            }
        }
    }

    return fields;
}

function isDate(value) {
    var dateFormat;
    if (toString.call(value) === '[object Date]') {
        return true;
    }
    if (value == false || value == null || value === true || (typeof value == "string" && !value.length) || typeof value != "string"){
        return false;
    }
    value.replace(/^\s+|\s+$/gm, '');
    dateFormat = /(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/;
    return dateFormat.test(value);
}

function getFlattened(parsedResponse){
    //flatten result, get fields

    var flattened = [];

    //https://stackoverflow.com/a/19101235/5865284 -- amended
    var result = {};
    function recurse (cur, prop) {
        if (Object(cur) !== cur) {
            result[prop] = cur;
        } else if (Array.isArray(cur)) {
            for(var i=0, l=cur.length; i<l; i++)
                recurse(cur[i], prop);
            if (l == 0)
                result[prop] = [];
        } else {
            var isEmpty = true;
            for (var p in cur) {
                isEmpty = false;
                recurse(cur[p], prop ? prop+"."+p : p);
            }
            if (isEmpty && prop)
                result[prop] = {};
        }
    }

    for (i in parsedResponse){
        result = {};
        recurse(parsedResponse[i], "");
        flattened.push(result);
    }

  return flattened;
}

function isAdminUser(){ return true }

function getSchema(request) {
    return { schema: getFields(request).build() }
}

function getData(request){


    var response = UrlFetchApp.fetch(request.configParams.json_url);
    var parsedResponse = JSON.parse(response);

    var flattened = getFlattened(parsedResponse);

    var schema = getFields(request).build();

    var rows = [];
    var fieldsFound = [];

    for (var i =0; i < flattened.length; i++){

        var row = {
            values: []
        };

        var rowEntries = [];

        for (key in schema){
            var value = flattened[i][schema[key]["name"]];

            switch (typeof value){
                case "number":
                row.values.push(value.toString());
                break;
                case "boolean":
                row.values.push(value ? true:false);
                break;
                default:

                if (isDate(value)){
                    row.values.push(value.replace(/-/g, ''));
                }
                else if (value == null){
                    row.values.push(null);
                }
                else {
                    row.values.push(""+value);
                }
                break;
            }
        }

        rows.push(row);
    }

    var result = {
        schema: schema,
        rows: rows,
        cachedData: false,
    };

    console.log(JSON.stringify(result));
    // reports as expected - matching https://developers.google.com/datastudio/connector/reference#getdata

    return result;
}

Результат:

enter image description here

Отладка: (отозвано) - изображение console.log() команда в getData() - все строки и схемы правильно соответствуют https://developers.google.com/datastudio/connector/reference#getdata

Есть идеи?Спасибо вам.

1 Ответ

0 голосов
/ 24 января 2019

При использовании UrlFetchApp.fetch с ответом JSON необходимо вызвать getContentText перед анализом:

var json = resp.getContentText();
var data = JSON.parse(json);

Или использовать анализ JSON с reviver:

JSON.parse(resp,function(k,v) { if (""===k) return v;});

https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app

...