package com.qianwen.core.notify.provider.email.embedded;
|
|
import java.io.FileInputStream;
|
import java.io.FileNotFoundException;
|
import java.nio.charset.StandardCharsets;
|
import java.util.HashMap;
|
import java.util.Iterator;
|
import java.util.List;
|
import java.util.Map;
|
|
import javax.mail.internet.MimeMessage;
|
|
import org.jsoup.Jsoup;
|
import org.jsoup.nodes.Document;
|
import org.jsoup.nodes.Element;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.core.io.ByteArrayResource;
|
import org.springframework.core.io.InputStreamResource;
|
import org.springframework.core.io.InputStreamSource;
|
import org.springframework.mail.javamail.JavaMailSender;
|
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
import org.springframework.mail.javamail.MimeMessageHelper;
|
import org.springframework.util.StringUtils;
|
|
import com.alibaba.fastjson.JSONObject;
|
import com.qianwen.core.http.HttpRequest;
|
import com.qianwen.core.log.exception.ServiceException;
|
import com.qianwen.core.notify.DefaultNotifyType;
|
import com.qianwen.core.notify.NotifyType;
|
import com.qianwen.core.notify.Provider;
|
import com.qianwen.core.notify.notifier.AbstractNotifier;
|
import com.qianwen.core.notify.notifier.NotifierProperties;
|
import com.qianwen.core.notify.provider.email.EmailProvider;
|
import com.qianwen.core.notify.template.TemplateManager;
|
import com.qianwen.core.tool.api.ResultCode;
|
import com.qianwen.core.tool.metadata.Values;
|
import com.qianwen.core.tool.utils.ExpressionUtils;
|
import com.qianwen.core.tool.utils.Func;
|
import com.qianwen.core.tool.utils.StringUtil;
|
|
public class DefaultEmailNotifier extends AbstractNotifier<EmailTemplate> {
|
private static final Logger log = LoggerFactory.getLogger(DefaultEmailNotifier.class);
|
private String sender;
|
private JavaMailSender javaMailSender;
|
private NotifierProperties notifierProperties;
|
private String notifierId;
|
|
|
public String getSender() {
|
return this.sender;
|
}
|
|
public void setSender(final String sender) {
|
this.sender = sender;
|
}
|
|
public JavaMailSender getJavaMailSender() {
|
return this.javaMailSender;
|
}
|
|
public void setJavaMailSender(final JavaMailSender javaMailSender) {
|
this.javaMailSender = javaMailSender;
|
}
|
|
public void setNotifierProperties(final NotifierProperties notifierProperties) {
|
this.notifierProperties = notifierProperties;
|
}
|
|
public DefaultEmailNotifier(NotifierProperties properties, TemplateManager templateManager) {
|
super(templateManager);
|
this.notifierId = properties.getId();
|
DefaultEmailProperties emailProperties = (DefaultEmailProperties) new JSONObject(properties.getConfiguration()).toJavaObject(DefaultEmailProperties.class);
|
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
|
mailSender.setHost(emailProperties.getHost());
|
mailSender.setPort(emailProperties.getPort());
|
mailSender.setUsername(emailProperties.getUsername());
|
mailSender.setPassword(emailProperties.getPassword());
|
mailSender.setJavaMailProperties(emailProperties.createJavaMailProperties());
|
this.sender = emailProperties.getSender();
|
this.javaMailSender = mailSender;
|
this.notifierProperties = properties;
|
}
|
|
@Override // com.qianwen.core.notify.notifier.Notifier
|
public String getNotifierId() {
|
return this.notifierId;
|
}
|
|
@Override // com.qianwen.core.notify.notifier.Notifier
|
public NotifyType getType() {
|
return DefaultNotifyType.email;
|
}
|
|
@Override // com.qianwen.core.notify.notifier.Notifier
|
public Provider getProvider() {
|
return EmailProvider.embedded;
|
}
|
|
@Override // com.qianwen.core.notify.notifier.Notifier
|
public NotifierProperties getNotifierProperties() {
|
return this.notifierProperties;
|
}
|
|
public void send(EmailTemplate template, String traceId, Values context, List<String> notifiedParty) {
|
ParsedEmailTemplate parsedEmailTemplate = convert(template, context.getAllValues());
|
doSend(parsedEmailTemplate, notifiedParty);
|
}
|
|
protected void doSend(ParsedEmailTemplate template, List<String> sendTo) {
|
try {
|
MimeMessage mimeMessage = this.javaMailSender.createMimeMessage();
|
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "utf-8");
|
helper.setFrom(this.sender);
|
helper.setTo((String[]) sendTo.toArray(new String[0]));
|
helper.setSubject(template.getSubject());
|
helper.setText(new String(template.getContent().getBytes(), StandardCharsets.UTF_8), true);
|
for (Map.Entry<String, String> entry : template.getAttachments().entrySet()) {
|
String attachmentFileName = entry.getKey();
|
InputStreamSource fileResource = convertResource(entry.getValue());
|
if (Func.isNotEmpty(fileResource)) {
|
helper.addAttachment(attachmentFileName, fileResource);
|
}
|
}
|
for (Map.Entry<String, String> entry2 : template.getImages().entrySet()) {
|
String attachmentFileName2 = entry2.getKey();
|
InputStreamSource fileResource2 = convertResource(entry2.getValue());
|
if (Func.isNotEmpty(fileResource2)) {
|
helper.addInline(attachmentFileName2, fileResource2, "application/octet-stream");
|
}
|
}
|
this.javaMailSender.send(mimeMessage);
|
}catch(Exception ex) {
|
throw new RuntimeException(ex);
|
}
|
}
|
|
protected InputStreamSource convertResource(String resource) {
|
if (resource.startsWith("http")) {
|
HashMap<Object, Object> headers = new HashMap<>();
|
headers.put("Accept", "application/octet-stream");
|
byte[] fileBytes = HttpRequest.get(resource).addHeader("Accept", "application/octet-stream").execute().onFailed((k, v) -> log.info(StringUtil.format("获取附件资源{}失败,原因{}", new Object[] { k.url(), v.getMessage() }))).asBytes();
|
return (InputStreamSource)new ByteArrayResource(fileBytes);
|
}
|
try {
|
return (InputStreamSource)new InputStreamResource(new FileInputStream(resource));
|
} catch (FileNotFoundException e) {
|
log.error("处理邮件中资源文件异常:{},堆栈信息如下{}", e.getMessage(), e.getStackTrace());
|
return null;
|
}
|
}
|
|
protected ParsedEmailTemplate convert(EmailTemplate template, Map<String, Object> context) {
|
String subject = template.getSubject();
|
String content = template.getContent();
|
if (StringUtils.isEmpty(subject) || StringUtils.isEmpty(content)) {
|
throw new ServiceException(ResultCode.PARAM_MISS, new Throwable("模板内容错误,content 或者 subject 不能为空."));
|
}
|
String sendContent = render(content, context);
|
List<EmailTemplate.Attachment> tempAttachments = template.getAttachments();
|
Map<String, String> attachments = new HashMap<>();
|
if (tempAttachments != null) {
|
for (EmailTemplate.Attachment tempAttachment : tempAttachments) {
|
attachments.put(tempAttachment.getName(), render(tempAttachment.getLocation(), context));
|
}
|
}
|
return ParsedEmailTemplate.builder().attachments(attachments).images(extractSendContentImage(sendContent)).content(sendContent).subject(render(subject, context)).build();
|
}
|
|
private Map<String, String> extractSendContentImage(String sendContent) {
|
Map<String, String> images = new HashMap<>();
|
Document doc = Jsoup.parse(sendContent);
|
Iterator it = doc.getElementsByTag("img").iterator();
|
while (it.hasNext()) {
|
Element src = (Element) it.next();
|
String s = src.attr("src");
|
if (!s.startsWith("http")) {
|
String tempKey = Func.randomUUID();
|
src.attr("src", "cid:".concat(tempKey));
|
images.put(tempKey, s);
|
}
|
}
|
return images;
|
}
|
|
private String render(String str, Map<String, Object> context) {
|
return ExpressionUtils.analytical(str, context, "spel");
|
}
|
|
@Override // com.qianwen.core.notify.notifier.Notifier
|
public void close() {
|
}
|
}
|