• If you need help or want to discuss things, you now can also join us on our Discord Server!
  • A first preview of the unlimited version of SinusBot can be found in the Upcoming Changes thread. A version for Windows will follow, but we don't have a release date, yet.

EN Learning some javascript, JSON issues.

So I currently have some code that loads data from an API using the http.simpleRequest method. When I check the data on the API manually, I get something like this:

{"status":"ok","meta":{"count":2},"data":[{"nickname":"foo","account_id":999999999},{"nickname":"bar","account_id":000000000}]}

I assume this to be something that I could easily use JSON.parse on, but that doesn't seem to yield the desired result.
Here is relevant parts of code that are yielding unexpected results.
JavaScript:
function setClientWN8() {
        backend.getClients().forEach(client => {
            var nameClient = client.name();
            var clientResponse;
            engine.log(nameClient);
            var urlCheck=apiURL+region+'/wot/account/list/'+apikey+'&search='+nameClient;
            engine.log(urlCheck);
            var clientFound=getClientInfo(urlCheck);
                engine.log(clientFound);
                if (clientFound["meta"]["count"]!=0) { //<-clientFound.meta is undefined w/o jsonparse
                    //irrelevant for rest of this function, skipping to other function

function getClientInfo(url){
    http.simpleRequest({
                method: 'GET',
                timeout: 60000,
                url: url
                
            },
            function (error, clientInfoResponse) {
                engine.log(clientInfoResponse);//this does not look as expected, see below
                clientInfo=JSON.parse(clientInfoResponse);//this errors
                return clientInfo;
            });

This is the JSON.parse error -> Unexpected token u in JSON at position 0 Stack trace: SyntaxError: Unexpected token u in JSON at position 0 at JSON.parse (<anonymous>)

and this is the engine.log(clientInfoResponse) -> {"data":{},"headers":{"Access-Control-Allow-Origin":["*"],"Access-Control-Request-Method":["GET, POST"],"Connection":["keep-alive"],"Content-Language":["en"],"Content-Length":["148"],"Content-Type":["application/json; charset=utf-8"],"Date":["Mon, 25 Feb 2019 05:08:20 GMT"],"Etag":["\"a172cdf798e4f724b2d0d9464c458ac8\""],"Server":["nginx"],"X-Api-Version":["2.65.0"]},"status":"200 OK","statusCode":200}

I'm sure I am missing something obvious but I am at a loss. Off to bed, look forward to seeing responses in the morning!
 

Multivitamin

Well-Known Member
Tier III
is awesome!
V.I.P.
is uber awesome!
Contributor
Insider
the response you get is an object not a string, i would like to recommend you to use the alpha sinusbot version then you can use this function

when using the 1.0.0.alpha build then do not forget to add this line requiredModules: ["http"], where your vars, author, name, description etc is

a http request will then look like this

JavaScript:
const http = require("http")
http.simpleRequest({
  method: "GET",
  url: `https://example.com`
}, (err, res) => {
  if (err) throw new Error(err)
  if (res.statusCode !== 200) {
    //handle a status code which is is not 200
    return
  }
  let data = ""
  try {
    data = JSON.parse(res.data.toString())
  } catch (e) {
    //JSON parsing error the response was not parsed successfully
    throw new Error("JSON parsing Error")
  }
  //the variable "data" now has the parsed result
})
 
I hate to ask for help that is not specifically related to the function of sinusbot scripts, but I am running into errors when trying to pass data between functions such as 'undefined' for variables that I have assigned certain data to. I don't know how to resolve this. It is kind of messy from me testing various ways of avoiding the errors. One spot as a 'for example' is at line 73 (although errors may occur before that) where I am told that WN8 is undefined and therefore the description cannot be set.
JavaScript:
registerPlugin({
    name: 'TS Stats',
    version: '0.0.1',
    description: 'Automatic TS Stats',
    author: 'Josh <[email protected]>',
    requiredModules: ["http", "backend"],
    backends: ['ts3'],
    vars: [{
        name: 'clanServerGroup',
        title: 'clan Server Group ID',
        type: 'string'
    },{
        name: 'clanIDNum',
        title: 'Clan ID(in url of clan page https://i.imgur.com/qWBn3Ia.png)',
        type: 'string'
    },{
        name: 'region',
        title: 'Region of clan',
        type: 'select',
        options: ['RU','EU','NA','ASIA']
    },{
        name: 'apikey',
        title: 'WG API key (get one at https://developers.wargaming.net)',
        type: 'string'
    },{
        name: 'updatePeriod',
        title: 'Update Period (mins)',
        type: 'number',
        placeholder: '10'
    }]
},
function(sinusbot, config) {
    var http = require('http');
    var backend = require('backend');
       var engine = require('engine');
    var regionArr = ['ru','eu','com','asia'];
    var apiURL = "https://api.worldoftanks.";
    var region = regionArr[config.region];
    var apikey = "?application_id="+config.apikey;
    var tankValues;
    getTankValues('https://static.modxvm.com/wn8-data-exp/json/wn8exp.json');
    function getTankValues(url) {
    http.simpleRequest({
            method: 'GET',
            timeout: 60000,
            url: url
        },(error, tankValuesResponse) =>{
            //engine.log(JSON.parse(tankValuesResponse.data.toString()))
          tankValues = JSON.parse(tankValuesResponse.data.toString());
         return;
        })
    }

    function setClientWN8() {
        backend.getClients().forEach(client => {
            var nameClient = client.name();
            var clientResponse;
            engine.log(nameClient);
            var urlCheck=apiURL+region+'/wot/account/list/'+apikey+'&search='+nameClient;
            engine.log(urlCheck);
            http.simpleRequest({
                method: 'GET',
                timeout: 60000,
                url: urlCheck
               
            },(error, clientInfoResponse)=> {
                clientFound=JSON.parse(clientInfoResponse.data.toString());
                engine.log(clientFound);
                if (clientFound["meta"]["count"]!=0) {
                    var clientWOTName = clientFound.data[1].nickname;
                    var clientIDNum = clientFound.data[1].account_id;
                    var WN8 = calcWN8(clientIDNum);
                    backend.client.setDescription(WN8 + ' WN8');
                    if (WN8<=1000) {
                backend.client.addToServerGroup(9408);
        }else if (WN8<=1199){
                backend.client.addToServerGroup(9409);
        }else if (WN8<=1599) {
                backend.client.addToServerGroup(9410);
        }else if (WN8<=1999){
                backend.client.addToServerGroup(9411);
        }else if (WN8<=2449) {
            backend.client.addToServerGroup(9412);
        }else if (WN8<=2899) {
            backend.client.addToServerGroup(9413);
        }else{
            backend.client.addToServerGroup(9414);
                }
        }
        })
        })
    }
    function getClientInfo(url){
    http.simpleRequest({
                method: 'GET',
                timeout: 60000,
                url: url
               
            },(error, clientInfoResponse)=> {
                clientInfo=JSON.parse(clientInfoResponse.data.toString());
                engine.log(clientInfo);
                return clientInfo;
            });
}
function calcWN8(playerNum){
        var totalBattles=0;
        var playerBattles=0;
        var playerFrag=0;
        var playerDef=0;
        var playerSpot=0;
        var playerDmg=0;
        var playerWR=0;
        var numTanks=0;
        var tankWN8=0;
        var colorWN8;
        var playerTanks=getPlayerTanks(playerNum);
        http.simpleRequest({
            method: 'GET',
            timeout: 60000,
            url: apiURL+region+'/wot/tanks/stats/'+apikey+'&account_id='+playerNum+'&fields=random,tank_id&extra=random'
        },
        function (error, tankStatsResponse) {
            var tankStats = JSON.parse(tankStatsResponse.data.toString());
            //engine.log(tankStats)
            engine.log(tankValues)
            for (i in tankValues.data) {
            for (x in tankStats["data"][playerNum]) {
                if (tankValues.data[i].IDNum==playerTanks["data"][playerNum[x]][tank_id]) {
                    var xFrag=tankValues.data[i].expFrag;
                    var xDef=tankValues.data[i].expDef;
                    var xSpot=tankValues.data[i].expSpot;
                    var xDmg=tankValues.data[i].expDamage;
                    var xWR=tankValues.data[i].expWinRate;
                    for (y in tankValues.data) {
                        if (playerTanks["data"][playerNum[x]][tank_id]==tankStats["data"][playerNum[y]][tank_id]) {
                            playerBattles=tankStats["data"][playerNum[y]]["random"]["battles"];
                            break
                        }
                       
                    }
                    playerFrag=playerFrag+xFrag*playerBattles;
                    playerDef=playerDef+xDef*playerBattles;
                    playerSpot=playerSpot+xSpot*playerBattles;
                    playerDmg=playerDmg+xDmg*playerBattles;
                    playerWR=playerWR+xWR*playerBattles;
                }
            }
            }
            var overalls= getOveralls(playerNum);
            totalBattles=overalls["data"][playerNum]["statistics"]["random"]["battles"];
            var calculatedWins=100*(overalls["data"][playerNum]["statistics"]["random"]["wins"]);
            var rFrag=(overalls["data"][playerNum]["statistics"]["random"]["frags"])/playerFrag;
            var rDef=(overalls["data"][playerNum]["statistics"]["random"]["dropped_capture_points"])/playerDef;
            var rSpot=(overalls["data"][playerNum]["statistics"]["random"]["spotted"])/playerSpot;
            var rDmg=(overalls["data"][playerNum]["statistics"]["random"]["damage_dealt"])/playerDmg;
            var rWR=calculatedWins/playerWR;
            var rWRc=(rWR-0.71)/(1-0.71);
            var rDmgc=max(0,(rDmg-0.22)/(1-0.22));
            var rFragc=max(0,min(rDmgc+0.2,(rFrag-0.12)/(1-0.12)));
            var rSpotc=max(0,min(rDmgc+0.1,(rSpot-0.38)/(1-0.38)));
            var rDefc=max(0,min(rDmg+0.1,(rDef-0.1)/(1-0.1)));
            tankWN8=(980*rDmgc+210*rDmgc*rFragc+155*rFragc*rSpotc+75*rDefc*rFragc+145*min(1.8,rWRc))+tankWN8;
        tankWN8=Math.round(tankWN8);
        if (totalWN8<=1000) {
                colorWN8='[color=#ccb800]';
        }else if (totalWN8<=1199){
                colorWN8='[color=#849b24]';
        }else if (totalWN8<=1599) {
                colorWN8='[color=#4d7326]';
        }else if (totalWN8<=1999){
                colorWN8='[color=#4099bf]';
        }else if (totalWN8<=2449) {
            colorWN8='[color=#3161ab]';
        }else if (totalWN8<=2899) {
            colorWN8='[color=#60249b]';
        }else{
            colorWN8='[color=#401070]';
        }
        var textOut='https://wotlabs.net/na/player/'+getPlayerName(playerNum)+' '+colorWN8+tankWN8+'[/color]';
        return tankWN8;
        });
       
       
    }
    function getOveralls(playerNum) {
        http.simpleRequest({
            method: 'GET',
            timeout: 60000,
            url: apiURL+region+'/wot/account/info/'+apikey+'&extra=statistics.random&fields=account_id%2Cstatistics.random&account_id='+playerNum
        },function (error, playerOverallsResponse) {
            return JSON.parse(playerOverallsResponse.data.toString());
        });      
    }
    function getPlayerName(playerNum) {
        http.simpleRequest({
            method: 'GET',
            timeout: 60000,
            url: apiURL+region+'/wgn/account/info/'+apikey+'nickname&account_id='+playerNum
        },function (error, playerNameResponse) {
            nameJSON=JSON.parse(playerNameResponse);
            return nameJSON["data"][playerNum]["nickname"];
        });      
    }
    function getPlayerTanks(playerNum){
        http.simpleRequest({
            method: 'GET',
            timeout: 60000,
            url:apiURL+region+'/wot/tanks/stats/'+apikey+'&account_id'+playerNum+'&fields=tank_id'
        },function (error, playerTanksResponse) {
            var tanks = JSON.parse(playerTanksResponse.data.toString());

        return tanks;
       
    });
    }
   
        setInterval(function refreshWN8(){
        setClientWN8();
        engine.log("check");
    }, config.updatePeriod * 60000);
});
I believe I need to use something called 'callbacks' but I don't know how that helps me after looking into it.
 

Diesmon

Tuetchen Dominator
is awesome!
Contributor
Insider
You misreading the error log:

The logs says probably that the code is unable to execute .setDescription of undefined. Because settings an undefined (empty) description is totally valid and would be executed without a problem.

But your syntax is wrong. backend.client does not exist.
Therefore there is no function .setDescription, because backend.client is equal to undefined. (Can't execute a function of a non existing object/class)

To make your code work, just simply removed the "backend." part from your call:
backend.client.setDescription(...) ==> client.setDescription(...)
This is because the setDescription is a function only available to the client object, not the backend.client which doesn't exist.

For further documentation and available functions for the different module/object see the docs:
backend object: https://sinusbot.github.io/scripting-docs/#backend
client object/setDescription: https://sinusbot.github.io/scripting-docs/#clientsetdescription
 
Top