I promised to add more functionality to the send.sh script, so I thought that adding the -hex
switch would be simple enough. Not quite, as the hex string I tested with happened to be text containing the scandinavian characters ö and ä which lead to the dreaded Bad Request error from Opaali API.
HTTP/1.1 400 Bad Request
content-type: text/xml
Content-Length: 11
Opaali API seems to want special characters as unicode escape sequences:
'å' -> "\\u00E5"
'ä' -> "\\u00E4"
'ö' -> "\\u00F6"
'Å' -> "\\u00C5"
'Ä' -> "\\u00C4"
'Ö' -> "\\u00D6"
There are more, but these are the most common ones used in texts written in Finnish or Swedish.
Those @#!$ åäö characters
These conversions can be applied to the content of the MESSAGE variable by adding this single line:
MESSAGE=$(echo -n "$MESSAGE" | sed 's/å/\\u00e5/g; s/ä/\\u00e4/g; s/ö/\\u00f6/g; s/Å/\\u00c5/g; s/Ä/\\u00c4/g; s/Ö/\\u00d6/g')
(I’m counting on writing those special characters as is actually working in the shell script. If not, you may need to replace them with their character codes, the actual values of which may depend on your platform.)
There’s more!
While we are at it, we might as well escape characters that have special meaning in JSON. (Although you might as well escape them on the send.sh command line already. And I left out the backspace escape as I couldn’t get it to work nicely. Who would even want to use a backspace in a text message?)
MESSAGE=$(echo -n "$MESSAGE" | sed 's/\"/\\\"/g; s/\\/\\\\/g; s/\//\\\//g')
You will want to insert this line before the previous one so that you won’t break the unicode escapes by rewriting their backslashes. (Don’t worry – even I am not sure if I fully understand what happens there…)
Oh yes – the hex bit
I almost forgot what I originally started to do! We need to add the new command line switch -hex
and convert the hex data into text. (Hex input data is actually more useful for sending a binary message, but we’ll return to that in some later episode of this story…)
Converting the hex data into text can be done using the xxd
command:
MESSAGE=$(echo -n "$MESSAGE" | xxd -r -p)
(You can learn how xxd
works by running it with the –help parameter: xxd --help
)
Changes
After adding the -hex
switch processing the diff
between the original and new script is this:
$ diff -b send.sh.orig send.sh
37c37
< echo "Usage: $1 -s sender -r recipient [-m message] [-f filename]" >/dev/stderr
---
> echo "Usage: $1 -s sender -r recipient [-m message] [-f filename] [-hex message in hex]" >/dev/stderr
97a98,106
> -hex)
> shift
> if [[ -n "$1" ]]; then
> MESSAGE=$(echo -n "$1" | xxd -r -p)
> else
> error_exit "$0" "error decoding hex message" "$1"
> fi
> shift
> ;;
107,108c116
< -c|\
< -hex)
---
> -c)
150a159,164
> # escape (some) JSON reserved chars
> MESSAGE=$(echo -n "$MESSAGE" | sed 's/\"/\\\"/g; s/\\/\\\\/g; s/\//\\\//g')
>
> # convert scandinavian chars to unicode
> MESSAGE=$(echo -n "$MESSAGE" | sed 's/å/\\u00e5/g; s/ä/\\u00e4/g; s/ö/\\u00f6/g; s/Å/\\u00c5/g; s/Ä/\\u00c4/g; s/Ö/\\u00d6/g')
>
I’ll update these changes to the repository where you can read the script in full.
(…did anybody notice that I’m not really testing if xxd
fails?
)
Examples
Lets now convert some text into hex data and try sending it:
$ echo "Soittopyyntö äänipostiin" | xxd -p
536f6974746f7079796e74c3b620c3a4c3a46e69706f737469696e0a
$ ./send.sh -s '$jpla' -r 0401234567 -hex 536f6974746f7079796e74c3b620c3a4c3a46e69706f737469696e0a
SENT: 0401234567 DeliveredToNetwork
$
Looks like it worked!
See Writing a send application as a shell script for the previous episode.
