Msg.payload send base64-encoded URL to http request

Hi,

spotify stores album covers on the localhost. I’m able to retrieve the URL by using a sensor. Now I want to use Node-RED to retrieve the image and save it to the local storage to use espHOME to display the picture on an epaper.

Currently the “trigger: state”-node send the URL to the “http request” node within the msg.payload. The “debug” node shows it without base64 encoding. But the “http request” cannont use the url - its invalid. And the Url starts with 2x http.

[node: dbgSpotify]
http://homeassistant.local:8123/api/media_player_proxy/media_player.sonos?token=***&cache=3e374221731ddb45.jpg

[node: localhost] - msg : error
“TypeError: Invalid URL:
http://http://homeassistant.local:8123/api/media_player_proxy/media_player.sonos?token=***&cache=3e374221731ddb45.jpg”

[
    {
        "id": "49133e8f8a330893",
        "type": "tab",
        "label": "SaveAlbumArt",
        "disabled": false,
        "info": ""
    },
    {
        "id": "579cdc752b2948a2",
        "type": "trigger-state",
        "z": "49133e8f8a330893",
        "name": "Spotify",
        "server": "37ca2604.2a94ea",
        "version": 0,
        "exposeToHomeAssistant": false,
        "haConfig": [
            {
                "property": "name",
                "value": ""
            },
            {
                "property": "icon",
                "value": ""
            }
        ],
        "entityid": "sensor.album_art",
        "entityidfiltertype": "exact",
        "debugenabled": false,
        "constraints": [],
        "outputs": 2,
        "customoutputs": [],
        "outputinitially": false,
        "state_type": "str",
        "x": 170,
        "y": 80,
        "wires": [
            [
                "08bc9cf38db69974",
                "d6c79fc42bb02d8f"
            ],
            []
        ]
    },
    {
        "id": "08bc9cf38db69974",
        "type": "debug",
        "z": "49133e8f8a330893",
        "name": "dbgSpotify",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 310,
        "y": 180,
        "wires": []
    },
    {
        "id": "d6c79fc42bb02d8f",
        "type": "http request",
        "z": "49133e8f8a330893",
        "name": "localhost",
        "method": "GET",
        "ret": "bin",
        "paytoqs": "ignore",
        "url": "{{payload}}",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "x": 460,
        "y": 40,
        "wires": [
            []
        ]
    },
    {
        "id": "37ca2604.2a94ea",
        "type": "server",
        "name": "Home Assistant",
        "version": 1,
        "addon": true,
        "rejectUnauthorizedCerts": true,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": false,
        "cacheJson": true
    }
]

What I can do to retrieve the URL without base64-encoding and just one http?

Thank you
Matthias

how do you know it’s base64 encoded?

The forum editor replaced it:

"TypeError: Invalid URL: http://http://homeassistant.local:8123/api/media_player_proxy/media_player.sonos?token=_token_&cache=c3fbe5154f3b8907.jpg"

It’s not base64. it’s html entity encoded.
You can use html entities node to decode it

Thank you for your help. I added the node to my my flow, but it’s still the same behaviour

[
    {
        "id": "49133e8f8a330893",
        "type": "tab",
        "label": "SaveAlbumArt",
        "disabled": false,
        "info": ""
    },
    {
        "id": "579cdc752b2948a2",
        "type": "trigger-state",
        "z": "49133e8f8a330893",
        "name": "Spotify",
        "server": "4e19419ffbf53bf8",
        "version": 0,
        "exposeToHomeAssistant": false,
        "haConfig": [
            {
                "property": "name",
                "value": ""
            },
            {
                "property": "icon",
                "value": ""
            }
        ],
        "entityid": "sensor.album_art",
        "entityidfiltertype": "exact",
        "debugenabled": false,
        "constraints": [],
        "outputs": 2,
        "customoutputs": [],
        "outputinitially": false,
        "state_type": "str",
        "x": 190,
        "y": 180,
        "wires": [
            [
                "08bc9cf38db69974",
                "1627c969a18faeaf"
            ],
            []
        ]
    },
    {
        "id": "08bc9cf38db69974",
        "type": "debug",
        "z": "49133e8f8a330893",
        "name": "dbgSpotify",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 330,
        "y": 280,
        "wires": []
    },
    {
        "id": "1627c969a18faeaf",
        "type": "html-entities",
        "z": "49133e8f8a330893",
        "name": "htmlEntity",
        "property": "payload",
        "mode": "decode",
        "optionsStrict": false,
        "optionsUseNamedReferences": false,
        "optionsPreferDecimal": false,
        "optionsEncodeEverything": true,
        "optionsAllowUnsafeSymbols": false,
        "optionsIsAttributeValue": true,
        "x": 360,
        "y": 160,
        "wires": [
            [
                "f5961d299e1ca952",
                "3f552563d9ea0563"
            ]
        ]
    },
    {
        "id": "3f552563d9ea0563",
        "type": "debug",
        "z": "49133e8f8a330893",
        "name": "dbgEntity",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 520,
        "y": 40,
        "wires": []
    },
    {
        "id": "f5961d299e1ca952",
        "type": "http request",
        "z": "49133e8f8a330893",
        "name": "getImage",
        "method": "GET",
        "ret": "txt",
        "paytoqs": "ignore",
        "url": "{{payload}}",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "x": 610,
        "y": 160,
        "wires": [
            []
        ]
    },
    {
        "id": "4e19419ffbf53bf8",
        "type": "server",
        "name": "Home Assistant",
        "version": 1,
        "legacy": false,
        "addon": true,
        "rejectUnauthorizedCerts": true,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": true,
        "cacheJson": true
    }
]

With this output

24.8.2021, 21:39:55node: dbgSpotify
sensor.album_art : msg.payload : string[171]
"http://homeassistant.local:8123/api/media_player_proxy/media_player.sonos?token=<Token>&cache=bd41463d42c33404.jpg"
24.8.2021, 21:39:55node: getImage
msg : error
"TypeError: Invalid URL: http://http:&#x2F;&#x2F;homeassistant.local:8123&#x2F;api&#x2F;media_player_proxy&#x2F;media_player.sonos?token&#x3D;<Token>&amp;cache&#x3D;bd41463d42c33404.jpg"
24.8.2021, 21:39:55node: dbgEntity
sensor.album_art : msg : Object
{ topic: "sensor.album_art", payload: "http://homeassistant.local:812…", data: object, _msgid: "f72b42df8a40175d" }

Try using {{{payload}}} inside the http node. So it ignores the “/” character. This should at least solve the double http: issue

Edit: This is also mentioned in the nodes description

Here is my test based on your flow:

  1. decoding of html entities works properly, either with your example or mine.
  2. change settings of http request node as Syntox is suggesting.

[{"id":"9e6e613e.d7b03","type":"tab","label":"SaveAlbumArt","disabled":false,"info":""},{"id":"3cc753f3.1964ec","type":"trigger-state","z":"9e6e613e.d7b03","d":true,"name":"Spotify","server":"4e19419ffbf53bf8","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityid":"sensor.album_art","entityidfiltertype":"exact","debugenabled":false,"constraints":[],"outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","x":150,"y":160,"wires":[["14d0756d.dd5d7b","5b8a18e7.decac8"],[]]},{"id":"14d0756d.dd5d7b","type":"debug","z":"9e6e613e.d7b03","name":"dbgSpotify","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":330,"y":280,"wires":[]},{"id":"5b8a18e7.decac8","type":"html-entities","z":"9e6e613e.d7b03","name":"htmlEntity","property":"payload","mode":"decode","optionsStrict":false,"optionsUseNamedReferences":false,"optionsPreferDecimal":false,"optionsEncodeEverything":true,"optionsAllowUnsafeSymbols":false,"optionsIsAttributeValue":true,"x":360,"y":160,"wires":[["b8e820fb.475e3","9ee279a3.d184a8"]]},{"id":"9ee279a3.d184a8","type":"debug","z":"9e6e613e.d7b03","name":"dbgEntity","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":560,"y":50,"wires":[]},{"id":"b8e820fb.475e3","type":"http request","z":"9e6e613e.d7b03","name":"getImage","method":"GET","ret":"txt","paytoqs":"ignore","url":"{{{payload}}}","tls":"","persist":false,"proxy":"","authType":"","x":560,"y":160,"wires":[[]]},{"id":"8ed22f02.162","type":"inject","z":"9e6e613e.d7b03","name":"inject original url","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"http:&#x2F;&#x2F;homeassistant.local:8123&#x2F;api&#x2F;media_player_proxy&#x2F;media_player.sonos?token&#x3D;<Token>&amp;cache&#x3D;bd41463d42c33404.jpg","payloadType":"str","x":160,"y":60,"wires":[["5b8a18e7.decac8"]]},{"id":"d7b895b9.e82eb8","type":"inject","z":"9e6e613e.d7b03","name":"inject some test url","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"https:&#x2F;&#x2F;upload.wikimedia.org&#x2F;wikipedia&#x2F;commons&#x2F;thumb&#x2F;7&#x2F;73&#x2F;Flat_tick_icon.svg&#x2F;512px-Flat_tick_icon.svg.png","payloadType":"str","x":160,"y":110,"wires":[["5b8a18e7.decac8"]]},{"id":"4e19419ffbf53bf8","type":"server","name":"Home Assistant","legacy":false,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]

Thank you for the help. Now I got the next error:

"RequestError: getaddrinfo ENOTFOUND homeassistant.local"

node-red can’t resolve the url. When I insert a static URL to an image into the “http request”-node it works well and I’m able to store the file in my esphome-directory.

Edit: I added homeassistant.local to /etc/hosts but it won’t work.

Are you sure your URL works? You could test that with postman for example.
Testing with the browser should work theoretically as it is a GET request, but I don’t know what your browser could add to the request.
Another way would be to replace homeassistant.local with HA’s IP

Hi @Syntox,

I’ve used a function node and replaced the string homeassistant.local by the ip and it works. Maybe it depends to this issue.

After the workaround, I’ve realized that an epaper isn’t a good way to display images. A second problem ist, that esphome compile the image and transfer it to the module. So I’m not able to update the image, when I play the next track.

Finally I need to purchase another display and a way to update the image dynamically. But for now I’m a little bit mor familiar to node-red.

Thank you all for your help (maybe someone has a smart solution for the both open issues)
Matthias