[英]curl : send html email with embedded image and attachment
我的目标是使用curl
和带有嵌入图像的 html 主体发送 email,例如:
我像这样发送 email:
curl "smtp://smtp.gmail.com:587" -v \
--mail-from "sender@gmail.com" \
--mail-rcpt "receiver@gmail.com" \
--ssl -u sender@gmail.com:secretpassword \
-T "message.txt" -k --anyauth
我的message.txt
看起来像:
From: Some Name <sender@gmail.com>
To: Some Name <receiver@gmail.com>
Subject: example of mail
Reply-To: Some Name <sender@gmail.com>
Cc:
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="MULTIPART-MIXED-BOUNDARY"
--MULTIPART-MIXED-BOUNDARY
Content-Type: multipart/alternative; boundary="MULTIPART-ALTERNATIVE-BOUNDARY"
--MULTIPART-ALTERNATIVE-BOUNDARY
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64
Content-Disposition: inline
PGh0bWw+Cjxib2R5PgogICAgPGRpdj4KICAgICAgICA8cD5IZWxsbywgPC9wPgogICAgICAgIDxw
PlBsZWFzZSBzZWUgdGhlIGxvZyBmaWxlIGF0dGFjaGVkPC9wPgogICAgICAgIDxwPkFkbWluIFRl
YW08L3A+CiAgICAgICAgPGltZyBzcmM9ImFkbWluLnBuZyIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI1
MCI+CiAgICA8L2Rpdj4KPC9ib2R5Pgo8L2h0bWw+Cg==
--MULTIPART-ALTERNATIVE-BOUNDARY--
--MULTIPART-MIXED-BOUNDARY
解码后的 html 为:
<html>
<body>
<div>
<p>Hello, </p>
<p>Please see the log file attached</p>
<p>Admin Team</p>
<img src="admin.png" width="150" height="50">
</div>
</body>
</html>
How can I embed admin.png
in this html and attach another file log.txt
to this email using curl
and bash
?
我想出的解决方案是对所有附件(图像和文本文件)进行 base64 编码,并将它们直接包含在multipart/mixed
正文中的上传文件中,例如:
--MULTIPART-MIXED-BOUNDARY
Content-Type: image/png
Content-Transfer-Encoding: base64
Content-Disposition: inline
Content-Id: <admin.png>
iVBORw0KGgoAAAANSUhEUgAAAIAAAACgCAIAAABL8POqAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA
B3RJTUUH4AQNDwEVouBdqAAAG2xJREFUeNrtfX9oHFe25jdDBU5BG25BG7pABhXEkDJjSIsYIs1m
WbfJA8ubhcjjgdiTQNJOYCInj0RKYGIl8CbyPF4iZSCxEkgsB5LIgWQlL2Pcfow3bdgw0mMzox6e
....
--MULTIPART-MIXED-BOUNDARY
Content-Type: text/plain
Content-Transfer-Encoding: base64
Content-Disposition: inline; filename=log.txt
c29tZSBsb2cgaW4gYSB0eHQgZmlsZSB0byBhdHRhY2ggdG8gdGhlIG1haWwK
--MULTIPART-MIXED-BOUNDARY--
Content-Id
标头用于标识可以在 html 中引用的资源: cid:
like:
<img src="cid:admin.png" width="150" height="50">
这是一个完整的bash
示例,用于发送带有admin.png
嵌入图像和log.txt
的 html 电子邮件:
#!/bin/bash
rtmp_url="smtp://smtp.gmail.com:587"
rtmp_from="sender@gmail.com"
rtmp_to="receiver@gmail.com"
rtmp_credentials="sender@gmail.com:secretpassword"
file_upload="data.txt"
# html message to send
echo "<html>
<body>
<div>
<p>Hello, </p>
<p>Please see the log file attached</p>
<p>Admin Team</p>
<img src=\"cid:admin.png\" width=\"150\" height=\"50\">
</div>
</body>
</html>" > message.html
# log.txt file to attached to the mail
echo "some log in a txt file to attach to the mail" > log.txt
mail_from="Some Name <$rtmp_from>"
mail_to="Some Name <$rtmp_to>"
mail_subject="example of mail"
mail_reply_to="Some Name <$rtmp_from>"
mail_cc=""
# add an image to data.txt :
# $1 : type (ex : image/png)
# $2 : image content id filename (match the cid:filename.png in html document)
# $3 : image content base64 encoded
# $4 : filename for the attached file if content id filename empty
function add_file {
echo "--MULTIPART-MIXED-BOUNDARY
Content-Type: $1
Content-Transfer-Encoding: base64" >> "$file_upload"
if [ ! -z "$2" ]; then
echo "Content-Disposition: inline
Content-Id: <$2>" >> "$file_upload"
else
echo "Content-Disposition: attachment; filename=$4" >> "$file_upload"
fi
echo "$3
" >> "$file_upload"
}
message_base64=$(cat message.html | base64)
echo "From: $mail_from
To: $mail_to
Subject: $mail_subject
Reply-To: $mail_reply_to
Cc: $mail_cc
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=\"MULTIPART-MIXED-BOUNDARY\"
--MULTIPART-MIXED-BOUNDARY
Content-Type: multipart/alternative; boundary=\"MULTIPART-ALTERNATIVE-BOUNDARY\"
--MULTIPART-ALTERNATIVE-BOUNDARY
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64
Content-Disposition: inline
$message_base64
--MULTIPART-ALTERNATIVE-BOUNDARY--" > "$file_upload"
# add an image with corresponding content-id (here admin.png)
image_base64=$(curl -s "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_116x41dp.png" | base64)
add_file "image/png" "admin.png" "$image_base64"
# add the log file
log_file=$(cat log.txt | base64)
add_file "text/plain" "" "$log_file" "log.txt"
# add another image
#image_base64=$(curl -s "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_116x41dp.png" | base64)
#add_file "image/png" "something.png" "$image_base64"
# end of uploaded file
echo "--MULTIPART-MIXED-BOUNDARY--" >> "$file_upload"
# send email
echo "sending ...."
curl -s "$rtmp_url" \
--mail-from "$rtmp_from" \
--mail-rcpt "$rtmp_to" \
--ssl -u "$rtmp_credentials" \
-T "$file_upload" -k --anyauth
res=$?
if test "$res" != "0"; then
echo "sending failed with: $res"
else
echo "OK"
fi
我真的很想通过请求,CURL和BeautifulSoup来跟踪您以前的旧报废表单wsj中的文章 。 是否可以要求您更新答案? 非常感谢。 已经研究了许多小时,但无法弄清楚该怎么做。
另外,您的代码示例有点误导性强,实际上它不起作用。 正如您所说,您只需将每个部分括在一个边界中,在您的情况下,分隔符是:
“--MULTIPART-MIXED-BOUNDARY”。
尽管如此,它可以是任何其他用户定义的字符串。 您正在嵌套多个边界类型,这是不必要的。 HTML 内容不需要是 base64 编码的,如果你愿意,它可以被编码。
每个分隔符前后都需要一个空行。
我建议查看 W3 论文和示例: https : //www.w3.org/Protocols/rfc1341/7_2_Multipart.html
这是您可以使用的 shell 脚本。 我大量来自https://blog.ambor.com/2021/08/using-curl-to-send-e-mail-with.html
密码可以存储在 .netrc 文件中,如下所述: https ://everything.curl.dev/usingcurl/netrc 但我没有尝试过。
只需确保您需要的图像使用 base64 编码嵌入到 HTML 中。
#!/bin/bash
declare -a VOPTS;
declare -a HOPTS;
sesAccess="sender.account.authentication@email.id" ;
sesSecret="sender.account.passwordXXXXXX";
sesFromName="Sender Full Name";
sesFromAddress='<sender@email.id>';
sesToName="Recipient Full Name";
sesToAddress="<recepient@email.id>"
sesSubject="Email Subject Line";
sesSMTP='mail.server.fqdn';
sesPort='465';
sesMessage=$'Test of line 1\nTest of line 2'
sesFile="$1"; # attachment is first argument
sesHTMLbody="/path/to/html/file.html"; # content of this file will be used to create HTML body
sesMIMEType=`file --mime-type "$sesFile" | sed 's/.*: //'`;
# sesMIMEType=`file -b --mime-type "$sesFile"`;
VOPTS=();
HOPTS=();
#Curl Options
VOPTS+=("-v");
VOPTS+=("--url"); VOPTS+=("smtps://$sesSMTP:$sesPort");
VOPTS+=("--ssl-reqd")
VOPTS+=("--user"); VOPTS+=("${sesAccess}:${sesSecret}");
VOPTS+=("--mail-from"); VOPTS+=("${sesFromAddress}");
VOPTS+=("--mail-rcpt"); VOPTS+=("${sesToAddress}");
#Header Options
HOPTS+=("-H"); HOPTS+=("Subject: ${sesSubject}");
HOPTS+=("-H"); HOPTS+=("From: ${sesFromName} ${sesFromAddress}");
HOPTS+=("-H"); HOPTS+=("To: ${sesToName} ${sesToAddress}");
curl "${VOPTS[@]}" -F '=(;type=multipart/mixed' -F "=<$sesHTMLbody;type=text/html;encoder=base64" -F "file=@$sesFile;type=$sesMIMEType;encoder=base64" -F '=)' "${HOPTS[@]}"
exit
@bertrand-martel 的答案在我运行 Ubuntu 22.04 并提交到我网络中的后缀服务器的系统上大部分是正确的。 html email 消息通过就好了,我有正确命名的空附件。 我必须编辑他定义的 add_file function 并在最后的 $3 之前添加一个空行。 如果 Content-Disposition: 和 base64 编码之间没有空行,email 将无法工作。 我还必须在 --MULTIPART-ALTERNATIVE-BOUNDARY-- 之后插入一个空行。 一旦我进行了这些更改,html 消息、嵌入的图像和附件都正确出现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.