Issue with creating a loop of messages

Hi,

i'm currently stuck with a flow, that creates a message sequence within a function block.

I want to send messages through the Threema API Gateway. My issue is, that due to the limitations of the gateway i need to send a message for each receipient (don't ask why).

So i have created a function block, that generates the payload for the Threema gateway. But each time i run the flow, the payload gets only generated for the last ID. It seems somehow, that the for each loop is somehow wrong, or i'm making something specific wrong.

Can anyone help me? I think it's a super easy issue.

Thanks and BR,
Michael

[
    {
        "id": "c498af33053021f0",
        "type": "http in",
        "z": "61c099bc8a5603ed",
        "name": "",
        "url": "/threema-orga",
        "method": "post",
        "upload": false,
        "swaggerDoc": "",
        "x": 150,
        "y": 120,
        "wires": [
            [
                "490a78e806b5f529"
            ]
        ]
    },
    {
        "id": "b1473b042df0bd27",
        "type": "http request",
        "z": "61c099bc8a5603ed",
        "name": "Threema-Gateway-Basic",
        "method": "POST",
        "ret": "obj",
        "paytoqs": "body",
        "url": "https://msgapi.threema.ch/send_simple",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "senderr": false,
        "x": 790,
        "y": 240,
        "wires": [
            [
                "58072af40205eb98",
                "ebe1aa117fd28da2"
            ]
        ]
    },
    {
        "id": "8220b91d97ead85d",
        "type": "function",
        "z": "61c099bc8a5603ed",
        "name": "CreateThreemaPayload",
        "func": "let toArray = [ \"ABCDEF\", \"FEDCBA\" ];\n\nif (msg.payload.content.items.length > 0 && msg.payload.content.items[0].state != \"confirmed\"){\n    return;\n}\n\nlet msgArray = [];\nlet msgIndex = 0;\nfor (const to of toArray) {\n    let from = \"*FUCSCLD\";\n    let text = \"\";\n    let secret = \"redacted\";\n    let payload = msg.payload;\n    if (payload.message){\n        let user = payload.account.user;\n        let titles = payload.content.items.map(i => i.name).join(', ');\n        text += `👋 ${user} hat *${titles}* aktualisiert.\\n`;\n        let content = payload.content;\n        if (content.added && content.added.length > 0) {\n            let addedTags = content.added.map(t => t.name).join(', ');\n            text += `🔖  Tags hinzugefügt: ${addedTags}\\n`;\n        }\n        if (content.removed && content.removed.length > 0) {\n            let removedTags = content.removed.map(t => t.name).join(' ');\n            text += `🗑️ Tags entfernt: ${removedTags}\\n`;\n        }\n        if (content.itemUrl && content.items) {\n            let docUrls = content.items\n                .map(i => `${content.itemUrl}/${i.id}`)\n                .join(', ');\n            text += \"🌍 Link zum Dokument: \";\n            text += `${docUrls}`;\n        }\n        text = text.trim();\n    }\n    \n    msg.payload = `to=${to}&text=${text}&from=${from}&secret=${secret}`;\n    msg.headers = { \n        \"content-type\": \"application/x-www-form-urlencoded; charset=utf-8\" \n    };\n    msg.parts = { \n        \"id\": to,\n        \"index\": msgIndex++,\n        \"count\": toArray.length\n    }\n    msgArray.push(msg)\n}\n\nreturn msgArray;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 470,
        "y": 240,
        "wires": [
            [
                "a2bd49989a19b46f",
                "b1473b042df0bd27"
            ]
        ]
    },
    {
        "id": "58072af40205eb98",
        "type": "http response",
        "z": "61c099bc8a5603ed",
        "name": "",
        "statusCode": "",
        "headers": {},
        "x": 1030,
        "y": 240,
        "wires": []
    },
    {
        "id": "a2bd49989a19b46f",
        "type": "debug",
        "z": "61c099bc8a5603ed",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 670,
        "y": 120,
        "wires": []
    },
    {
        "id": "ebe1aa117fd28da2",
        "type": "debug",
        "z": "61c099bc8a5603ed",
        "name": "Threema-Gateway-Response",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1150,
        "y": 320,
        "wires": []
    },
    {
        "id": "dd9881d750617ca6",
        "type": "catch",
        "z": "61c099bc8a5603ed",
        "name": "",
        "scope": null,
        "uncaught": false,
        "x": 780,
        "y": 440,
        "wires": [
            [
                "374d62d53aeb9d52",
                "0b98194c50dd5e02"
            ]
        ]
    },
    {
        "id": "374d62d53aeb9d52",
        "type": "http response",
        "z": "61c099bc8a5603ed",
        "name": "",
        "statusCode": "500",
        "headers": {},
        "x": 1040,
        "y": 440,
        "wires": []
    },
    {
        "id": "490a78e806b5f529",
        "type": "switch",
        "z": "61c099bc8a5603ed",
        "name": "filter for eventType",
        "property": "payload.eventType",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "TagsChanged",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 330,
        "y": 180,
        "wires": [
            [
                "8220b91d97ead85d",
                "066f6795a4c96f36"
            ]
        ]
    },
    {
        "id": "0b98194c50dd5e02",
        "type": "debug",
        "z": "61c099bc8a5603ed",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 950,
        "y": 380,
        "wires": []
    },
    {
        "id": "ce44bd897e227c52",
        "type": "inject",
        "z": "61c099bc8a5603ed",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"message\":{\"title\":\"TagsChanged (by *Michael*)\",\"body\":\"Adding *Receipt*; Removing *Invoice* on [`MapleSirupLtd_202331.pdf`](https://docs.fuchscloud.de/app/item/BUYteMPs2F8-PQQKxQjjSd2-R9EkRctzg8j-hQdM9svoq82).\"},\"messageHtml\":{\"title\":\"<p>TagsChanged (by <em>Michael</em>)</p>\",\"body\":\"<p>Adding <em>Receipt</em>; Removing <em>Invoice</em> on <a href=\\\"https://docs.fuchscloud.de/app/item/BUYteMPs2F8-PQQKxQjjSd2-R9EkRctzg8j-hQdM9svoq82\\\"><code>MapleSirupLtd_202331.pdf</code></a>.</p>\"},\"eventType\":\"TagsChanged\",\"account\":{\"collective\":\"fuchscloud\",\"user\":\"Michael\",\"login\":\"fuchscloud/Michael\"},\"content\":{\"account\":{\"collectiveId\":3,\"collective\":\"fuchscloud\",\"userId\":\"8Xmbmh2td56-QKmPD4sgJrA-efKchSPHRej-j2fe3MuGyQd\",\"login\":\"Michael\"},\"items\":[{\"id\":\"BUYteMPs2F8-PQQKxQjjSd2-R9EkRctzg8j-hQdM9svoq82\",\"name\":\"MapleSirupLtd_202331.pdf\",\"dateMillis\":1704569295367,\"date\":\"2024-01-06\",\"direction\":\"incoming\",\"state\":\"confirmed\",\"dueDateMillis\":null,\"dueDate\":null,\"source\":\"webapp\",\"overDue\":false,\"dueIn\":null,\"corrOrg\":\"Acme AG\",\"notes\":null}],\"added\":[{\"id\":\"6pJ9CJJTQyR-j2ycebZx3FF-55Txdfrufmx-r9zxgz3Q6Hj\",\"name\":\"Receipt\",\"category\":\"doctype\"}],\"removed\":[{\"id\":\"3rGjYxdC1uN-1bj52m3h2ZG-zpg3T14fopi-jkQteAoZqEq\",\"name\":\"Invoice\",\"category\":\"doctype\"}],\"itemUrl\":\"https://docs.fuchscloud.de/app/item\"}}",
        "payloadType": "json",
        "x": 110,
        "y": 220,
        "wires": [
            [
                "490a78e806b5f529"
            ]
        ]
    },
    {
        "id": "066f6795a4c96f36",
        "type": "debug",
        "z": "61c099bc8a5603ed",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 490,
        "y": 120,
        "wires": []
    }
]

Objects are saved in arrays as references (pointers) to the same object.

Clone the msg object before any adjustments and pushing it into the array.

const m = RED.util.cloneMessage(msg)
m.payload = "xxx" // change stuff
myArray.push(m)

Hey,

thanks. That actually helped me to a bit. But i'm still stuck in creating/processing multiple messages.
My problem is, i'm getting a single message and during the CreateThreemaPayload block i'm virtually generating more messages - for each ID i'm creating one message.
How do i process each message, in a way that a POST-Request is sent for each message?

change the last line to

return [msgArray];

its all explained in the docs :wink:

1 Like

Yes,that's what I did. And now it works! Thanks a lot!

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