Is there a way to embed images into the body of an email using linux commands like mutt
or sendmail
?
I used this
mutt -e \
It's even possible with the basic mail command
You want to create a mime HTML email a la:
How to embed images in email
Then take the headers (all the lines before the first boundary), remove them from that input and add them individually with the -a command after mail such as:
https://stackoverflow.com/a/12262421/2244213 or Sending HTML mail using a shell script
Here is an improved version of the Joce's script.
This one does not require a custom sendmail
command, because it creates one on the fly, uses it and deletes it afterwards.
It is parametric, so you don't need to change its code for different recipients and the like, and it offers a few other goodies.
The first few lines of code should be clear enough to explain the five positional parameters meaning, but here is an example, just in case:
<script.sh> /srv/emailbody.html "Sender's Name" sender@example.com "Embedded images" 'Recipent's name <recipient@example.net>'
It depends on mktemp
(the original script did not), because I like that more than using $$
, but that's only a matter of taste.
#!/bin/bash
HTMLFULLPATH="$1"
SENDER="$2"
SENDEREMAIL="$3"
SUBJECT="$4"
RECIPIENT="$5"
HTML=$(basename "${HTMLFULLPATH}")
SENDERDOMAIN=$(echo "${SENDEREMAIL}" | cut -d@ -f2)
if ! [[ "${RECIPIENT}" == '*<*' ]] ; then
RECIPIENT="${RECIPIENT}"'<'"${RECIPIENT}"'>' # TO_NO_BRKTS_* SpamAssassin rules
fi
function atexit
{
rm -rf "${TEMPDIR}" "${NEOMUTTCONFIG}" >/dev/null 2>&1
}
trap atexit INT TERM EXIT
TEMPDIR=$(mktemp -d)
mkdir -p "${TEMPDIR}/img"
grep "src=" "${HTMLFULLPATH}" | sed -e "s,.*src=\"\([^\"]*/\)*\([^\"/]*\)\".*,wget \1\2 -O ${TEMPDIR}/img/\2," > "${TEMPDIR}/getimg.sh"
bash "${TEMPDIR}/getimg.sh" >/dev/null 2>&1
sed -e 's,src="\([^"]*/\)*\([^"/]*\)",src="cid:\2@'${SENDERDOMAIN}'",g' < "${HTMLFULLPATH}" > "${TEMPDIR}/${HTML}"
SENDMAIL="${TEMPDIR}/sendmail.sh"
cat > "${SENDMAIL}" << EOF
#!/bin/bash
sed -e 's,Content-Disposition: attachment; filename="\([^"]*\)",Content-Disposition: inline; name="\1"\nContent-ID: <\1@'${SENDERDOMAIN}'>,' < /dev/stdin | sed -e 's,Content-Type: multipart/mixed;,Content-Type: multipart/related;,' | sendmail \$*
EOF
chmod a+rx "${SENDMAIL}"
NEOMUTTCONFIG=$(mktemp)
echo 'set from="'"${SENDER}"' <'"${SENDEREMAIL}"'>"' >> "${NEOMUTTCONFIG}"
echo 'set smtp_url=""' >> "${NEOMUTTCONFIG}"
echo 'set sendmail="'${SENDMAIL}'"' >> "${NEOMUTTCONFIG}"
echo "set content_type=text/html" >> "${NEOMUTTCONFIG}"
neomutt -F "${NEOMUTTCONFIG}" "${RECIPIENT}" -s "${SUBJECT}" -a "${TEMPDIR}/img/"* < "${TEMPDIR}/${HTML}"
For those looking to send emails with embedded images as part of the email using a bash script, I pieced this code together.
The email is started with these line:
EMAILBODY="echo \"Alarm went off! "
EMAILATTACH=""
Inside of a loop that defines each file to attach:
EMAILATTACH=$EMAILATTACH" -a /home/xyz/"$ID"/"$Event"/"$Frame"-capture.jpg"
EMAILBODY=$EMAILBODY"<BR> <IMG Height=150 SRC=\"$Frame-capture.jpg\">"
After the loop, the email is completed with these lines:
EMAILBODY=$EMAILBODY"\" | mutt -e \"set content_type=text/html\" -s \"House Alarm went off!\""
EMAILSTRING=$EMAILBODY$EMAILATTACH" -- user@server.net"
eval $EMAILSTRING
My last hurdle is that when I receive this on my android phone (maybe the same on other browsers), it doesn't display the picture, only a small box (even after you have downloaded the attachments). It shows up fine in Outlook though.
You can attach the image, by changing the -i in your command line to a -a. This won't embed the image perse, but will include it. If you want to embed it, the mail you send will have to be of content type text/html
and include an img
tag to show the attached image.
See this SO page about how to correctly embed image attachments in HTML mail.
Embedding attached images in HTML emails
EMAILBODY="echo \"Alarm went off! "
EMAILATTACH=""
EMAILATTACH=$EMAILATTACH" -a "/home/uat12mgr/XXDBD_AR_INV_PRINT.jpg""
EMAILBODY=$EMAILBODY"<BR> <IMG Height=150 SRC=\""/home/uat12mgr/XXDBD_AR_INV_PRINT.jpg"\">"
EMAILBODY=$EMAILBODY"\" | mutt -e \"set content_type=text/html\" -s \"House Alarm went off!\""
EMAILSTRING=$EMAILBODY$EMAILATTACH" -- myaka@abc.com"
eval $EMAILSTRING
I have written a shell script to send with mutt
an HTML message with embedded images rather than linked ones.
Several steps:
<img>
tags in the original HTML,src
url to a cid
,(neo)mutt
sendmail
Here's the main script which takes the HTML filename as argument (no checks performed, please do not consider it as an alpha software):
#!/bin/bash
F=$(basename "$1")
DIR="/tmp/inlinizer-$$/"
mkdir -p $DIR/Img
grep "src=" "$1" | sed -e "s,.*src=\"\([^\"]*/\)*\([^\"/]*\)\".*,wget \1\2 -O $DIR/Img/\2," > $DIR/get_img.sh
bash $DIR/get_img.sh
sed -e 's,src="\([^"]*/\)*\([^"/]*\)",src="cid:\2@example.com",g' < "$1" > "$DIR/$F"
neomutt -e 'set smtp_url=""' -e 'set sendmail="mysendmail"' -e "set content_type=text/html" me@example.com -s "test" -a $DIR/Img/* < "$DIR/$F"
One also needs a custom sendmail command (mysendmail
in the above) which post-processes the e-mail file generated by mutt
:
sed -e 's,Content-Disposition: attachment; filename="\([^"]*\)",Content-Disposition: inline; name="\1"\nContent-ID: <\1@example.com>,' < /dev/stdin | sed -e 's,Content-Type: multipart/mixed;,Content-Type: multipart/related;,' | sendmail $*
I have tested it in GMail and a few other webmails. Reports of problems with mail clients or webmails welcome.