我疯狂地试图找出为什么图像没有显示在我的电子邮件中。正如您在下面看到的,仅显示了 Discord 徽标图像。
电子邮件是通过以下功能从我的 Java 游戏服务器发送的。亚马逊 SES SMTP。我尝试过对不同的字符进行编码,但没有成功。我将不胜感激任何帮助,因为我花了几个小时调整/测试这个。
public static void SendAmazonSESEmailPureJava(String TO, String CC, String BODY, String SUBJECT, int headerAndFooterCode){
new Thread(new Runnable() {
@Override
public void run() {
LOGGER.info("Attempting to send an email through Amazon SES by using plain Java...");
Transport transport = null;
try {
//Replace with your "From" address. This address must be verified.
final String FROM = "REDACTED";
String FROMNAME = "REDACTED";
String SMTP_USERNAME = "REDACTED";
//Replace smtp_password with your Amazon SES SMTP password.
String SMTP_PASSWORD = "REDACTED";
//Amazon SES SMTP host name. This example uses the US West (Oregon) region.
//See https://docs.aws.amazon.com/ses/latest/DeveloperGuide/regions.html#region-endpoints for more information.
String HOST = "email-smtp.us-east-1.amazonaws.com";
//The port you will connect to on the Amazon SES SMTP endpoint.
//This port is used by STARTTLS to encrypt the email
int PORT = 587;
//Create a Properties object to contain connection configuration information.
Properties props = System.getProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.port", PORT);
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth", "true");
//Create a Session object to represent a mail session with the specified properties.
Session session = Session.getDefaultInstance(props);
//if headerAndFooter then add to BODY
String finalBody = BODY;
if (headerAndFooterCode != -1) {
String header = "";
header += "<!DOCTYPE html>";
header += "<html>";
header += "<head>";
header += "<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />";
header += "<title>Subscriber email</title>";
header += "</head>";
header += "<body style='font-size:14px; color:#B4BBCB; background:#101010;'>";
header += "<div style='width:880px; margin:0 auto;'>";
header += "<div style='margin-left:10px; margin-right:10px;'>";
//header
header += "<br />";
header += "<div style='margin: 15px auto; border-radius:20px; border:3px solid #a1a1a1; background:#1C2939;'>";
header += "<h1 align='center'>";
header += "<a href='https://www.kisnardonline.com/'>";
final String[] headerRandomName = {"cave", "dragon", "drisdin", "house", "jail", "sand", "sandgrass", "shark", "snow", "swamp", "worm"};
header += "<img src='https://s3.amazonaws.com/kisnardonline.site/images/header_v4_" + headerRandomName[rand.nextInt(headerRandomName.length)] + ".png' alt='Kisnard Online Game Header' width='830' height='104' />";
header += "</a>";
header += "</h1>";
header += "</div>";
header += "<div style='margin-left:20px; margin-right:20px;'>";
//BODY HERE
//social media bar
String footer = "<br />";
footer += "<div style='text-align:center; margin:15px auto; border-radius:20px; border:3px solid #a1a1a1; background:#1C2939;'>";
footer += "<br />";
footer += "<div style='display:inline-block; margin-left:10px; margin-right:10px;'>";
footer += "<a href='https://www.kisnardonline.com/wiki'>";
footer += "<img src='https://s3.amazonaws.com/kisnardonline.site/images/logos/wiki-logo-small.png' alt='Wiki logo' width='45' height='45'/>";
footer += "</a>";
footer += "</div>";
footer += "<div style='display:inline-block; margin-left:10px; margin-right:10px;'>";
footer += "<a href='https://www.facebook.com/KisnardOnline'>";
footer += "<img src='https://s3.amazonaws.com/kisnardonline.site/images/logos/facebook-logo-small.png' alt='Facebook logo' width='45' height='45'/>";
footer += "</a>";
footer += "</div>";
footer += "<div style='display:inline-block; margin-left:10px; margin-right:10px;'>";
footer += "<a href='https://www.reddit.com/r/KisnardOnline/new/'>";
footer += "<img src='https://s3.amazonaws.com/kisnardonline.site/images/logos/reddit-logo-small.png' alt='Reddit logo' width='45' height='45'/>";
footer += "</a>";
footer += "</div>";
footer += "<div style='display:inline-block; margin-left:10px; margin-right:10px;'>";
footer += "<a href='https://discord.gg/RBvQG5Q'>";
footer += "<img src='https://s3.amazonaws.com/kisnardonline.site/images/logos/discord-logo-small.png' alt='Discord logo' width='45' height='45'/>";
footer += "</a>";
footer += "</div>";
footer += "<br />";
footer += "<p>";
footer += "SPAM = BOO! These emails are sent infrequently to avoid spam at all costs.";
footer += "<br />";
String email = TO;
email = email.replace("+", "%2B");
footer += "Kisnard Online is an amazing game, but I need a break... please just <a href='https://www.kisnardonline.com/unsubscribe.php?email=" + email + "&emailunsub=" + headerAndFooterCode + "' style='color: #ADBFE1;'>unsubscribe</a> me.";
footer += "</p>";
footer += "</div>";
footer += "<br />";
footer += "</div>";
footer += "</div>";
footer += "</body>";
footer += "</html>";
String newBody = header + BODY + footer;
// newBody = newBody.replace("&", "&");
// newBody = newBody.replace("<", "<");
// newBody = newBody.replace(">", ">");
// newBody = newBody.replace("\"", """);
// newBody = newBody.replace("'", "'");
// newBody = newBody.replace("/", "/");
finalBody = newBody;
}
//Create a message with the specified information.
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(FROM,FROMNAME));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(TO));
if (!CC.equals("")) {
msg.setRecipient(Message.RecipientType.CC, new InternetAddress(CC));
}
msg.setSubject(SUBJECT);
msg.setContent(finalBody,"text/html");
//Create a transport.
transport = session.getTransport();
//Connect to Amazon SES using the SMTP username and password you specified above.
transport.connect(HOST, SMTP_USERNAME, SMTP_PASSWORD);
//Send the email.
transport.sendMessage(msg, msg.getAllRecipients());
LOGGER.info("Email sent!");
} catch (Exception ex) {
LOGGER.fatal("The email was not sent.");
LOGGER.fatal("TO: " + TO);
LOGGER.fatal("CC: " + CC);
LOGGER.fatal("SUBJECT: " + SUBJECT);
LOGGER.fatal("BODY: " + BODY);
LOGGER.fatal("Error message: " + ex.getMessage());
} finally {
//Close and terminate the connection.
try {
transport.close();
} catch (Exception e) {
LOGGER.fatal("Unable to close email transport:" + e.getMessage());
}
}
}
}).start();
}
这是从 gmail 下载的电子邮件:
Date: Sun, 28 Apr 2024 05:19:36 +0000
From: REDACTED
To: REDACTED
Message-ID: <0100018f2324f805-9fc23f73-4db6-4a7c-8a02-e7a4db64e59d-000000@email.amazonses.com>
Subject: Kisnard Online - Version 1.7.0
MIME-Version: 1.0
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Feedback-ID: 1.us-east-1.pMQx/G6rg9yU/XL5kamnG8jb1mTbMevSee4j3WRzlyU=:AmazonSES
X-SES-Outgoing: 2024.04.28-54.240.8.26
<!DOCTYPE html><html><head><meta http-equiv=3D'Content-Type' content=3D'tex=
t/html; charset=3Dutf-8' /><title>Subscriber email</title></head><body styl=
e=3D'font-size:14px; color:#B4BBCB; background:#101010;'><div style=3D'widt=
h:880px; margin:0 auto;'><div style=3D'margin-left:10px; margin-right:10px;=
'><br /><div style=3D'margin: 15px auto; border-radius:20px; border:3px sol=
id #a1a1a1; background:#1C2939;'><h1 align=3D'center'><a href=3D'https://ww=
w.kisnardonline.com/'><img src=3D'https://s3.amazonaws.com/kisnardonline.si=
te/images/header_v4_house.png' alt=3D'Kisnard Online Game Header' width=3D'=
830' height=3D'104' /></a></h1></div><div style=3D'margin-left:20px; margin=
-right:20px;'>Dear REDACTED,<br /><br />Thank you for your continued =
interest! Kisnard Online just had a massive update to Version 1.7.0! To s=
ee this update and other recent updates: https://www.kisnardonline.com/cate=
gory/release-notes/. There are quests, items, spells, monster, sounds, and=
more.<br /><br />Spells can now have an area effect (AoE).<br /><img style=
=3D"margin: auto; border: 1px solid #ffffff;" src=3D"https://s3.amazonaws.c=
om/kisnardonline.site/images/releasenotes/area-of-effect-spells.gif" alt=3D=
"aoe, area effect, spells" width=3D"354" height=3D"240"/><br />Big backpack=
expansion item adds 4 slots to backpack and Mega backpack expansion item a=
dds 5 slots to backpack.<br /><img style=3D"margin: auto; border: 1px solid=
#ffffff;" src=3D"https://s3.amazonaws.com/kisnardonline.site/images/releas=
enotes/big-mega-backpack.png" alt=3D"backpack, size, mega, big" width=3D"19=
5" height=3D"207"/><br />Recycle your pets, armor, and weapons.<br /><img s=
tyle=3D"margin: auto; border: 1px solid #ffffff;" src=3D"https://s3.amazona=
ws.com/kisnardonline.site/images/releasenotes/pet-recycler-shop-trades.gif"=
alt=3D"pet, recycler, shop trades" width=3D"502" height=3D"358"/><br /><br=
/>And more... Come join the fight!<br /><br /><br /><div style=3D'text-al=
ign:center; margin:15px auto; border-radius:20px; border:3px solid #a1a1a1;=
background:#1C2939;'><br /><div style=3D'display:inline-block; margin-left=
:10px; margin-right:10px;'><a href=3D'https://www.kisnardonline.com/wiki'><=
img src=3D'https://s3.amazonaws.com/kisnardonline.site/images/logos/wiki-lo=
go-small.png' alt=3D'Wiki logo' width=3D'45' height=3D'45'/></a></div><div =
style=3D'display:inline-block; margin-left:10px; margin-right:10px;'><a hre=
f=3D'https://www.facebook.com/KisnardOnline'><img src=3D'https://s3.amazona=
ws.com/kisnardonline.site/images/logos/facebook-logo-small.png' alt=3D'Face=
book logo' width=3D'45' height=3D'45'/></a></div><div style=3D'display:inli=
ne-block; margin-left:10px; margin-right:10px;'><a href=3D'https://www.redd=
it.com/r/KisnardOnline/new/'><img src=3D'https://s3.amazonaws.com/kisnardon=
line.site/images/logos/reddit-logo-small.png' alt=3D'Reddit logo' width=3D'=
45' height=3D'45'/></a></div><div style=3D'display:inline-block; margin-lef=
t:10px; margin-right:10px;'><a href=3D'https://discord.gg/RBvQG5Q'><img src=
=3D'https://s3.amazonaws.com/kisnardonline.site/images/logos/discord-logo-s=
mall.png' alt=3D'Discord logo' width=3D'45' height=3D'45'/></a></div><br />=
<p>SPAM =3D BOO! These emails are sent infrequently to avoid spam at =
all costs.<br />Kisnard Online is an amazing game, but I need a break... pl=
ease just <a href=3D'https://www.kisnardonline.com/unsubscribe.php?email=3D=
REDACTED&emailunsub=3D787214' style=3D'color: #ADBFE1;'>unsubscrib=
e</a> me.</p></div><br /></div></div></body></html>
看起来这可能与 Google Image Proxy(即 googleusercontent)有关。托管图像的 Amazon S3 存储桶设置为可公开访问:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AllowPublicRead",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::kisnardonline.site/*"
}
]
}