1

I am having issues with the amazon advertising api. I am using a nodejs library (https://github.com/humanstupidity/amazon-advertising-api) to fetch a report from amazon which returns me a body that seems to be in binary but I am not able to make it readable in JSON.

I tried the request in postman and it returns the same binary response. I have to download and unpacked the file from postman to make it readable but I am somehow not able to make it work in nodeJS.

This is the part inside the library which is important:

const request = require('request');
const util = require('util');

const requestPromise = util.promisify(request);
const postRequestPromise = util.promisify(request.post);
const getRequestPromise = util.promisify(request.get);


module.exports = class AdvertisingClient {
    async getReport(reportId) {

        while (true) {

            let reportRequest = JSON.parse(await this._operation(`sp/reports/${reportId}`));

            if (reportRequest.status === 'SUCCESS') {
                return this._download(reportRequest.location);
            }

            await sleep(500);

        }

    }
    _download(location, auth = true)
    {
        let headers = {}

        if (auth) {
            headers.Authorization = 'Bearer ' + this.options.accessToken;
        }

        if (this.options.profileId) {
            headers['Amazon-Advertising-API-Scope'] = this.options.profileId;
        }

        let requestOptions = {
            url: location,
            headers: headers,
            followRedirect: false,
            gzip: true
        }

        return this._executeRequest(requestOptions);
    }

    async _executeRequest(requestOptions){

        let response = await getRequestPromise(requestOptions);

        if (response.statusCode == 307) {
            let finalResult = await this._download(response.headers.location, false);
            return finalResult;
        }

        let result={
            success: false,
            code: response.statusCode,
            response: response.body,
            requestId: 0
        };

        console.log(result);

        if (!(response.statusCode < 400 && response.statusCode >= 200)) {
            let data = JSON.parse(response.body);

            if (data && data.requestId) {
                requestId = data.requestId;
            }

            result = false;
        } else {
            result.success = true;
        }

       return result

    }

    async _operation(_interface, data, method = 'GET') {
        let url = `https://${this.endpoint}/v2/${_interface}`;
        let headers = {
            'Authorization': 'Bearer ' + this.options.accessToken,
            'Amazon-Advertising-API-ClientId': this.options.clientId,
            'Content-Type': 'application/json',
        }

        if (this.options.profileId) {
            headers['Amazon-Advertising-API-Scope'] = this.options.profileId;
        }

        let requestOptions={
            url: url,
            headers: headers,
            method: method,
            gzip: true,
        }

        if (method=="GET") {
            requestOptions.qs=data;
        }else{
            requestOptions.json=data;
        }

        let response = await requestPromise(requestOptions)

        let resData = response.body;

        if (!resData.error) {
            return resData;
        } else {
            throw resData.error;
        }

    }
}

I call the code via the function:

let reportResult = await client.getReport(reportID);

And this is the result I am getting:

{
  success: false,
  code: 200,
  response: '\u001f�\b\u0000\u0000\u0000\u0000\u0000\u0000\u0000���j�@\u0010\u0006�{�B<�\u0010�������P�\u0016�[���M�F\r\u001a\u000b����\u0002y�nӖ�!�7����7�O\u001faRT�p�Fa\u0012g�8}�g�p\u0002H\\\u0019�H�����.M^��4ۗ���"�Z�\u0016q��I8��MR:��y3�\u001a/�F�P3\u0004�C�\u0017�t\\\u0017Y\u001a��\u001b��v��Hf��(`��0�+֧�g�8��]\u000b\u0019\u0013�\u001d-I\u001b.%��g��`���$���\u001f(��f~�tʐ�`H�/C���\u0011�>\u0014M\u0000�Fw\f��\u001b\u0018���\f�71`.���]Ev9[4\r1��5��!�˥�i\u0018�m�\u001c�R�=3��I�VL(����t�~sm_��\\i!\u0005\n' +
    '�٠�aU���=��e�\u0007KW�Ypk�z(��Q��\u0003\u0013$`�em\u0010�\u0018=�d�����}���y3��\u000b.��=9\u0004\u0000\u0000',
  requestId: 0
}

I played around with zlib as well but only get the error Error: unexpected end of file

I am pretty new to nodeJS and really have no idea what the issue is.

Thanks a lot in advance for your help!

Jamal
  • 229
  • 2
  • 5

1 Answers1

1

The body is a gzip'ed (compressed) JSON. You need to gunzip it first.

If you use amazon-advertising-api-sdk package, it will do this automatically for you.

moltar
  • 1,372
  • 1
  • 11
  • 18
  • Hi moltar, What is the fastest way to download the last 60 days Report Data. I tried using ASYNCIO method in Python But its not working. Thanks in advance. – Prasand Kumar Jul 23 '21 at 20:49