Ошибка авторизации при загрузке рекламного отчета AMZ - PullRequest
0 голосов
/ 25 мая 2018

У меня есть следующее приложение для загрузки productAds от Amazon Sponsored Products API

Документы: https://advertising.amazon.com/API/docs/reference/reports

Когда я пытаюсь получить удовольствие, я получаю ответ от запроса отчета, иполучить файл в S3 Bucket.

server is running at localhost:3000
{"reportId":"amzn1.clicPI.v1.p7.5B7EE.d141f-e5-4b-a8-6a4e712","status":"SUCCESS","statusDetails":"Report has been successfully generated","location":"https://advertising-api.amazon.com/v1/reports/amzn1.clsAPI.v1.p7.5B7EE.d151f-e5-4b-a8-699e712/download","fileSize":22}

Далее я пытаюсь загрузить отчет enter image description here

и получить сообщение об ошибке:

donwloading <?xml version="1.0" encoding="UTF-8"?>
<Error><Code>InvalidArgument</Code><Message>Only one auth mechanism allowed; only the X-Amz-Algorithm query parameter, Signature query string parameter or the Authorization header should be specified</Message><ArgumentName>Authorization</ArgumentName><ArgumentValue>bearer Atza|IwEBIJvCt20TUi122srkN4JCOdUxlBNuLJBrtbIGF9x5QbKG67f-K-0L4RkLzeyouXWy_U_-VscaCe1aFqOJK55X9Mu2X6nwWkAWRyhc6cCMfPjKpyyVjKtPqC8Plme84om1dqtmIqC93yUVc_clHimQqmnl262te2EXyUhYoVQg8hK2nlDG67Iw7xjsLK4rgl3E4RR36DHnZkEOnVQZtfjIkIbcYtsCSAdpRZRazF4FQfpS-jHvMlwuH8TZfY9tRpmBEx5fjJw1WZ14Dejqti23mZ7yt-MjNkUuD-DdPXs3fek1ZJePlHEVzcI2y_WzCnwJnoSVp5a5w1WgNco8YqEGEuLsT9S0dxQRluTiw8f4b4lx2FFFm9jz0K7pqo1Mvs6DZOVCDJzE-xJ_VLlWoE5QDMUAMor4AEQH44_0NWBjJDrYaVvn1vZLCER1uxW4jgr127W5yXaj4y1vj_vADwFq9a3330hAc73EWwL6FFSfoTQZyNc4Fh1d3DXfVHpXFk6cv0bHt4cV_OotGwGHat5fv75VHX5K3al3Xd5-QJv2cTiQ9srY5oqKsdbxptGaxAdrdMQaUlFHhyHEGbwED9xYoCw6-IauN15gvMAei9wz2kzRCA</ArgumentValue><RequestId>BDCE812C4363E9D2</RequestId><HostId>4ixH24mPtMBt+FDnI3rM9UJP95toaNBmmR1v0uQJ5XkyiXbtLEuZ8d+vDI0+gquwhn6/Fkz6/+o=</HostId></Error>

Здесьэто приложение.Как я могу загрузить отчет и правильно передать заголовки?Я нашел этот репозиторий в PHP, который имеет функцию загрузки: https://github.com/dbrent-amazon/amazon-advertising-api-php/blob/master/AmazonAdvertisingApi/Client.php

const express = require('express')
const app = express();
const request = require('request');
const moment = require('moment');
const fs = require('fs')
const path = require('path')
const config = require('./config')
const auth = require('./helpers/auth');
const cron = require('./helpers/cron');
const con = require('./helpers/database');

const getProfiles = (headers) => {
    return new Promise((resolve, reject) => {
        request({
            url: config.ad_url + '/v1/profiles',
            method: "GET",
            headers: headers
        }, (err, httpResponse, body) => {
            if (err) {
                reject(err);
            }
            resolve(body);
        });
    })
}

const createReport = (params, recordType, headers) => {
    return new Promise((resolve, reject) => {
        request({
            url: config.ad_url + '/v1/' + recordType + '/report',
            method: "POST",
            headers: headers,
            json: params
        }, (err, httpResponse, body) => {
            if (err) {
                reject(err);
            }
            resolve(body);
        });
    })
}

const getReport = (reportId, headers) => {
    return new Promise((resolve, reject) => {
        request({
            url: config.ad_url + '/v1/reports/' + reportId,
            method: "GET",
            headers: headers
        }, (err, httpResponse, body) => {
            if (err) {
                reject(err);
            }
            resolve(body);
        });
    })
}

function download(fileUrl, apiPath, callback) {
    var url = require('url'),
        http = require('http'),
        p = url.parse(fileUrl),
        timeout = 10000;

    var file = fs.createWriteStream(apiPath);

    var timeout_wrapper = function (req) {
        return function () {
            console.log('abort');
            req.abort();
            callback("File transfer timeout!");
        };
    };


    console.log('before');

    var request = http.get(fileUrl).on('response', function (res) {
        console.log('in cb');
        var len = parseInt(res.headers['content-length'], 10);
        var downloaded = 0;

        res.on('data', function (chunk) {
            file.write(chunk);
            downloaded += chunk.length;
            process.stdout.write("Downloading " + (100.0 * downloaded / len).toFixed(2) + "% " + downloaded + " bytes" + isWin ? "\033[0G" : "\r");
            // reset timeout
            clearTimeout(timeoutId);
            timeoutId = setTimeout(fn, timeout);
        }).on('end', function () {
            // clear timeout
            clearTimeout(timeoutId);
            file.end();
            console.log(file_name + ' downloaded to: ' + apiPath);
            callback(null);
        }).on('error', function (err) {
            // clear timeout
            clearTimeout(timeoutId);
            callback(err.message);
        });
    });

    // generate timeout handler
    var fn = timeout_wrapper(request);

    // set initial timeout
    var timeoutId = setTimeout(fn, timeout);
}

const recordType = 'productAds';
const campaignType = 'sponsoredProducts';
const reportDate = moment().format('YYYYMMDD');
const metrics = 'campaignId,sku,currency,attributedConversions1d';

const reportParam = {
    campaignType: campaignType,  
    // segment: "query",
    reportDate: reportDate,      
    metrics: metrics             
}


auth().then(res => {
    const headers = {
        'Content-Type': 'application/json',
        'Authorization': config.token_type + ' ' + res.access_token,
        'Amazon-Advertising-API-Scope': '196354651614',
    }

    // getProfiles(headers).then(res => {})
    const reportId = 'amzn1.clicksAI.1.p.5B057EE.d41f-e5-4a-a8-699e712';
        getReport(reportId, headers).then(res => {
            console.log(res)
            const file = JSON.parse(res);
            // console.log(file.location )
            // download

            request({
                url: file.location,
                method: 'GET',
                headers: {
                    'Authorization': headers.Authorization,
                    'Amazon-Advertising-API-Scope': '196335474',
                    'Allow': 'GET, HEAD, PUT, DELETE'
                }
            }, (err, response, body) => {
                console.log('donwloading', body)
            })
        })

    createReport(reportParam, recordType, headers).then(res => {
        const reportId = 'amzn1.clicksI.v1.p7.5B07EE.d1541f-e5-eb-a68-6996e712';
    })
})


app.listen(3000, function(err) {
    console.log("server is running at localhost:3000");
})

1 Ответ

0 голосов
/ 28 ноября 2018

Это вызвано отправкой заголовка «Авторизация» на S3, и он этого не хочет.Причина в том, что ответ / download от API представляет собой перенаправление 307, поэтому используемый вами клиент перенаправляет с полными заголовками API.Чтобы обойти это, не позволяйте вашему клиенту следовать перенаправлениям и вместо этого проанализируйте расположение S3 из заголовка ответа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...