Matrix To MMS-Over-Email Bridge: Step 2 — Matrix Over Email

This step was considerably harder than the last, but the end result turned out to be pretty simple. Here’s how it works:

That’s really it. I did encounter some hurdles, though:

I fixed these by mapping Matrix room IDs to human-readable IDs such as “room-number-7”, and by putting the program in a while loop (don’t look at me like that — I made this because I promised a friend, it doesn’t need to be high quality).

On smirkingface

matrix2email

#!/bin/sh


TO_ADDR="enter email address here"
FROM_USER="enter sender email address local part here"
FROM_DOMAIN="enter sender email address domain here"

unescape() {
        printf '%s\n' "$1" | sed -E '
                s/\\"/"/g;
                s/\\t/\t/g;
                s/\\r/\r/g;
                s/\\n/\n/g;
                s/\\e/\\/g
        '
}

# room_avatar_url has to be last bc it has a good chance of being null
matrix-commander -l -o json --download-media --listen-self \
| jq --raw-output --unbuffered '
        . | [
                .source.type,
                .source.content.body,
                .source.content.msgtype,
                .room.room_id,
                (.room.users | length),
                .room_display_name,
                .sender_nick,
                .room.room_avatar_url
        ] | @tsv' \
| while IFS=$'\t\n' read -r event body mime room users name sender icon; do
        [ "$event" = "m.room.message" ] || continue


        if grep -Eq "^$room " ~matrix/rooms; then
                addr="$(grep -E "^$room " ~matrix/rooms \
                        | head -n 1 | cut -d' ' -f2)"
        else
                # map mxid to something that doesn’t look like spam
                touch ~matrix/rooms
                num="$(wc -l <~matrix/rooms)"
                addr="${FROM_USER}+room.no.${num}@${FROM_DOMAIN}"
                printf '%s %s\n' "$room" "$addr" >>~matrix/rooms

                # inform ~team so it can add a ~/.forward file
                printf 'room.no.%s\n' "$num" | mailx -s "New forward file" \
                        -r "matrix@${FROM_DOMAIN}" "matrix@${FROM_DOMAIN}"

                # inform user so they can name the chat and etc
                file="$(mktemp)"
                trap "rm -rf '$file'" INT TERM HUP EXIT
                matrix-commander --download "$icon" --file-name "$file"
                unescape "$(
                        printf '%s ' "“$name” ($room) is <$addr>"
                        printf '\n'
                )" \
                | mailx -s "" \
                        -r "${FROM_USER}+matrix@${FROM_DOMAIN}" \
                        -S "sendcharsets=utf-8,UTF-8" \
                        -a "$file" \
                        "$TO_ADDR"
                rm "$file"
        fi

        file="$body"
        [ "$users" -gt 2 ] && body="<$sender> $body"


        if [ "$mime" = "m.text" ] || [ "$mime" = "m.notice" ] \
                || [ "$mime" = "text/plain" ] || [ "$mime" = "text/markdown" ]
        then
                unescape "$body" | mailx -s "" \
                        -r "$addr" \
                        -S "sendcharsets=utf-8,UTF-8" \
                        "$TO_ADDR"
        else
                echo "$file" >~matrix/file-name
                unescape "$body" | mailx -s "" \
                        -r "$addr" \
                        -S "sendcharsets=utf-8,UTF-8" \
                        -a ~matrix/media/"$(unescape "$file")" \
                        "$TO_ADDR"
                rm ~matrix/media/"$(unescape "$file")"
        fi
done

restart.sh

#!/bin/sh

while :; do
        ./matrix2email
done

email2matrix

#!/bin/sh

to="$1"
body="$(cat)"

matrix-commander \
        --room "$(grep -F "$to" ~matrix/rooms | cut -d " " -f 1)" \
        --message "$body"

On ~team

#!/bin/sh


# POSIX sh lacks $HOSTNAME and `hostname`
hostname() {
        set -- $(grep -F "$(cat /etc/hostname)" /etc/hosts)
        printf '%s\n' "$2"
}

OTHER_MACHINE="enter fqdn here"
email="$(cat)"
from="$(
        printf '%s\n' "$email" \
        | grep -Em1 "^From:" \
        | cut -d : -f 2- \
        | sed -E 's/^[[:blank:]]*(.*<)?//g; s/>?[[:blank:]]*$//g'
)"
to="$(
        printf '%s\n' "$email" \
        | grep -Em1 "^To:" \
        | cut -d : -f 2- \
        | sed -E 's/^[[:blank:]]*(.*<)?//g; s/>?[[:blank:]]*$//g'
)"
split="$(printf '%s\n' "$email" | grep -En "^$" | cut -d : -f 1)"
body="$(printf '%s\n' "$email" | tail -n +"$((split + 1))")"

if [ "$from" = "matrix@$(hostname)" ]; then
        ln ~/.forward+matrix ~/".forward+matrix+$body"
else
        printf '%s\n' "$body" \
        | ssh "matrix@$OTHER_MACHINE" -t /usr/local/share/matrix/email2matrix "$to"
fi