Call service node not replacing {{payload}} with content of payload

Hi everyone

I have built a flow in node red to play a message via my Google Home when I arrive home.

I have a function node which prepares the message and passes it through in msg.payload then a call service node to call the speak service using Piper to generate the audio.

Here’s a simplified version of the flow. The real function has logic in it to create a custom message depending on a number of entities and global variables, but for simplicity I am just passing basic text in this example.

When I run this, the Google Home just says payload rather than the payload content which is Welcome home.

Any ideas what I’m doing wrong here?

[{"id":"7f5c54f7f8a681b9","type":"api-call-service","z":"98224c63c49e6306","name":"voice alert","server":"b1fcdc06.6fce2","version":5,"debugenabled":true,"domain":"tts","service":"speak","areaId":[],"deviceId":[],"entityId":["tts.piper"],"data":"{\t   \"message\": \"{{payload}}\",\t   \"media_player_entity_id\": \"media_player.kitchen_speaker\"\t}","dataType":"jsonata","mergeContext":"","mustacheAltTags":true,"outputProperties":[],"queue":"none","x":770,"y":2380,"wires":[[]]},{"id":"3c924a8068ee8285","type":"function","z":"98224c63c49e6306","name":"prepare voice message","func":"var voice_message = 'Welcome home. ';\n\nmsg.payload = voice_message;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":550,"y":2380,"wires":[["7f5c54f7f8a681b9"]]},{"id":"365bcfebff306cea","type":"inject","z":"98224c63c49e6306","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":340,"y":2380,"wires":[["3c924a8068ee8285"]]},{"id":"b1fcdc06.6fce2","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

You have the data field type set to JSONata. Which doesn’t use mustache templates.

{
  "message": payload,
  "media_player_entity_id": "media_player.kitchen_speaker"
}

Or use what you have and change the data field type to JSON.

Great, thank you very much! I thought it needed to be JSONata to understand the payload reference, but that isn’t quite the case.

Thanks for your help!