Почему UrlFetchApp скрипта Google Apps возвращает HTML вместо файла CSV (запрашивая API Facebook)? - PullRequest
3 голосов
/ 28 января 2020

Фон

UrlFetchApp отвечает файлом html вместо файла csv, когда я запрашиваю отчет через API insights facebook. Из документации Facebook - внизу страницы :

Экспорт отчетов

Мы предоставляем удобную конечную точку для экспорта в локализованный человек -читаемый формат. в локализованном удобочитаемом формате.

curl -G \
  -d 'report_run_id=<AD_REPORT_RUN_ID>' \
  -d 'name=myreport' \
  -d 'format=csv' \
'https://www.facebook.com/ads/ads_insights/export_report/'

Я уже запустил отчет и, следовательно, получил adReportId, и аутентификация не является проблемой, так как я использую действительный access_token. Фактически, когда я захожу на URL вручную, загрузка правильного csv-файла начинается немедленно.

Проблема

При синтаксическом анализе ответа csv Google Apps Script выдает следующую ошибку:

Не удалось разобрать текст. (строка 219, файл)

Строки 215-219:

function getReportData(reportId) {
  const id = reportId || CacheService.getScriptCache().get('campaign-report-id');
  const facebookUrl = buildFacebookReportUrl(id);
  //facebookUrl:https://www.facebook.com/ads/ads_insights/export_report?report_run_id=<REPORT_ID>&format=csv&access_token=<ACCESS_TOKEN>
  var fetchRequest = UrlFetchApp.fetch(facebookUrl);
  var response = fetchRequest.getContentText();
  Logger.log(response);
  return Utilities.parseCsv(fetchRequest)
    };

function buildFacebookReportUrl(reportId) {
  const baseUrl = `https://www.facebook.com/ads/ads_insights/export_report?`;
  const paramString = `report_run_id=${reportId}&format=csv&access_token=${
    fbConfig.TOKEN}`;
  const requestUrl = `${baseUrl}${paramString}`;
  return encodeURI(requestUrl);
}

В журнале отображаются следующие данные для response (усечено):

<!DOCTYPE html>
<html lang="en" id="facebook" class="no_js">

<head>
    <meta charset="utf-8" />
    <meta name="referrer" content="default" id="meta_referrer" />
    <script>
        window._cstart = +new Date();
    </script>
    <script>
        function envFlush(a) {
            function b(b) {
                for (var c in a) b[c] = a[c]
            }
            window.requireLazy ? window.requireLazy(["Env"], b) : (window.Env = window.Env || {}, b(window.Env))
        }
        envFlush({
            "ajaxpipe_token": "AXjyFTuniyv5Ka6j",
            "timeslice_heartbeat_config": {
                "pollIntervalMs": 33,
                "idleGapThresholdMs": 60,
                "ignoredTimesliceNames": {
                    "requestAnimationFrame": true,
                    "Event listenHandler mousemove": true,
                    "Event listenHandler mouseover": true,
                    "Event listenHandler mouseout": true,
                    "Event listenHandler scroll": true
                },
                "isHeartbeatEnabled": true,
                "isArtilleryOn": false
            },
            "shouldLogCounters": true,
            "timeslice_categories": {
                "react_render": true,
                "reflow": true
            },
            "sample_continuation_stacktraces": true,
            "dom_mutation_flag": true,
            "stack_trace_limit": 30,
            "deferred_stack_trace_rate": 1000,
            "timesliceBufferSize": 5000,
            "show_invariant_decoder": false,
            "compat_iframe_token": "AQ7vXO7c6UeVAX4i",
            "isCQuick": false
        });
    </script>
    <style></style>
    <script>
        __DEV__ = 0;
        CavalryLogger = window.CavalryLogger || function(a) {
            this.lid = a, this.transition = !1, this.metric_collected = !1, this.is_detailed_profiler = !1, this.instrumentation_started = !1, this.pagelet_metrics = {}, this.events = {}, this.ongoing_watch = {}, this.values = {
                t_cstart: window._cstart
            }, this.piggy_values = {}, this.bootloader_metrics = {}, this.resource_to_pagelet_mapping = {}, this.initializeInstrumentation && this.initializeInstrumentation()
        }, CavalryLogger.prototype.setIsDetailedProfiler = function(a) {
            this.is_detailed_profiler = a;
            return this
        }, CavalryLogger.prototype.setTTIEvent = function(a) {
            this.tti_event = a;
            return this
        }, CavalryLogger.prototype.setValue = function(a, b, c, d) {
            d = d ? this.piggy_values : this.values;
            (typeof d[a] === "undefined" || c) && (d[a] = b);
            return this
        }, CavalryLogger.prototype.getLastTtiValue = function() {
            return this.lastTtiValue
        }, CavalryLogger.prototype.setTimeStamp = CavalryLogger.prototype.setTimeStamp || function(a, b, c, d) {
            this.mark(a);
            var e = this.values.t_cstart || this.values.t_start;
            e = d ? e + d : CavalryLogger.now();
            this.setValue(a, e, b, c);
            this.tti_event && a == this.tti_event && (this.lastTtiValue = e, this.setTimeStamp("t_tti", b));
            return this
        }, CavalryLogger.prototype.mark = typeof console === "object" && console.timeStamp ? function(a) {
            console.timeStamp(a)
        } : function() {}, CavalryLogger.prototype.addPiggyback = function(a, b) {
            this.piggy_values[a] = b;
            return this
        }, CavalryLogger.instances = {}, CavalryLogger.id = 0, CavalryLogger.disableArtilleryOnUntilOffLogging = !1, CavalryLogger.getInstance = function(a) {
            typeof a === "undefined" && (a = CavalryLogger.id);
            CavalryLogger.instances[a] || (CavalryLogger.instances[a] = new CavalryLogger(a));
            return CavalryLogger.instances[a]
        }, CavalryLogger.setPageID = function(a) {
            if (CavalryLogger.id === 0) {
                var b = CavalryLogger.getInstance();
                CavalryLogger.instances[a] = b;
                CavalryLogger.instances[a].lid = a;
                delete CavalryLogger.instances[0]
            }
            CavalryLogger.id = a
        }, CavalryLogger.now = function() {
            return window.performance && performance.timing && performance.timing.navigationStart && performance.now ? performance.now() + performance.timing.navigationStart : new Date().getTime()
        }, CavalryLogger.prototype.measureResources = function() {}, CavalryLogger.prototype.profileEarlyResources = function() {}, CavalryLogger.getBootloaderMetricsFromAllLoggers = function() {}, CavalryLogger.start_js = function() {}, CavalryLogger.done_js = function() {};
        CavalryLogger.getInstance().setTTIEvent("t_domcontent");
        CavalryLogger.prototype.measureResources = function(a, b) {
            if (!this.log_resources) return;
            var c = "bootload/" + a.name;
            if (this.bootloader_metrics[c] !== void 0 || this.ongoing_watch[c] !== void 0) return;
            var d = CavalryLogger.now();
            this.ongoing_watch[c] = d;
            "start_" + c in this.bootloader_metrics || (this.bootloader_metrics["start_" + c] = d);
            b && !("tag_" + c in this.bootloader_metrics) && (this.bootloader_metrics["tag_" + c] = b);
            if (a.type === "js") {
                c = "js_exec/" + a.name;
                this.ongoing_watch[c] = d
            }
        }, CavalryLogger.prototype.stopWatch = function(a) {
            if (this.ongoing_watch[a]) {
                var b = CavalryLogger.now(),
                    c = b - this.ongoing_watch[a];
                this.bootloader_metrics[a] = c;
                var d = this.piggy_values;
                a.indexOf("bootload") === 0 && (d.t_resource_download || (d.t_resource_download = 0), d.resources_downloaded || (d.resources_downloaded = 0), d.t_resource_download += c, d.resources_downloaded += 1, d["tag_" + a] == "_EF_" && (d.t_pagelet_cssload_early_resources = b));
                delete this.ongoing_watch[a]
            }
            return this
        }, CavalryLogger.getBootloaderMetricsFromAllLoggers = function() {
            var a = {};
            Object.values(window.CavalryLogger.instances).forEach(function(b) {
                b.bootloader_metrics && Object.assign(a, b.bootloader_metrics)
            });
            return a
        }, CavalryLogger.start_js = function(a) {
            for (var b = 0; b < a.length; ++b) CavalryLogger.getInstance().stopWatch("js_exec/" + a[b])
        }, CavalryLogger.done_js = function(a) {
            for (var b = 0; b < a.length; ++b) CavalryLogger.getInstance().stopWatch("bootload/" + a[b])
        }, CavalryLogger.prototype.profileEarlyResources = function(a) {
            for (var b = 0; b < a.length; b++) this.measureResources({
                name: a[b][0],
                type: a[b][1] ? "js" : ""
            }, "_EF_")
        };
        CavalryLogger.getInstance().log_resources = true;
        CavalryLogger.getInstance().setIsDetailedProfiler(true);
        window.CavalryLogger && CavalryLogger.getInstance().setTimeStamp("t_start");
    </script>
    <title id="pageTitle">Facebook</title>
    <link rel="shortcut icon" href="https://static.xx.fbcdn.net/rsrc.php/yz/r/KFyVIAWzntM.ico" />
    <link type="text/css" rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v3/y2/l/0,cross/3kNz1uzYvN2.css?_nc_x=Ij3Wp8lg5Kz" data-bootloader-hash="SUv1J" />
    <link type="text/css" rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v3/yW/l/0,cross/9NGO1GuacRK.css?_nc_x=Ij3Wp8lg5Kz" data-bootloader-hash="nOHzA" />
    <link type="text/css" rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v3/yA/l/0,cross/rvNB4fphdT0.css?_nc_x=Ij3Wp8lg5Kz" data-bootloader-hash="T1Fcr" />
    <link type="text/css" rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v3/yJ/l/0,cross/kDxV0y2UotM.css?_nc_x=Ij3Wp8lg5Kz" data-bootloader-hash="cNDmN" />
    <script src="https://static.xx.fbcdn.net/rsrc.php/v3/yh/r/53ZB62AZOTo.js?_nc_x=Ij3Wp8lg5Kz" data-bootloader-hash="QPWJc"></script>
    <script>
        requireLazy(["gkx"], function(gkx) {
            gkx.add({
                "676837": {
                    "result": false,
                    "hash": "AT5qgm2lluu0ObEm"
                },
                "676920": {
                    "result": false,
                    "hash": "AT4fRx_5a-x5BCKq"
                },
                "676921": {
                    "result": false,
                    "hash": "AT7L2NIsWs1k6mzF"
                },
                "676922": {
                    "result": false,
                    "hash": "AT434PRa2zIf0VNU"
                },
                "676940": {
                    "result": false,
                    "hash": "AT75c1NCKpiznkoK"
                },
                "946894": {
                    "result": false,
                    "hash": "AT4KxZoaFuONM6jW"
                },
                "996939": {
                    "result": false,
                    "hash": "AT7CXDiWhrCd8u4n"
                },
                "996940": {
                    "result": false,
                    "hash": "AT4S6r3cOh4ebic8"
                },
                "1073500": {
                    "result": false,
                    "hash": "AT6ny6L_AsBsjSUH"
                },
                "1113247": {
                    "result": false,
                    "hash": "AT6aSDBxHRQgvz2h"
                },
                "1263340": {
                    "result": false,
                    "hash": "AT4j6MH_K-2kudmO"
                },
                "1167394": {
                    "result": false,
                    "hash": "AT7tg1d7ZhRzO_3p"
                }
            });
        });
        requireLazy(["qex"], function(qex) {
            qex.add({
                "1211266": {
                    "r": null
                }
            });
        });
        require("TimeSliceImpl").guard(function() {
                    (require("ServerJSDefine")).handleDefines([
                                ["cr:696703", [], {
                                    "__rc": [null, "Aa2d-W5-1nWg1sVgO19izjYy_tqPH8dlVHuIPPgy4FLx3zt-Nw63rJWoc0DdN3TfViSyYfbhpyQGjKQRzfCxl1I"]
                                }, -1],
                                ["cr:708886", ["EventProfilerImpl"], {
                                    "__rc": ["EventProfilerImpl", "Aa2d-W5-1nWg1sVgO19izjYy_tqPH8dlVHuIPPgy4FLx3zt-Nw63rJWoc0DdN3TfViSyYfbhpyQGjKQRzfCxl1I"]
                                }, -1],
                                ["cr:717822", ["TimeSliceImpl"], {
                                    "__rc": ["TimeSliceImpl", "Aa2d-W5-1nWg1sVgO19izjYy_tqPH8dlVHuIPPgy4FLx3zt-Nw63rJWoc0DdN3TfViSyYfbhpyQGjKQRzfCxl1I"]
                                }, -1],
                                ["cr:806696", ["clearTimeoutBlue"], {
                                    "__rc": ["clearTimeoutBlue", "Aa2d-W5-1nWg1sVgO19izjYy_tqPH8dlVHuIPPgy4FLx3zt-Nw63rJWoc0DdN3TfViSyYfbhpyQGjKQRzfCxl1I"]
                                }, -1],
                                ["cr:807042", ["setTimeoutBlue"], {
                                    "__rc": ["setTimeoutBlue", "Aa2d-W5-1nWg1sVgO19izjYy_tqPH8dlVHuIPPgy4FLx3zt-Nw63rJWoc0DdN3TfViSyYfbhpyQGjKQRzfCxl1I"]
                                }, -1],
                                ["cr:896462", ["setIntervalAcrossTransitionsBlue"], {
                                    "__rc": ["setIntervalAcrossTransitionsBlue", "Aa2d-W5-1nWg1sVgO19izjYy_tqPH8dlVHuIPPgy4FLx3zt-Nw63rJWoc0DdN3TfViSyYfbhpyQGjKQRzfCxl1I"]
                                }, -1],
                                ["cr:986633", ["setTimeoutAcrossTransitionsBlue"], {
                                    "__rc": ["setTimeoutAcrossTransitionsBlue", "Aa2d-W5-1nWg1sVgO19izjYy_tqPH8dlVHuIPPgy4FLx3zt-Nw63rJWoc0DdN3TfViSyYfbhpyQGjKQRzfCxl1I"]
                                }, -1],
                                ["cr:1003267", ["clearIntervalBlue"], {
                                    "__rc": ["clearIntervalBlue", "Aa2d-W5-1nWg1sVgO19izjYy_tqPH8dlVHuIPPgy4FLx3zt-Nw63rJWoc0DdN3TfViSyYfbhpyQGjKQRzfCxl1I"]
                                }, -1],
                                ["cr:1100101", ["requestAni [20 - 01 - 28 15: 24: 04: 186 CET] < !DOCTYPE html >
                                        < html lang = "en"
                                        id = "facebook"
                                        class = "no_js" >
                                        < head > < meta charset = "utf-8" / > < meta name = "referrer"
                                        content = "default"
                                        id = "meta_referrer" / > < script > window._cstart = +new Date();
    </script>
    <script>
        function envFlush(a) {
            function b(b) {
                for (var c in a) b[c] = a[c]
            }
            window.requireLazy ? window.requireLazy(["Env"], b) : (window.Env = window.Env || {}, b(window.Env))
        }
        envFlush({
            "ajaxpipe_token": "AXjyFTuniyv5Ka6j",
            "timeslice_heartbeat_config": {
                "pollIntervalMs": 33,
                "idleGapThresholdMs": 60,
                "ignoredTimesliceNames": {
                    "requestAnimationFrame": true,
                    "Event listenHandler mousemove": true,
                    "Event listenHandler mouseover": true,
                    "Event listenHandler mouseout": true,
                    "Event listenHandler scroll": true
                },
                "isHeartbeatEnabled": true,
                "isArtilleryOn": false
            },
            "shouldLogCounters": true,
            "timeslice_categories": {
                "react_render": true,
                "reflow": true
            },
            "sample_continuation_stacktraces": true,
            "dom_mutation_flag": true,
            "stack_trace_limit": 30,
            "deferred_stack_trace_rate": 1000,
            "timesliceBufferSize": 5000,
            "show_invariant_decoder": false,
            "compat_iframe_token": "AQ7vXO7c6UeVAX4i",
            "isCQuick": false
        });
    </script>
    <style></style>
    <script>
        __DEV__ = 0;
        CavalryLogger = window.CavalryLogger || function(a) {
            this.lid = a, this.transition = !1, this.metric_collected = !1, this.is_detailed_profiler = !1, this.instrumentation_started = !1, this.pagelet_metrics = {}, this.events = {}, this.ongoing_watch = {}, this.values = {
                t_cstart: window._cstart
            }, this.piggy_values = {}, this.bootloader_metrics = {}, this.resource_to_pagelet_mapping = {}, this.initializeInstrumentation && this.initializeInstrumentation()
        }, CavalryLogger.prototype.setIsDetailedProfiler = function(a) {
            this.is_detailed_profiler = a;
            return this
        }, CavalryLogger.prototype.setTTIEvent = function(a) {
            this.tti_event = a;
            return this
        }, CavalryLogger.prototype.setValue = function(a, b, c, d) {
            d = d ? this.piggy_values : this.values;
            (typeof d[a] === "undefined" || c) && (d[a] = b);
            return this
        }, CavalryLogger.prototype.getLastTtiValue = function() {
            return this.lastTtiValue
        }, CavalryLogger.prototype.setTimeStamp = CavalryLogger.prototype.setTimeStamp || function(a, b, c, d) {
            this.mark(a);
            var e = this.values.t_cstart || this.values.t_start;
            e = d ? e + d : CavalryLogger.now();
            this.setValue(a, e, b, c);
            this.tti_event && a == this.tti_event && (this.lastTtiValue = e, this.setTimeStamp("t_tti", b));
            return this
        }, CavalryLogger.prototype.mark = typeof console === "object" && console.timeStamp ? function(a) {
            console.timeStamp(a)
        } : function() {}, CavalryLogger.prototype.addPiggyback = function(a, b) {
            this.piggy_values[a] = b;
            return this
        }, CavalryLogger.instances = {}, CavalryLogger.id = 0, CavalryLogger.disableArtilleryOnUntilOffLogging = !1, CavalryLogger.getInstance = function(a) {
            typeof a === "undefined" && (a = CavalryLogger.id);
            CavalryLogger.instances[a] || (CavalryLogger.instances[a] = new CavalryLogger(a));
            return CavalryLogger.instances[a]
        }, CavalryLogger.setPageID = function(a) {
            if (CavalryLogger.id === 0) {
                var b = CavalryLogger.getInstance();
                CavalryLogger.instances[a] = b;
                CavalryLogger.instances[a].lid = a;
                delete CavalryLogger.instances[0]
            }
            CavalryLogger.id = a
        }, CavalryLogger.now = function() {
            return window.performance && performance.timing && performance.timing.navigationStart && performance.now ? performance.now() + performance.timing.navigationStart : new Date().getTime()
        }, CavalryLogger.prototype.measureResources = function() {}, CavalryLogger.prototype.profileEarlyResources = function() {}, CavalryLogger.getBootloaderMetricsFromAllLoggers = function() {}, CavalryLogger.start_js = function() {}, CavalryLogger.done_js = function() {};
        CavalryLogger.getInstance().setTTIEvent("t_domcontent");
        CavalryLogger.prototype.measureResources = function(a, b) {
            if (!this.log_resources) return;
            var c = "bootload/" + a.name;
            if (this.bootloader_metrics[c] !== void 0 || this.ongoing_watch[c] !== void 0) return;
            var d = CavalryLogger.now();
            this.ongoing_watch[c] = d;
            "start_" + c in this.bootloader_metrics || (this.bootloader_metrics["start_" + c] = d);
            b && !("tag_" + c in this.bootloader_metrics) && (this.bootloader_metrics["tag_" + c] = b);
            if (a.type === "js") {
                c = "js_exec/" + a.name;
                this.ongoing_watch[c] = d
            }
        }, CavalryLogger.prototype.stopWatch = function(a) {
            if (this.ongoing_watch[a]) {
                var b = CavalryLogger.now(),
                    c = b - this.ongoing_watch[a];
                this.bootloader_metrics[a] = c;
                var d = this.piggy_values;
                a.indexOf("bootload") === 0 && (d.t_resource_download || (d.t_resource_download = 0), d.resources_downloaded || (d.resources_downloaded = 0), d.t_resource_download += c, d.resources_downloaded += 1, d["tag_" + a] == "_EF_" && (d.t_pagelet_cssload_early_resources = b));
                delete this.ongoing_watch[a]
            }
            return this
        }, CavalryLogger.getBootloaderMetricsFromAllLoggers = function() {
            var a = {};
            Object.values(window.CavalryLogger.instances).forEach(function(b) {
                b.bootloader_metrics && Object.assign(a, b.bootloader_metrics)
            });
            return a
        }, CavalryLogger.start_js = function(a) {
            for (var b = 0; b < a.length; ++b) CavalryLogger.getInstance().stopWatch("js_exec/" + a[b])
        }, CavalryLogger.done_js = function(a) {
            for (var b = 0; b < a.length; ++b) CavalryLogger.getInstance().stopWatch("bootload/" + a[b])
        }, CavalryLogger.prototype.profileEarlyResources = function(a) {
            for (var b = 0; b < a.length; b++) this.measureResources({
                name: a[b][0],
                type: a[b][1] ? "js" : ""
            }, "_EF_")
        };
        CavalryLogger.getInstance().log_resources = true;
        CavalryLogger.getInstance().setIsDetailedProfiler(true);
        window.CavalryLogger && CavalryLogger.getInstance().setTimeStamp("t_start");
    </script>
    <title id="pageTitle">Facebook</title>
    <link rel="shortcut icon" href="https://static.xx.fbcdn.net/rsrc.php/yz/r/KFyVIAWzntM.ico" />
    <link type="text/css" rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v3/y2/l/0,cross/3kNz1uzYvN2.css?_nc_x=Ij3Wp8lg5Kz" data-bootloader-hash="SUv1J" />
    <link type="text/css" rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v3/yW/l/0,cross/9NGO1GuacRK.css?_nc_x=Ij3Wp8lg5Kz" data-bootloader-hash="nOHzA" />
    <link type="text/css" rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v3/yA/l/0,cross/rvNB4fphdT0.css?_nc_x=Ij3Wp8lg5Kz" data-bootloader-hash="T1Fcr" />
    <link type="text/css" rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v3/yJ/l/0,cross/kDxV0y2UotM.css?_nc_x=Ij3Wp8lg5Kz" data-bootloader-hash="cNDmN" />
    <script src="https://static.xx.fbcdn.net/rsrc.php/v3/yh/r/53ZB62AZOTo.js?_nc_x=Ij3Wp8lg5Kz" data-bootloader-hash="QPWJc"></script>
    <script>
        requireLazy(["gkx"], function(gkx) {
            gkx.add({
                "676837": {
                    "result": false,
                    "hash": "AT5qgm2lluu0ObEm"
                },
                "676920": {
                    "result": false,
                    "hash": "AT4fRx_5a-x5BCKq"
                },
                "676921": {
                    "result": false,
                    "hash": "AT7L2NIsWs1k6mzF"
                },
                "676922": {
                    "result": false,
                    "hash": "AT434PRa2zIf0VNU"
                },
                "676940": {
                    "result": false,
                    "hash": "AT75c1NCKpiznkoK"
                },
                "946894": {
                    "result": false,
                    "hash": "AT4KxZoaFuONM6jW"
                },
                "996939": {
                    "result": false,
                    "hash": "AT7CXDiWhrCd8u4n"
                },
                "996940": {
                    "result": false,
                    "hash": "AT4S6r3cOh4ebic8"
                },
                "1073500": {
                    "result": false,
                    "hash": "AT6ny6L_AsBsjSUH"
                },
                "1113247": {
                    "result": false,
                    "hash": "AT6aSDBxHRQgvz2h"
                },
                "1263340": {
                    "result": false,
                    "hash": "AT4j6MH_K-2kudmO"
                },
                "1167394": {
                    "result": false,
                    "hash": "AT7tg1d7ZhRzO_3p"
                }
            });
        });
        requireLazy(["qex"], function(qex) {
            qex.add({
                "1211266": {
                    "r": null
                }
            });
        });
        require("TimeSliceImpl").guard(function() {
                    (require("ServerJSDefine")).handleDefines([
                                ["cr:696703", [], {
                                    "__rc": [null, "Aa2d-W5-1nWg1sVgO19izjYy_tqPH8dlVHuIPPgy4FLx3zt-Nw63rJWoc0DdN3TfViSyYfbhpyQGjKQRzfCxl1I"]
                                }, -1],
                                ["cr:708886", ["EventProfilerImpl"], {
                                    "__rc": ["EventProfilerImpl", "Aa2d-W5-1nWg1sVgO19izjYy_tqPH8dlVHuIPPgy4FLx3zt-Nw63rJWoc0DdN3TfViSyYfbhpyQGjKQRzfCxl1I"]
                                }, -1],
                                ["cr:717822", ["TimeSliceImpl"], {
                                    "__rc": ["TimeSliceImpl", "Aa2d-W5-1nWg1sVgO19izjYy_tqPH8dlVHuIPPgy4FLx3zt-Nw63rJWoc0DdN3TfViSyYfbhpyQGjKQRzfCxl1I"]
                                }, -1],
                                ["cr:806696", ["clearTimeoutBlue"], {
                                    "__rc": ["clearTimeoutBlue", "Aa2d-W5-1nWg1sVgO19izjYy_tqPH8dlVHuIPPgy4FLx3zt-Nw63rJWoc0DdN3TfViSyYfbhpyQGjKQRzfCxl1I"]
                                }, -1],
                                ["cr:807042", ["setTimeoutBlue"], {
                                    "__rc": ["setTimeoutBlue", "Aa2d-W5-1nWg1sVgO19izjYy_tqPH8dlVHuIPPgy4FLx3zt-Nw63rJWoc0DdN3TfViSyYfbhpyQGjKQRzfCxl1I"]
                                }, -1],
                                ["cr:896462", ["setIntervalAcrossTransitionsBlue"], {
                                    "__rc": ["setIntervalAcrossTransitionsBlue", "Aa2d-W5-1nWg1sVgO19izjYy_tqPH8dlVHuIPPgy4FLx3zt-Nw63rJWoc0DdN3TfViSyYfbhpyQGjKQRzfCxl1I"]
                                }, -1],
                                ["cr:986633", ["setTimeoutAcrossTransitionsBlue"], {
                                    "__rc": ["setTimeoutAcrossTransitionsBlue", "Aa2d-W5-1nWg1sVgO19izjYy_tqPH8dlVHuIPPgy4FLx3zt-Nw63rJWoc0DdN3TfViSyYfbhpyQGjKQRzfCxl1I"]
                                }, -1],
                                ["cr:1003267", ["clearIntervalBlue"], {
                                    "__rc": ["clearIntervalBlue", "Aa2d-W5-1nWg1sVgO19izjYy_tqPH8dlVHuIPPgy4FLx3zt-Nw63rJWoc0DdN3TfViSyYfbhpyQGjKQRzfCxl1I"]
                                }, -1],
                                ["cr:1100101", ["requestAni

Что я пробовал (другие решения stackoverflow)

  • В этом вопросе утверждается, что аналогичный запрос urlFetch дал содержимое csv, однако я не понимаю, какие дополнительные опции он вставляет (я не думаю, что мне это нужно, поскольку аутентификация не проблема, и она работает при ручном посещении URL)
  • Этот вопрос имеет ту же проблему, но единственный ответ - на проблемы аутентификации , которые я могу исключить в моем случае.
  • Я пробовал эту реализацию (получение большого двоичного объекта), а также приводил к ошибке скрипта Google Apps при попытке разархивировать BLOB-объект.
  • Этот вопрос заставил меня проверить файл csv на возможные дефекты, однако после проверки и ручного импорта в листы Google все выглядело нормально: enter image description here
  • Спасибо т @TheMaster, который указал на кодировку, которую я также добавил выше функции buildFacebookReportUrl() и также попытался encodeURIComponent () для токена и reportId - без успеха, хотя:
function buildFacebookReportUrl(reportId) {
  const baseUrl = `https://www.facebook.com/ads/ads_insights/export_report?`;
  const paramString = `report_run_id=${encodeURIComponent(reportId)}&format=csv&access_token=${encodeURIComponent(
    fbConfig.TOKEN
  )}`;
  const requestUrl = `${baseUrl}${paramString}`;
  return encodeURI(requestUrl);
}

Как воспроизвести

  1. Facebook Insights API Быстрый старт
  2. Отправка запроса POST в конечную точку / insights, которая отвечает идентификатором рекламного отчета. Выполните.
  3. Экспорт отчета, как в примере выше

Я надеюсь, что кто-то может воспроизвести эту ошибку или сразу заметит, что не так с моим запросом.

Дайте мне знать, если вам нужно больше контекста! (У меня нет большого опыта, но я старался изо всех сил)

1 Ответ

0 голосов
/ 30 января 2020

После публикации ответа я наконец узнал, в чем дело.

Проблема заключается в том, что я сделал асинхронный запрос на создание отчета и хотел загрузить его до завершения задания.

Из документации Facebook :

  1. Отправка запроса POST на конечную точку <AD_OBJECT>/insights, которая отвечает с идентификатором Ad Report Run.
  2. Ad Report Run s содержит информацию об этом асинхронном задании, например async_status. Опрашивайте это поле, пока async_status не станет Job Completed, а async_percent_completion не станет 100.
  3. Затем вы можете запросить <AD_REPORT_RUN_ID>/insights edge для получения окончательного результата.

Я пытался сделать 3. прежде чем были выполнены условия на шаге 2.

Решение

Я добавил некоторое время l oop, опрашивая поле async_status, как рекомендовано.

function fetchReportAndSaveToSheet() {
  const reportId = createReportAndReturnId();
  //THE FOLLOWING CODE HAS SOLVED MY ISSUE
  let jobIsCompleted = false;
  const runReportAdsUrl = `https://graph.facebook.com/v5.0/${reportId}?access_token=${fbConfig.TOKEN}`;
  while (!jobIsCompleted) {
    const fetchRequest = UrlFetchApp.fetch(runReportAdsUrl));
    const runReportAds = JSON.parse(fetchRequest.getContentText());
    jobIsCompleted= runReportAds.async_status === 'Job Completed';
    if (runReportAds.async_status === 'Job Failed') {
      Logger.log((runReportAds.async_status))
      break
    }
  //END OF CODE MODIFICATION
  }
  cacheId(reportId);
  const data = getReportData(reportId);
  clearData();
  pushReportToSheet(data);
}
}
...