shikeying
2024-01-11 3b67e947e36133e2a40eb2737b15ea375e157ea0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
package com.walker.push.mail;
 
import com.walker.infrastructure.utils.StringUtils;
import com.walker.push.AbstractPushObject;
import com.walker.push.Notification;
import com.walker.push.NotificationChannel;
import com.walker.push.PushException;
import com.walker.push.PushResult;
import com.walker.push.util.PushUtils;
 
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
 
/**
 * 标准的邮件推送实现。同步调用
 * @author 时克英
 * @date 2023-04-22
 */
public abstract class MailPush extends AbstractPushObject<MailSenderInfo> {
 
    private MyAuthenticator authenticator = null;
 
    public MailPush(){
        this.setId(NotificationChannel.INDEX_MAIL);
        this.setName(NotificationChannel.NAME_MAIL);
    }
 
    @Override
    protected PushResult doPushContent(Notification notification, List<MailSenderInfo> data) throws PushException {
 
        PushResult pushResult = PushUtils.acquireSuccessPushResult();
 
        for(MailSenderInfo mailInfo : data){
 
            Properties pro = mailInfo.getProperties();
            // 根据邮件会话属性和密码验证器构造一个发送邮件的session
            Session sendMailSession = Session.getDefaultInstance(pro, this.authenticator);
 
            try {
                // 根据session创建一个邮件消息
                Message mailMessage = new MimeMessage(sendMailSession);
                // 创建邮件发送者地址
                Address from = new InternetAddress(mailInfo.getFromAddress());
                // 设置邮件消息的发送者
                mailMessage.setFrom(from);
                // 创建邮件的接收者地址,并设置到邮件消息中
                Address to = new InternetAddress(mailInfo.getToAddress());
                mailMessage.setRecipient(Message.RecipientType.TO,to);
                // 设置邮件消息的主题
                mailMessage.setSubject(mailInfo.getSubject());
                // 设置邮件消息发送的时间
                mailMessage.setSentDate(new Date());
 
                // 是否是html格式,暂时只有纯文本
                // 设置邮件消息的主要内容
                String mailContent = mailInfo.getContent();
                mailMessage.setText(mailContent);
                // 发送邮件
                Transport.send(mailMessage);
                logger.debug("成功发送'通知邮件': {}", mailContent);
 
            } catch (Exception ex){
                logger.error("发送'通知邮件'失败: " + mailInfo.getContent(), ex);
                pushResult.setCode(99);
                pushResult.setText(ex.getMessage());
//                pushResult.addOneFailed(mailInfo.getToAddress());
                pushResult.addOneFailed(mailInfo.getUser());
            }
        }
        return pushResult;
    }
 
    @Override
    public NotificationChannel getNotificationChannel() {
        return NotificationChannel.Mail;
    }
 
    @Override
    public List<MailSenderInfo> translateToTarget(Notification notification) {
        List<MailSenderInfo> data = new ArrayList<>(2);
        MailSenderInfo mailSenderInfo = null;
        String toAddress = null;
        for(String user: notification.getReceiverList()){
            mailSenderInfo = new MailSenderInfo();
            mailSenderInfo.setMailServerHost(this.mailServerHost);
            mailSenderInfo.setMailServerPort(this.mailServerPort);
            mailSenderInfo.setValidate(true);
            mailSenderInfo.setUserName(this.fromAddress);
            mailSenderInfo.setPassword(this.fromPassword);
            mailSenderInfo.setFromAddress(this.fromAddress);
            // 转换前,要记录原始发送用户id
            mailSenderInfo.setUser(user);
 
            if(user.indexOf(StringUtils.STRING_AT) > 0){
                // 说明直接是邮箱地址
                toAddress = user;
            } else {
                // 让业务转换为邮箱
                toAddress = this.getUserMail(user);
            }
            if(StringUtils.isEmpty(toAddress)){
                logger.error("根据用户id未找到'email'地址,该推送消息忽略。user={}", user);
                continue;
            }
            mailSenderInfo.setToAddress(toAddress);
            mailSenderInfo.setSubject(notification.getTitle());
            mailSenderInfo.setContent(notification.getContent());
            data.add(mailSenderInfo);
        }
        return data;
    }
 
    @Override
    public void startup(){
        if(StringUtils.isEmpty(this.fromAddress) || StringUtils.isEmpty(this.fromPassword)){
            throw new IllegalArgumentException("需要先设置邮件发送者信息: fromAddress, fromPassword!");
        }
        if(authenticator == null){
            authenticator = new MyAuthenticator(this.fromAddress, this.fromPassword);
        }
    }
 
    /**
     * 根据用户id,获取email地址
     * @param userId
     * @return
     */
    protected abstract String getUserMail(String userId);
 
    /**
     * 设置邮件服务地址
     * @param mailServerHost
     */
    public void setMailServerHost(String mailServerHost) {
        this.mailServerHost = mailServerHost;
    }
 
    /**
     * 设置邮件服务端口,默认:25
     * @param mailServerPort
     */
    public void setMailServerPort(String mailServerPort) {
        this.mailServerPort = mailServerPort;
    }
 
    /**
     * 设置发送邮件地址
     * @param fromAddress
     */
    public void setFromAddress(String fromAddress) {
        this.fromAddress = fromAddress;
    }
 
    /**
     * 设置发送邮件密码(现在是密钥,不是登录邮箱密码)
     * @param fromPassword
     */
    public void setFromPassword(String fromPassword) {
        this.fromPassword = fromPassword;
    }
 
    private String mailServerHost;
    private String mailServerPort;
    private String fromAddress;
    private String fromPassword;
}