一、前往阿里云控制台开通邮件推送服务
1. 进入邮件推送控制台,如下图

2.设置发信域名

(1)点击新建域名

(2)输入发信域名,自定义前缀加上域名,点击确定

(3)看到上图出现待验证,点击配置查看域名解析记录

(4)前往云解析DNS控制台,点击域名(下图中红色涂抹位置),进入解析设置

(5)将第四步图中的4种解析依次添加到解析记录

(6)回到发信域名的配置页点击验证(大约10分钟后解析生效),等待验证通过后即可通过发信域名进行发信

2.设置发信地址

(1)点击新建发信地址

选择刚刚新建的发信域名,输入自定义的账号,设置发信类型、回信地址(一个邮箱地址)
(2)设置SMTP密码

3.设置邮件标签(用于发送邮件进行邮件追踪使用)

4、模板管理 创建邮件模板

二、异步通知

1.选择发信地址级异步通知,点击新建发信地址级异步通知

2.开通消息服务MNS,前往控制台

(1)进入事件通知,选择邮件推送DM

(2)创建规则,事件类型有打开、点击链接、发送成功、发送失败4种,接收终端选择队列输入队列名称点击确定

(3)上一步创建完成后会自动创建一个主题和队列,对应事件规则触发后会有消息推送到主题中,每到一个小时会推送到队列中。

更多中编辑队列的参数(根据自己的业务调整消息在队列的保存时长和消息可见性超时时间等参数)

3.SMTP发信
JAVA 发送DEMO (参考阿里云文档)SMTP 之 Java 调用示例 (aliyun.com)
https://help.aliyun.com/document_detail/29450.html
发信端口不要使用25(不通)
import javax.mail.*;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeMessage;import java.util.Properties;public class SampleMail {private static final String ALIDM_SMTP_HOST = "smtpdm.aliyun.com";private static final String ALIDM_SMTP_PORT = "25";//或"80"public static void main(String[] args) {// 配置发送邮件的环境属性final Properties props = new Properties();// 表示SMTP发送邮件,需要进行身份验证props.put("mail.smtp.auth", "true");props.put("mail.smtp.host", ALIDM_SMTP_HOST);props.put("mail.smtp.port", ALIDM_SMTP_PORT);// 如果使用ssl,则去掉使用25端口的配置,进行如下配置,// props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");// props.put("mail.smtp.socketFactory.port", "465");// props.put("mail.smtp.port", "465");// 发件人的账号,填写控制台配置的发信地址,比如xxx@xxx.comprops.put("mail.user", "发信地址");// 访问SMTP服务时需要提供的密码(在控制台选择发信地址进行设置)props.put("mail.password", "***");// 构建授权信息,用于进行SMTP进行身份验证Authenticator authenticator = new Authenticator() {@Overrideprotected PasswordAuthentication getPasswordAuthentication() {// 用户名、密码String userName = props.getProperty("mail.user");String password = props.getProperty("mail.password");return new PasswordAuthentication(userName, password);}};// 使用环境属性和授权信息,创建邮件会话Session mailSession = Session.getInstance(props, authenticator);// mailSession.setDebug(true);//UUID uuid = UUID.randomUUID();//final String messageIDValue = "<" + uuid.toString() + ">";// 创建邮件消息MimeMessage message = new MimeMessage(mailSession){//@Override//protected void updateMessageID() throws MessagingException {//设置自定义Message-ID值//setHeader("Message-ID", messageIDValue);//}};try {// 设置发件人邮件地址和名称。填写控制台配置的发信地址,比如xxx@xxx.com。和上面的mail.user保持一致。名称用户可以自定义填写。InternetAddress from = new InternetAddress("发信地址", "发件人名称(用户自定义填写)");message.setFrom(from);//可选。设置回信地址Address[] a = new Address[1];a[0] = new InternetAddress("***");message.setReplyTo(a);// 设置收件人邮件地址,比如yyy@yyy.comInternetAddress to = new InternetAddress("收件人邮件地址");message.setRecipient(MimeMessage.RecipientType.TO, to);//如果同时发给多人,才将上面两行替换为如下(因为部分收信系统的一些限制,尽量每次投递给一个人;同时我们限制单次允许发送的人数是60人)://InternetAddress[] adds = new InternetAddress[2];//adds[0] = new InternetAddress("xxxxx@qq.com");//adds[1] = new InternetAddress("xxxxx@qq.com");//message.setRecipients(Message.RecipientType.TO, adds);String ccUser = "抄送邮箱";// 设置多个抄送地址if(null != ccUser && !ccUser.isEmpty()){@SuppressWarnings("static-access")InternetAddress[] internetAddressCC = new InternetAddress().parse(ccUser);message.setRecipients(Message.RecipientType.CC, internetAddressCC);}String bccUser = "密送邮箱";// 设置多个密送地址if(null != bccUser && !bccUser.isEmpty()){@SuppressWarnings("static-access")InternetAddress[] internetAddressBCC = new InternetAddress().parse(bccUser);message.setRecipients(Message.RecipientType.BCC, internetAddressBCC);}// 设置邮件标题message.setSubject("测试邮件");// 设置邮件的内容体message.setContent("测试的HTML邮件", "text/html;charset=UTF-8");//若需要开启邮件跟踪服务,请使用以下代码设置跟踪链接头。前置条件和约束见文档"如何开启数据跟踪功能?"//String tagName = "Test";//HashMap<String, String> trace = new HashMap<>();//这里为字符串"1"//trace.put("OpenTrace", "1");//trace.put("TagName", tagName);//String jsonTrace = JSON.toJSONString(trace);//String base64Trace = new String(Base64.encodeBase64(jsonTrace.getBytes()));//设置跟踪链接头//message.addHeader("X-AliDM-Trace", base64Trace);// 发送附件,总的邮件大小不超过15M,创建消息部分//BodyPart messageBodyPart = new MimeBodyPart();// 消息//messageBodyPart.setText("消息Text");// 创建多重消息//Multipart multipart = new MimeMultipart();// 设置文本消息部分//multipart.addBodyPart(messageBodyPart);// 附件部分//messageBodyPart = new MimeBodyPart();//设置要发送附件的文件路径//String filename = "D:\\goProjects\\src\\测试pdf.pdf";//FileDataSource source = new FileDataSource(filename);//messageBodyPart.setDataHandler(new DataHandler(source));//处理附件名称中文(附带文件路径)乱码问题//messageBodyPart.setFileName(MimeUtility.encodeText(filename));//messageBodyPart.addHeader("Content-Transfer-Encoding", "base64");//multipart.addBodyPart(messageBodyPart);// 发送含有附件的完整消息//message.setContent(multipart);// 发送附件代码,结束// 发送邮件Transport.send(message);}catch (MessagingException e) {String err = e.getMessage();// 在这里处理message内容, 格式是固定的System.out.println(err);}}}

三、接收消息队列MNS中的消息
参考阿里云文档队列使用手册 (aliyun.com)
https://help.aliyun.com/document_detail/32449.html
public class ComsumerDemo {public static void main(String[] args) {CloudAccount account = new CloudAccount(ServiceSettings.getMNSAccessKeyId(),ServiceSettings.getMNSAccessKeySecret(),ServiceSettings.getMNSAccountEndpoint());MNSClient client = account.getMNSClient();try{CloudQueue queue = client.getQueueRef("queue-demo");for (int i = 0; i < 10; i++){Message popMsg = queue.popMessage();if (popMsg != null){System.out.println("message handle: " + popMsg.getReceiptHandle());System.out.println("message body: " + popMsg.getMessageBodyAsString());System.out.println("message id: " + popMsg.getMessageId());System.out.println("message dequeue count:" + popMsg.getDequeueCount());queue.deleteMessage(popMsg.getReceiptHandle());System.out.println("delete message successfully.\n");}}} catch (ClientException ce){System.out.println("Something wrong with the network connection between client and MNS service."+ "Please check your network and DNS availability.");ce.printStackTrace();} catch (ServiceException se){if (se.getErrorCode().equals("QueueNotExist")){System.out.println("Queue is not exist.Please create queue before use");} else if (se.getErrorCode().equals("TimeExpired")){System.out.println("The request is time expired. Please check your local machine timeclock");}se.printStackTrace();} catch (Exception e){System.out.println("Unknown exception happened!");e.printStackTrace();}client.close();}}
while (true) {Message popMsg = queue.popMessage();try {if (popMsg != null) {String orisignString = popMsg.getMessageBodyAsRawString();Map<String, String> keyMap = keyMapUtils.keyMap("&", orisignString);if (keyMap.get("event") != null) {/*打开邮件*/if ("Open".equals(keyMap.get("event"))) {String msgId = keyMap.get("msg_id");String opTime = keyMap.get("operate_time");/*执行自己相关业务*/} else if ("deliver".equals(keyMap.get("event"))) {String id = keyMap.get("msg_id");String failedType = keyMap.get("failed_type");try {if ("SendOk".equals(failedType)) {/*发送成功 执行相关业务*/} else {/*发送失败 执行相关业务*/}queue.deleteMessage(popMsg.getReceiptHandle());} catch (Exception e) {e.printStackTrace();logger.error(e.getMessage());}}}} else {break;}} catch (Exception e) {e.printStackTrace();logger.error(e.getMessage());}}
将上述for循环改为While(true) 循环,取消息内容,进行相应处理完成自己的业务逻辑
工具类:(仅供参考)
public class keyMapUtils {public static Map<String, String> keyMap(String split, String originString) {Map<String, String> map = new HashMap<>();try {String[] strArr = originString.split(split);for (int i = 0; i < strArr.length; i++) {String key = strArr[i].split("=")[0];String value = strArr[i].split("=")[1];map.put(key, value);}}catch (Exception e){log.error(e.toString());}return map;}}
推送消息如下:邮件推送事件通知概述 (aliyun.com)
https://help.aliyun.com/document_detail/52587.html
成功
env_id=457323378&msg_id=77041400535408&account=test@example.com&from=test@example.com&rcpt=abc@example.net&recv_time=2017-04-14 11:44:47&end_time=2017-04-14 11:44:48&status=0&event=deliver®ion=cn-hangzhou&err_code=250&err_msg=250 Send Mail OK
失败
env_id=457323379&msg_id=77041400535409&account=test@example.com&from=test@example.com&rcpt=abc@example.net&recv_time=2017-04-14 11:44:48&end_time=2017-04-14 11:44:49&status=2&event=deliver®ion=cn-hangzhou&err_code=550&err_msg=550 No Such User
打开
event=Open®ion=cn-hangzhou&env_id=17870283524410894694&msg_id=e3c666f7-7899-4e91-bdf7-7a668a1c0967&from=test@example.com&rcpt=test@example.com&operate_time=2021-12-12 15:06:06
点击(暂未使用)
参考打开消息类型




