openHAB, Telegram Bot and quoting URLs
A while ago I integrated DWD warnings (Deutscher Wetterdienst) into our home automation system, and receive severe weather notifications ever since then. That works quite good, but it was missing a weblink with more details - or if you want to forward the warning to someone it would be useful to have a link to the warning as well. The DWD binding does not provide that piece of information, but it is easy enough to add - or so I thought.
In my setup I roll out the rules file with Ansible, which lets me loop over all the locations I'm interested in. I expanded the $dwds variable with an additional link:
{% set dwds = [('Ort 1', 'ort1', '111000001', 'https://www.dwd.de/DE/wetter/warnungen_gemeinden/warnWetter_node.html?ort=Halle%20(Saale)'),
('Ort 2', 'ort2', '111000002', '...'),
('Ort 3', 'ort3', '111000003', '...'),
('Ort 4', 'ort4', '111000004', '...')
] %}
So far this is easy, and I only need to attach the link to the Telegram message. First iteration:
meldung = meldung + Warning{{ dwd[1] }}Instruction{{ chan }}.state.toString
meldung = meldung + "\n\n" + "[Details]({{ dwd[3] }})"
logInfo("DWD", meldung)
The format the Telegram bot uses is "Markdown V2", and the [...](...) format adds a link (...) with a description in [...]. That however does not work, the Telegram API does not add the correct link (one closing parenthesis short), and the resulting link in the group is a 404.
A look into the documentation reveals:
Inside (...) part of inline link definition, all ')' and '\' must be escaped with a preceding '\' character.
Well, ok, let's escape the closing parenthesis and see where this goes. I'm doing that directly in Ansible:
meldung = meldung + "\n\n" + "[Details]({{ dwd[3] | replace(')', '\\)') }})"
However you can also do it in the rule DSL:
meldung = meldung + "\n\n" + "[Details](url.replace(')','\\)'))"
The debug output shows that the parenthesis is indeed escaped:
https://www.dwd.de/DE/wetter/warnungen_gemeinden/warnWetter_node.html?ort=Halle%20(Saale\)
But for reasons I'm unable to figure out, Telegram still shows the closing parenthesis. The URL however is still cut short by one parenthesis, and an additional "?" is added.
At this point, and after much debugging, I switched to URL escaping the characters. In Ansible:
meldung = meldung + "\n\n" + "[Details]({{ dwd[3] | replace('(', '%28') | replace(')', '%29') }})"
Or directly in the rule:
meldung = meldung + "\n\n" + "[Details](url.replace('(','%28').replace(')', '%29'))"
The debug output for the link is now:
https://www.dwd.de/DE/wetter/warnungen_gemeinden/warnWetter_node.html?ort=Halle%20%28Saale%29
And the correct link is added in Telegram:
Notes:
All URLs should be URL quoted, if they come from an external source. In this case I don't have to care about this, because I specify the URLs myself.
I could also add the quoted URLs directly to the $dwds variable - however I don't know if I will have further use cases which need the original URL. So I rather quote and escape it when needed, and don't add already quoted URLs to the initial data.
Comments
Display comments as Linear | Threaded