Stucked with "global" / "flow" object array

Hello !
Thank you in advance for being patient. I'm not familiar with javascript and I've just started the node-red world.
About my project: i'm developing a bot for telegram with the powerful Red-bot:
GitHub - guidone/node-red-contrib-chatbot: Visually build a full featured chat bot for Telegram, Facebook Messenger and Slack with Node-RED. Almost no coding skills required. (take a look, it is an AMAZING job)
Here the flows:


The sense of the bot is that it must intercept the blasphemies and scold the blasphemer (this he does).
What I want is to know for each user how many blasphemies he said and make a ranking among the members of the group.
I realize it sounds very silly, but I'm working hard to practice of course, and i can't store this information.
Here my attempt of a function node,

var nB = {                                                  //an object and it's 3 parameters
  name: msg.payload.userN,
  sur: msg.payload.userS,
  count: 1
};

//If not define the array notBless, create a empty array and simply add the nB

if (context.get("notBless") === undefined) {
    context.set("notBless", []);
    notBless.push(nB);
}
console.log(notBless.lenght);

//if the array is define, i look if the guy is a new blasphemous add it, if he is recidivist increase the count of profanity.

for(var i=0; i<notBless.lenght; i++){
    if(notBless[i].name == msg.payload.userN){
        notBless[i].count +=1;
        console.log(notBless[i].count);
        context.set("notBless",notBless,"notBless");
        return msg;
    }
}
notBless.push(nB);
context.set("notBless",notBless,"notBless");
console.log(notBless);
return msg;

Any suggestion for a fool who hasn't slept much since last night?

thank you for your time.

Hi, I would try to store the names and count of the individuals in a flow context then it becomes simple to just add one to their count. Using their name as a the count key.
eg.

[{"id":"56c05ab2.3c0c8c","type":"inject","z":"5a245aa1.510164","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"userN\": \"Daniel\", \"userS\": \"Lion\"}","payloadType":"json","x":120,"y":3940,"wires":[["e7dcc0a1.68c938"]]},{"id":"e7dcc0a1.68c938","type":"function","z":"5a245aa1.510164","name":"","func":"let name = \"notBless.\" + msg.payload.userN + \"_\" + msg.payload.userS;\nnotBless = flow.get(name) || 0;\nflow.set(name, notBless+1);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":330,"y":3920,"wires":[["634324ba.97c454"]]},{"id":"1788210a.056237","type":"inject","z":"5a245aa1.510164","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"userN\": \"Sadrack\", \"userS\": \"Fire\"}","payloadType":"json","x":110,"y":3980,"wires":[["e7dcc0a1.68c938"]]},{"id":"634324ba.97c454","type":"debug","z":"5a245aa1.510164","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"$flowContext(\"notBless\")","targetType":"jsonata","statusVal":"","statusType":"auto","x":490,"y":3920,"wires":[]}]

Each inject is a different name.

This is a simple example and you could add more checks to make sure incoming data is correct first.

let name = "notBless." + msg.payload.userN + "_" + msg.payload.userS;
let notBless = flow.get(name) || 0;
flow.set(name, notBless+1);
return msg;
1 Like

First of all, thank you again.
I tried to not borrow you, but i'am far from this logic. I feel like a tennis ball bouncing off a wall.

Your code works well, finaly i have my global "notBless" setted.
But i'm failing any attenot to sorting this "notBless" by descending number.

I'm trying to not frankestein my code and i really need some direction to change my way to think.

CASE 1: The function node retrive, create a nice string, it will be sorted, with .sort()

notBless = flow.get("notBless") || 0;
//notBless.sort(function(a,b){return b - a}); // i tried this in a moment of try&error&despair
var str = "";
str =String(JSON.stringify(notBless));
console.log(str.valueOf());
str=str.replace("{","");
str=str.replace("}","");
//str=str.replace(",","");
str=str.replace(/['"]+/g, '');
//console.log(str.valueOf().length);
//arr=str.split(",");
//arr = arr.valueOf();
//console.log(arr);
//console.log(arr.length);
/*
str="[\n";
for(var i =0; i<arr.length;i++ ){
    var spl = arr[i].split(":");
    console.log(spl);
    if(i<arr.length){
        str +="{name:"+ spl[0] +", best:"+spl[1]+"},";   }
    else{
        str+="{name:"+ spl[0]+", best:"+spl[1]+"}\n]";
    }
}*/
//console.log(str);

//var obj= JSON.parse(names);
//obj.sort(function(a, b){return b.best - a.best});
msg.payload =str;
return msg;

no way to use .lenght as old Java's String .lenght().

CASE 2
Same logic but with nodes, but how i can split and sort that thing? This my best approach to the goal.

[{"id":"56c05ab2.3c0c8c","type":"inject","z":"5a245aa1.510164","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"userN\": \"Daniel\", \"userS\": \"Lion\"}","payloadType":"json","x":120,"y":3940,"wires":[["e7dcc0a1.68c938"]]},{"id":"e7dcc0a1.68c938","type":"function","z":"5a245aa1.510164","name":"","func":"let name = \"notBless.\" + msg.payload.userN + \"_\" + msg.payload.userS;\nlet notBless = flow.get(name) || 0;\nflow.set(name, notBless+1);\nlet sortBless = flow.get(\"notBless\");\nmsg.payload = Object.entries(sortBless).sort(function(a, b) { \nreturn b[1] - a[1]});  ///msg.payload[0][0] will give name of highest non-blessed\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":330,"y":3920,"wires":[["634324ba.97c454"]]},{"id":"1788210a.056237","type":"inject","z":"5a245aa1.510164","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"userN\": \"Sadrack\", \"userS\": \"Fire\"}","payloadType":"json","x":110,"y":3980,"wires":[["e7dcc0a1.68c938"]]},{"id":"634324ba.97c454","type":"debug","z":"5a245aa1.510164","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":690,"y":3900,"wires":[]}]
let name = "notBless." + msg.payload.userN + "_" + msg.payload.userS;
let notBless = flow.get(name) || 0;
flow.set(name, notBless+1);
let sortBless = flow.get("notBless");
msg.payload = Object.entries(sortBless).sort(function(a, b) { 
return b[1] - a[1]});  ///msg.payload[0][0] will give name of highest non-blessed
return msg;

msg.payload[0][0] returns the name of highest
msg.payload[1][0] returns name of second highest
msg.payload[0][1] returns count of highest

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.