Skip to content

Instantly share code, notes, and snippets.

@schubev
Last active May 18, 2021 10:00
Show Gist options
  • Save schubev/46d6c135a852b061104bad422120423e to your computer and use it in GitHub Desktop.
Save schubev/46d6c135a852b061104bad422120423e to your computer and use it in GitHub Desktop.
Unholy bash e-mail generation library
#!/bin/bash
MAIL_WIDTH=76
function mail_example() {
From alice@example.com
To bob@example.com
Subject "Look at my test email!"
header_message_id
header_date_now
header_mime_version
multipart_begin alternative
Content-Type text/plain 'charset="UTF-8"'
Content-Transfer-Encoding quoted-printable
body_begin
echo "This is a sweet test email isn’t it?" | transfer_encoding_quoted_printable
multipart_next
Content-Type text/html 'charset="UTF-8"'
Content-Transfer-Encoding quoted-printable
body_begin
echo "<p>This is a <em>sweet</em> test email isn’t it?</p>" | transfer_encoding_quoted_printable
multipart_end
}
transfer_encoding_base64() {
base64 --wrap=$MAIL_WIDTH
}
transfer_encoding_quoted_printable() {
perl -MMIME::QuotedPrint -pe '$_=MIME::QuotedPrint::encode($_)'
}
function generate_boundary() {
head -c12 /dev/urandom | xxd -p
}
function header() {
headerindent=' '
{
printf "%s: " "$1"
shift
printf "%s" "$1"
shift
while [[ $# -gt 0 ]]
do
printf "; %s" "$1"
shift
done
echo
} \
| fold \
--spaces \
--width=$((MAIL_WIDTH - ${#headerindent})) \
| sed "2,\$s/^/${headerindent}/"
}
function From() {
header From "$@"
}
function To() {
header To "$@"
}
function Subject() {
header Subject "$@"
}
function Date() {
header Date "$@"
}
function Content-Transfer-Encoding() {
header Content-Transfer-Encoding "$@"
}
function Content-Type() {
header Content-Type "$@"
}
function Content-Disposition() {
header Content-Disposition "$@"
}
function header_message_id() {
header Message-ID "<$(generate_boundary)@$(hostname)>"
}
function header_date_now() {
Date "$(date --rfc-email)"
}
function header_mime_version() {
header MIME-Version 1.0
}
function body_begin() {
echo
}
boundary=
function multipart_begin() {
local content_type="multipart/$1"
shift
boundary=$(generate_boundary)
header Content-Type "$content_type" "boundary=$boundary" "$@"
body_begin
echo "--$boundary"
}
function multipart_next() {
echo
echo "--$boundary"
}
function multipart_end() {
echo
echo "--$boundary--"
}
function transform_pgp_signed() {
local tmp=$(mktemp)
cat > "$tmp"
header Content-Transfer-Encoding 7bit
header Content-Disposition inline
multipart_begin signed 'protocol="application/pgp-signature"' micalg="pgp-sha256"
sed -e '${/^$/d}' "$tmp"
multipart_next
header Content-type application/pgp-signature 'name="signature.asc"'
body_begin
gpg2 --armor --detach-sign --textmode < "$tmp"
multipart_end
}
function transform_pgp_encrypted() {
header Content-Transfer-Encoding 7bit
header Content-Disposition inline
multipart_begin encrypted 'protocol="application/pgp-encrypted"'
header Content-Type application/pgp-encrypted
body_begin
echo 'Version: 1'
multipart_next
header Content-Type application/octet-stream
body_begin
gpg2 --armor --encrypt --textmode "$@"
multipart_end
}
function transform_pgp_signed_encrypted() {
header Content-Transfer-Encoding 7bit
header Content-Disposition inline
multipart_begin encrypted 'protocol="application/pgp-encrypted"'
Content-Type application/pgp-encrypted
body_begin
echo 'Version: 1'
multipart_next
Content-Type application/octet-stream 'name="signature.asc"'
body_begin
gpg2 --armor --sign --encrypt --textmode "$@"
multipart_end
}
function transform_asciidoc_html_content() {
asciidoc --backend xhtml11 -
}
function transform_asciidoc_html() {
header Content-Transfer-Encoding quoted-printable
header Content-Disposition inline
header Content-Type text/html 'charset="UTF-8"'
body_begin
transform_asciidoc_html_content | transfer_encoding_quoted_printable
}
function transform_asciidoc_plain() {
header Content-Transfer-Encoding quoted-printable
header Content-Disposition inline
header Content-Type text/plain 'charset="UTF-8"' 'format=flowed'
body_begin
sed -n '/^$/,${/./,$p}' | transfer_encoding_quoted_printable
}
function mail_send() {
nslookup smtp.gmail.com >/dev/null
msmtp -- "$@"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment