package com.deloitte.system.service;
|
|
import cn.hutool.core.collection.CollectionUtil;
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.common.aws.util.S3Util;
|
import com.common.core.domain.DesensitiveType;
|
import com.common.core.enums.ResultCodeEnum;
|
import com.common.core.exception.BizException;
|
import com.common.core.service.SFService;
|
import com.common.core.utils.*;
|
import com.deloitte.system.model.MailMerge;
|
import com.deloitte.system.request.*;
|
import com.j256.simplemagic.ContentInfoUtil;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.core.env.Environment;
|
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.ResponseEntity;
|
import org.springframework.mail.javamail.JavaMailSender;
|
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
import org.springframework.stereotype.Service;
|
import org.springframework.util.ObjectUtils;
|
import software.amazon.awssdk.core.ResponseBytes;
|
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
|
|
import javax.activation.DataHandler;
|
import javax.activation.DataSource;
|
import javax.mail.*;
|
import javax.mail.internet.*;
|
import javax.mail.search.FlagTerm;
|
import javax.mail.util.ByteArrayDataSource;
|
import javax.transaction.Transactional;
|
import java.io.*;
|
import java.text.SimpleDateFormat;
|
import java.util.*;
|
|
/**
|
* @Author: Ben Pi
|
* @Date: 08/02/2022 15:16
|
*/
|
@Slf4j
|
@Service
|
public class MailService {
|
|
@Value("${aws.s3.bucketName}")
|
private String bucketName;
|
|
@Value("${mail.default-encoding}")
|
private String defaultEncoding;
|
|
@Value("${mail.smtp.host}")
|
private String smtpHost;
|
@Value("${mail.smtp.port}")
|
private Integer smtpPort;
|
@Value("${mail.smtp.protocol}")
|
private String smtpProtocol;
|
|
@Value("${mail.imap.host}")
|
private String imapHost;
|
@Value("${mail.imap.port}")
|
private String imapPort;
|
@Value("${mail.imap.protocol}")
|
private String imapProtocol;
|
|
@Value("${salesforce.baseUrl}")
|
private String sfUrl;
|
|
@Value("${file.url}")
|
private String fileUrl;
|
|
@Autowired
|
private IdUtils idWorker;
|
|
@Autowired
|
FileService fileService;
|
|
@Autowired
|
private SFService sfService;
|
|
public String sendEmail(String txId,MessageVo messageVo) {
|
try {
|
JavaMailSender mailSender=getMailSender();
|
log.info("开始发送邮件:from["+messageVo.getFrom()+"]"+"subject["+messageVo.getSubjectCopy()+"]");
|
MimeMessage message = mailSender.createMimeMessage();
|
generateMessage(message,messageVo);
|
// 更新notSaveEmail状态为true
|
updateSFRecord(messageVo.getRecordType(),messageVo.getRecordId());
|
// 处理邮件数据,发送sf mailMerge
|
Map<String,String> idMap=handleEmail(message,messageVo.getRecordId(),messageVo.getRecordType().substring(0,1).toUpperCase(),true,messageVo.getFileMap());
|
//发送邮件
|
mailSender.send(message);
|
log.info("结束发送邮件:from["+messageVo.getFrom()+"]"+"subject["+messageVo.getSubjectCopy()+"]");
|
// 返回sf mailMerge id
|
return idMap.get("mailMergeId");
|
} catch (Exception e) {
|
log.error("发送邮件失败:",e);
|
throw new BizException(ResultCodeEnum.EMAIL_ERROR);
|
}
|
}
|
private JavaMailSender getMailSender(){
|
this.getInit();
|
JavaMailSenderImpl sender = new JavaMailSenderImpl();
|
sender.setHost(smtpHost);
|
sender.setDefaultEncoding(defaultEncoding);
|
sender.setPort(smtpPort);
|
sender.setProtocol(smtpProtocol);
|
sender.setUsername(username);
|
sender.setPassword(password);
|
Properties p = new Properties();
|
p.setProperty("mail.smtp.auth", "true");
|
p.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
|
p.setProperty("mail.smtp.socketFactory.fallback", "false");
|
p.setProperty("mail.smtp.socketFactory.port", smtpPort.toString());
|
sender.setJavaMailProperties(p);
|
return sender;
|
}
|
|
/**
|
* 更新邮件notSaveEmail状态
|
*
|
* @param recordType
|
* @param recordId
|
*/
|
private void updateSFRecord(String recordType, String recordId) {
|
//更新SWO或其他表的 notSaveEmail 标识符
|
JSONObject jsonObject = new JSONObject();
|
//标记跳过邮件回复监听
|
jsonObject.put("notSaveEmail__c",true);
|
String tableName = "";
|
if("SWO".equalsIgnoreCase(recordType)){
|
tableName = "SWO__c";
|
}
|
if("Case".equalsIgnoreCase(recordType)){
|
tableName = "User_FaultInfo__c";
|
}
|
if("Quotes".equals(recordType)){
|
String sql="select Id,Name,notSaveEmail__c,SWO__c,SWO__r.Quotation_send__c from Quotes__c where Id= '"+recordId+"'";
|
JSONObject quotes=sfService.querySFData(sql).getJSONObject(0);
|
tableName = "Quotes__c";
|
if (StringUtils.isNotBlank(quotes.getString("SWO__c")) && quotes.get("SWO__r.Quotation_send__c") == null) {
|
JSONObject swo = new JSONObject();
|
String swoRecordId = quotes.getString("SWO__c");
|
swo.put("Quotation_send__c",new Date());
|
// update swo;
|
sfService.updateSFData("SWO__c",swoRecordId,swo);
|
}
|
}
|
sfService.updateSFData(tableName,recordId,jsonObject);
|
}
|
|
@Autowired
|
private Environment env;
|
@Autowired
|
private SecretsManagerUtils secretsManagerUtils;
|
public void receiveImapMail() {
|
try {
|
this.getInit();
|
// 准备连接服务器的会话信息
|
Properties props = new Properties();
|
props.setProperty("mail.store.protocol", imapProtocol);
|
props.setProperty("mail.imap.host", imapHost);
|
props.setProperty("mail.imap.port", imapPort);
|
props.setProperty("mail.imap.ssl.enable", "true");
|
props.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
|
// 创建Session实例对象
|
Session session = Session.getDefaultInstance(props, new Authenticator(){
|
@Override
|
protected PasswordAuthentication getPasswordAuthentication() {
|
return new PasswordAuthentication(username, password);
|
}
|
});
|
session.setDebug(false);
|
// 连接邮件服务器
|
Store store = session.getStore(imapProtocol);
|
store.connect(imapHost,Integer.valueOf(imapPort), username, password);
|
Folder folder = store.getFolder("INBOX");
|
folder.open(Folder.READ_WRITE);
|
|
// 获得收件箱的邮件列表
|
FlagTerm ft = new FlagTerm(new Flags(Flags.Flag.SEEN), false);
|
Message[] messages = folder.search(ft);
|
log.info("------------------------开始解析邮件----------------------------------");
|
log.info("-----------------您的邮箱共有新邮件:" + messages.length + " 封--------------");
|
for (int i = 0; i < messages.length; i++) {
|
try {
|
Message msg = messages[i];
|
//业务处理 1.写入mail merge 2.存储附件
|
processReceiveEmail(msg);
|
// 邮件在处理完成后更新邮件状态为已读
|
msg.setFlag(Flags.Flag.SEEN, true);
|
}catch (Exception e){
|
log.error("同步邮件失败:",e);
|
}
|
}
|
log.info("----------------End------------------");
|
// 关闭资源
|
folder.close(false);
|
store.close();
|
}catch (Exception e){
|
log.error("同步邮件失败:",e);
|
}
|
}
|
|
/**
|
* 接收邮件处理
|
*
|
* @param msg
|
* @return 返回当前邮件是否需要接收标识(需要接收:true,不需要接收:false)
|
* @throws Exception
|
*/
|
private void processReceiveEmail(Message msg) throws Exception {
|
log.info("接收邮件:" + msg.getSubject());
|
if(StringUtils.isEmpty(msg.getSubject())){
|
return;
|
}
|
//[EXT]Sandbox: 回复:h45h54h54~SWO:Test By Bubba
|
String[] str = msg.getSubject().split("~");
|
if(str.length < 2){
|
log.info("当前邮件不做处理:{}",msg.getSubject());
|
return;
|
}
|
String type= null;
|
String recordId= null;
|
//SWO:Test By Bubba
|
String nameAll = str[1];
|
//S
|
type = nameAll.substring(0,1);
|
String tableName = type.equalsIgnoreCase("s") ? "SWO__c":
|
(type.equalsIgnoreCase("c") ? "User_FaultInfo__c": (type.equalsIgnoreCase("q") ? "Quotes__c" : ""));
|
//Test By Bubba
|
String name = nameAll.substring(nameAll.indexOf(":")+1);
|
if(StringUtils.isEmpty(tableName)||StringUtils.isEmpty(name)){
|
log.info("解析tableName或name为空,subject:{}",msg.getSubject());
|
return;
|
}
|
String sql="select Id,notSaveEmail__c,Name from "+tableName+" where Name= '"+name+"'";
|
JSONArray jsonArray=sfService.querySFData(sql);
|
if(jsonArray==null || jsonArray.size()==0){
|
log.info("邮件:{},查询notSaveEmail结果为空,tableName:{},name:{}",msg.getSubject(),tableName,name);
|
return;
|
}
|
recordId = jsonArray.getJSONObject(0).getString("Id");
|
if( jsonArray.getJSONObject(0).getBoolean("notSaveEmail__c")){
|
log.info("跳过邮件服务监听:" + msg.getSubject()+","+recordId);
|
// 更新notSaveEmail__c标识
|
JSONObject jsonObject = new JSONObject();
|
//标记跳过邮件回复监听
|
jsonObject.put("notSaveEmail__c",false);
|
sfService.updateSFData(tableName,recordId,jsonObject);
|
// 此处为自己抄送给自己的邮件,设置为已读
|
return;
|
}
|
handleEmail(msg, recordId, type,false,null);
|
}
|
|
/**
|
* 处理email方法
|
*
|
* @param msg 邮件对象
|
* @param recordId 关联id eg:swo_id
|
* @param type 邮件类型 eg:swo
|
* @param isSend 是否为发出的邮件(发出:true,接收:false)
|
* @param fileMap 附件信息(key:s3文件Key,value:fileName)
|
* @return
|
* @throws Exception
|
*/
|
@Transactional
|
public Map<String, String> handleEmail(Message msg, String recordId, String type, boolean isSend, Map<String, String> fileMap) throws MessagingException {
|
|
log.info("------------- save email -------------");
|
try {
|
//保存邮件
|
MailMerge mailMerge = saveMailMerge(msg, recordId, type, isSend);
|
|
//接收到的邮件->保存附件到s3
|
if (!isSend) {
|
//解析到邮件中的附件,key为附件,value为filename
|
Map<BodyPart,String> parsedFileMap = new HashMap<>();
|
parseAttachMent(msg, parsedFileMap);
|
//遍历保存附件文件到s3
|
for (BodyPart bodyPart : parsedFileMap.keySet()) {
|
String fileName = parsedFileMap.get(bodyPart);
|
String key = saveFile(fileName,bodyPart);
|
fileMap = new HashMap<>();
|
fileMap.put(key,fileName);
|
}
|
}
|
|
//推送邮件和附件信息到SF idMap -> key:mailMergeId/fileAddressId,value:salesforce保存后返回的id,如果有多个附件,id用","分隔
|
Map<String, String> idMap = postMailToSF(mailMerge, fileMap);
|
// 回写sfid
|
updateMailMerge(idMap,mailMerge.getDataId());
|
return idMap;
|
} catch (Exception e) {
|
log.error("保存邮件异常,{}",e.getMessage(),e);
|
// 修改Message状态为未读
|
msg.setFlag(Flags.Flag.SEEN,false);
|
throw new BizException("保存邮件异常");
|
}
|
}
|
|
/**
|
* 保存mailmerge
|
*
|
* @param msg 邮件对象
|
* @param recordId 关联id eg:swo_id
|
* @param type 邮件类型 eg:swo
|
* @param isSend 是否为发出的邮件(发出:true,接收:false)
|
* @return
|
* @throws Exception
|
*/
|
private MailMerge saveMailMerge(Message msg, String recordId, String type,boolean isSend) throws Exception {
|
MailMerge mailMerge = new MailMerge();
|
String dataId = idWorker.nextId();
|
mailMerge.setDataId(Long.parseLong(dataId));
|
mailMerge.setRecord(recordId);
|
//邮件标题
|
if(StringUtils.isNotBlank(msg.getSubject())){
|
mailMerge.setSubjectCopy(msg.getSubject());
|
String[] str = msg.getSubject().split("~");
|
mailMerge.setSubject(str[0]);
|
mailMerge.setName(str[0]);
|
}else{
|
mailMerge.setSubjectCopy("");
|
mailMerge.setSubject("");
|
mailMerge.setName("");
|
}
|
if("S".equals(type)){
|
mailMerge.setSwo(recordId);
|
mailMerge.setRecordType("SWO");
|
}
|
if("C".equals(type)){
|
mailMerge.setCaseF(recordId);
|
mailMerge.setRecordType("Case");
|
}
|
if("Q".equals(type)){
|
mailMerge.setQuotes(recordId);
|
mailMerge.setRecordType("Quotes");
|
}
|
//发件人地址
|
InternetAddress address[];
|
if(isSend) {
|
address = (InternetAddress[]) msg.getReplyTo();
|
}else{
|
address = (InternetAddress[]) msg.getFrom();
|
}
|
String author = (address!=null && address.length>0) ?address[0].getAddress():"";
|
mailMerge.setFrom(author);
|
mailMerge.setAuthor(author);
|
//收件人地址
|
mailMerge.setRecipient(getMailAddress(msg,"TO"));
|
//抄送人
|
mailMerge.setCc(getMailAddress(msg,"CC"));
|
//秘抄送人
|
mailMerge.setBcc(getMailAddress(msg,"BCC"));
|
|
setAllMember(mailMerge,getMailAddressMap(msg,"TO"),getMailAddressMap(msg,"CC"),getMailAddressMap(msg,"BCC"));
|
//邮件信息
|
StringBuffer bodytext = new StringBuffer();
|
Multipart multipart = (msg.getContent() instanceof String) ? null : (Multipart) msg.getContent();
|
String mailContent;
|
if(multipart==null){
|
mailContent=msg.getContent().toString();
|
}else {
|
int counts = multipart.getCount();
|
for (int i = 0; i < counts; i++) {
|
getMailContent(multipart.getBodyPart(i), bodytext);
|
}
|
mailContent = bodytext.toString();
|
}
|
mailMerge.setMessage(mailContent);
|
//收取回复邮件时间
|
mailMerge.setDate(new Date());
|
|
if(isSend){
|
mailMerge.setType("send");
|
}else {
|
mailMerge.setType("reply");
|
}
|
mailMerge.setEmailSent("YES");
|
|
log.info("保存mail merge:{}",mailMerge.toString());
|
mailMerge.save();
|
|
return mailMerge;
|
}
|
|
/**
|
* 更新sf返回的mailMergeId和fileAddressId到mail_merge表
|
*
|
* @param idMap
|
*/
|
public void updateMailMerge(Map<String,String> idMap,Long dataId){
|
MailMerge mailMerge = new MailMerge();
|
mailMerge.setDataId(dataId);
|
String mailMergeId = idMap.get("mailMergeId");
|
String fileAddressId = idMap.get("fileAddressId");
|
mailMerge.setSfRecordId(mailMergeId);
|
mailMerge.setSfFileAddressId(fileAddressId);
|
log.info("update mail_merge---------->id:{},mailMergeId:{},fileAddressId:{}",dataId,mailMergeId,fileAddressId);
|
mailMerge.update();
|
}
|
|
/**
|
* 解析附件
|
*/
|
private void parseAttachMent(Part part,Map fileMap) throws Exception {
|
|
String fileName = "";
|
if (part.isMimeType("multipart/*")) {
|
Multipart mp = (Multipart) part.getContent();
|
for (int i = 0; i < mp.getCount(); i++) {
|
BodyPart mpart = mp.getBodyPart(i);
|
String disposition = mpart.getDisposition();
|
if ((disposition != null)
|
&& ((disposition.equals(Part.ATTACHMENT)) || (disposition
|
.equals(Part.INLINE)))) {
|
fileName = mpart.getFileName();
|
if(StringUtils.isBlank(fileName) && "message/rfc822".equalsIgnoreCase(mpart.getHeader("Content-Type")[0])){
|
Properties props = new Properties();
|
Session session = Session.getInstance(props, null);
|
MimeMessage msg=new MimeMessage(session,mpart.getInputStream());
|
fileName=msg.getSubject()+".eml";
|
}
|
fileName = MimeUtility.decodeText(fileName);
|
//附件写入map
|
fileMap.put(mpart,fileName);
|
} else if (mpart.isMimeType("multipart/*")) {
|
parseAttachMent(mpart,fileMap);
|
} else {
|
fileName = mpart.getFileName();
|
if (fileName != null) {
|
fileName = MimeUtility.decodeText(fileName);
|
fileMap.put(mpart,fileName);
|
}
|
}
|
}
|
} else if (part.isMimeType("message/rfc822")) {
|
parseAttachMent((Part) part.getContent(),fileMap);
|
}
|
|
}
|
|
/**
|
* 保存文件到s3
|
*/
|
private String saveFile(String fileName,BodyPart bodyPart) throws IOException, MessagingException {
|
log.info("保存附件:"+fileName);
|
FileRequest fileRequest = new FileRequest();
|
fileRequest.setFileName(fileName);
|
String contentType= ContentInfoUtil.findExtensionMatch(fileName)==null?"text/plain": ContentInfoUtil.findExtensionMatch(fileName).getMimeType();
|
String basePrefix="data:"+contentType+";base64,";
|
int size = bodyPart.getSize();
|
byte [] buffer = new byte[size];
|
InputStream instream;
|
instream = bodyPart.getInputStream();
|
instream.read(buffer,0,size);
|
fileRequest.setFile(basePrefix+ Base64.getEncoder().encodeToString(buffer));
|
String key = fileService.uploadFileNoSize(fileRequest);
|
log.info("附件上传至s3完成,key:"+key);
|
return key;
|
}
|
|
|
/**
|
* 获得邮件的收件人,抄送,和密送的地址,根据所传递的参数的不同 "to"----收件人 "cc"---抄送人地址 "bcc"---密送人地址
|
*/
|
public String getMailAddress(Message msg,String type) throws Exception {
|
StringBuilder mailaddr = new StringBuilder();
|
Map<String, String> mailAddressMap = getMailAddressMap(msg, type);
|
Set<String> addressSet = mailAddressMap.keySet();
|
for (String address:addressSet) {
|
mailaddr.append(address).append(";");
|
}
|
return mailaddr.toString();
|
}
|
|
/**
|
* 获得邮件的收件人,抄送,和密送的地址,根据所传递的参数的不同 "to"----收件人 "cc"---抄送人地址 "bcc"---密送人地址
|
*
|
* @return key:邮件地址,value:发送人名称
|
*/
|
public Map<String,String> getMailAddressMap(Message msg,String type) throws Exception {
|
HashMap<String,String> addressMap = new HashMap<>();
|
String addtype = type.toUpperCase();
|
InternetAddress[] address = null;
|
if ("TO".equals(addtype) || "CC".equals(addtype)|| "BCC".equals(addtype)) {
|
if ("TO".equals(addtype)) {
|
address = (InternetAddress[]) msg.getRecipients(Message.RecipientType.TO);
|
} else if ("CC".equals(addtype)) {
|
address = (InternetAddress[]) msg.getRecipients(Message.RecipientType.CC);
|
} else {
|
address = (InternetAddress[]) msg.getRecipients(Message.RecipientType.BCC);
|
}
|
if (address != null) {
|
for (int i = 0; i < address.length; i++) {
|
String email = address[i].getAddress();
|
if (email == null) {
|
email = "";
|
} else {
|
email = MimeUtility.decodeText(email);
|
}
|
String personal = address[i].getPersonal();
|
if (personal == null) {
|
personal = "";
|
} else {
|
personal = MimeUtility.decodeText(personal);
|
}
|
addressMap.put(email,personal);
|
}
|
}
|
} else {
|
throw new Exception("Error emailaddr type!");
|
}
|
return addressMap;
|
}
|
|
/**
|
* 解析邮件,把得到的邮件内容保存到一个StringBuffer对象中,解析邮件 根据MimeType类型的不同执行不同的操作
|
*/
|
public String getMailContent(Part part,StringBuffer bodytext) throws Exception {
|
|
String contenttype = part.getContentType();
|
int nameindex = contenttype.indexOf("name");
|
boolean conname = false;
|
if (nameindex != -1) {
|
conname = true;
|
}
|
if (part.isMimeType("text/plain") && !conname) {
|
if (part.getContent() instanceof InputStream) {
|
return null;
|
}
|
// 只保存文本内容
|
bodytext.append((String) part.getContent());
|
log.info("添加邮件文本:{}",part.getContent().toString());
|
} else if (part.isMimeType("multipart/*")) {
|
Multipart multipart = (Multipart) part.getContent();
|
int counts = multipart.getCount();
|
for (int i = 0; i < counts; i++) {
|
getMailContent(multipart.getBodyPart(i),bodytext);
|
}
|
} else if (part.isMimeType("message/rfc822")) {
|
getMailContent((Part) part.getContent(),bodytext);
|
} else {
|
//其他类型暂不处理
|
}
|
return bodytext.toString();
|
}
|
|
private void setAllMember(MailMerge mailMerge,Map<String,String> toAddress,Map<String,String> ccAddresses,Map<String,String> bccAddresses) {
|
mailMerge.setAllMember("");
|
mailMerge.setAllMemberName("");
|
mailMerge.setAllMemberType("");
|
if(toAddress !=null && toAddress.keySet().size()!=0){
|
for(String address : toAddress.keySet()){
|
//邮件地址之间用“;”隔开,发送邮件页会用“;”分割字符串
|
mailMerge.setAllMember(mailMerge.getAllMember() + address + ";");
|
//名字暂时都用“-”,邮件页面分割出“-”会用空代替
|
mailMerge.setAllMemberName(mailMerge.getAllMemberName() + toAddress.get(address)+ ";");
|
mailMerge.setAllMemberType(mailMerge.getAllMemberType() + "to;");
|
}
|
}
|
if(ccAddresses !=null && ccAddresses.keySet().size()!=0){
|
for(String address : ccAddresses.keySet()){
|
if(address.startsWith("email@") || "".equals(address)){
|
continue;
|
}
|
//邮件地址之间用“;”隔开,发送邮件页会用“;”分割字符串
|
mailMerge.setAllMember(mailMerge.getAllMember() + address + ';');
|
//名字暂时都用“-”,邮件页面分割出“-”会用空代替
|
mailMerge.setAllMemberName(mailMerge.getAllMemberName() + "-;");
|
mailMerge.setAllMemberType(mailMerge.getAllMemberType() + "cc;");
|
}
|
}
|
if(bccAddresses !=null && bccAddresses.keySet().size()!=0){
|
for(String address : bccAddresses.keySet()){
|
if(address.startsWith("email@") || "".equals(address)){
|
continue;
|
}
|
//邮件地址之间用“;”隔开,发送邮件页会用“;”分割字符串
|
mailMerge.setAllMember(mailMerge.getAllMember() + address + ';');
|
//名字暂时都用“-”,邮件页面分割出“-”会用空代替
|
mailMerge.setAllMemberName(mailMerge.getAllMemberName() + "-;");
|
mailMerge.setAllMemberType(mailMerge.getAllMemberType() + "bcc;");
|
}
|
}
|
}
|
|
|
/**
|
* 调用salesforce 邮件保存接口
|
*
|
* @return Map<String,String> key:mailMergeId/fileAddressId,value:salesforce保存后返回的id,如果有多个附件,id用","分隔
|
*/
|
public Map<String,String> postMailToSF(MailMerge mailMerge,Map<String,String> fileMap){
|
|
HashMap<String, String> idMap = new HashMap<>();
|
|
SfCompositeRequest request = new SfCompositeRequest();
|
//mailMerge to SFMessageVo
|
SFMessageVo sfMessageVo = mailMergeToSFMessageVo(mailMerge);
|
request.addMailMerge(sfMessageVo);
|
// fileMap to SFFileAddressVo
|
if (fileMap!=null && fileMap.size()>0) {
|
List<SFFileAddressVo> sfFileAddressVos = fileMapToSFFileAddressVo(fileMap);
|
request.addFileAddress(sfFileAddressVos);
|
}
|
|
SFTokenDto tokenDto = sfService.getToken();
|
String accessToken = tokenDto.getAccessToken();
|
HttpHeaders header = new HttpHeaders();
|
header.add("Authorization", "Bearer " + accessToken);
|
header.add("Content-Type","application/json");
|
|
try {
|
String requestBody = request.toJsonString();
|
log.info("推送sf邮件接口,request:{}",requestBody);
|
ResponseEntity sfRes = RestUtil.postNative(sfUrl + "services/data/v53.0/composite", header, null, request.toJsonString());
|
log.info("推送sf邮件接口,response:{}",Objects.requireNonNull(sfRes.getBody()).toString());
|
int statusCodeValue = sfRes.getStatusCodeValue();
|
JSONObject body = (JSONObject)sfRes.getBody();
|
JSONArray responseBody = body.getJSONArray("compositeResponse");
|
responseBody.forEach(object -> {
|
LinkedHashMap map = (LinkedHashMap) object;
|
// 判断返回状态
|
if(!map.get("httpStatusCode").toString().startsWith("2")){
|
log.error("推送salesforce邮件接口返回异常,response:"+sfRes.getBody());
|
throw new BizException("推送salesforce邮件接口返回状态异常");
|
}
|
// 获取返回参数中的mailMergeId
|
if ("NewMailMerge".equals(map.get("referenceId"))) {
|
LinkedHashMap body1 = (LinkedHashMap) map.get("body");
|
String mailMergeId = body1.get("id").toString();
|
idMap.put("mailMergeId",mailMergeId);
|
}
|
// 获取返回参数中的NewFileAddress,如果是多个,用','拼接
|
StringBuilder fileAddressIdBuilder = new StringBuilder();
|
if (map.get("referenceId").toString().startsWith("NewFileAddress")) {
|
LinkedHashMap body1 = (LinkedHashMap) map.get("body");
|
String fileAddressId = body1.get("id").toString();
|
fileAddressIdBuilder.append(",").append(fileAddressId);
|
}
|
if(fileAddressIdBuilder.length()>0){
|
String substring = fileAddressIdBuilder.substring(1);
|
idMap.put("fileAddressId",substring);
|
}
|
});
|
if(!Integer.toString(statusCodeValue).startsWith("2")){
|
throw new BizException("请求SF服务保存邮件异常,response code:"+statusCodeValue);
|
}
|
} catch (Exception e) {
|
log.error("请求SF服务异常",e);
|
throw new BizException("请求SF服务保存邮件异常");
|
}
|
return idMap;
|
}
|
|
//mailMerge to SFMessageVo
|
public SFMessageVo mailMergeToSFMessageVo(MailMerge mailMerge){
|
|
SFMessageVo sfMessageVo = new SFMessageVo();
|
sfMessageVo.setName(mailMerge.getName());
|
|
Map<String, String> desensitiveAllMemberNameMap = parseStringToDesensitive(mailMerge.getAllMemberName(),DesensitiveType.CHINESE_NAME);
|
sfMessageVo.setALL_MEMBER_NAME__c(desensitiveAllMemberNameMap.get("desensitive"));
|
sfMessageVo.setALL_MEMBER_NAME_Encrypted__c(desensitiveAllMemberNameMap.get("encrypt"));
|
|
sfMessageVo.setALL_MEMBER_TYPE__c(mailMerge.getAllMemberType());
|
|
Map<String, String> desensitiveAllMemberMap = parseStringToDesensitive(mailMerge.getAllMember(),DesensitiveType.EMAIL);
|
sfMessageVo.setALL_MEMBER__c(desensitiveAllMemberMap.get("desensitive"));
|
sfMessageVo.setALL_MEMBER_Encrypted__c(desensitiveAllMemberMap.get("encrypt"));
|
|
Map<String, String> desensitiveCcMap = parseStringToDesensitive(mailMerge.getCc(),DesensitiveType.EMAIL);
|
sfMessageVo.setCC__c(desensitiveCcMap.get("desensitive"));
|
sfMessageVo.setCC_Encrypted__c(desensitiveCcMap.get("encrypt"));
|
|
Map<String, String> desensitiveBccMap = parseStringToDesensitive(mailMerge.getBcc(),DesensitiveType.EMAIL);
|
sfMessageVo.setBCC__c(desensitiveBccMap.get("desensitive"));
|
sfMessageVo.setBCC_Encrypted__c(desensitiveBccMap.get("encrypt"));
|
|
Map<String, String> desensitiveFromMap = parseStringToDesensitive(mailMerge.getFrom(),DesensitiveType.EMAIL);
|
sfMessageVo.setFROM__c(desensitiveFromMap.get("desensitive"));
|
sfMessageVo.setFROM_Encrypted__c(desensitiveFromMap.get("encrypt"));
|
|
sfMessageVo.setMESSAGE__c(mailMerge.getMessage());
|
|
Map<String, String> desensitiveRecipientMap = parseStringToDesensitive(mailMerge.getRecipient(),DesensitiveType.EMAIL);
|
sfMessageVo.setRECIPIENT__c(desensitiveRecipientMap.get("desensitive"));
|
sfMessageVo.setRECIPIENT_Encrypted__c(desensitiveRecipientMap.get("encrypt"));
|
|
sfMessageVo.setRECORD_TYPE__c(mailMerge.getRecordType());
|
sfMessageVo.setSUBJECTCOPY__c(mailMerge.getSubjectCopy());
|
sfMessageVo.setSUBJECT__c(mailMerge.getSubject());
|
sfMessageVo.setTYPE__c(mailMerge.getType());
|
|
Map<String, String> desensitiveBccNameMap = parseStringToDesensitive(mailMerge.getBccName(),DesensitiveType.CHINESE_NAME);
|
sfMessageVo.setBccName__c(desensitiveBccNameMap.get("desensitive"));
|
sfMessageVo.setBccName_Encrypted__c(desensitiveBccNameMap.get("encrypt"));
|
|
Map<String, String> desensitiveCcNameMap = parseStringToDesensitive(mailMerge.getCcName(),DesensitiveType.CHINESE_NAME);
|
sfMessageVo.setCcName__c(desensitiveCcNameMap.get("desensitive"));
|
sfMessageVo.setCcName_Encrypted__c(desensitiveCcNameMap.get("encrypt"));
|
|
Map<String, String> desensitiveToNameMap = parseStringToDesensitive(mailMerge.getToName(),DesensitiveType.CHINESE_NAME);
|
sfMessageVo.setToName__c(desensitiveToNameMap.get("desensitive"));
|
sfMessageVo.setToName_Encrypted__c(desensitiveToNameMap.get("encrypt"));
|
|
sfMessageVo.setAWS_Data_Id__c(mailMerge.getDataId().toString());
|
sfMessageVo.setDATE__c(mailMerge.getDate()==null?null:DateUtils.formatToUtc(mailMerge.getDate(),DateUtils.DATE_TIME_GL_ST_FORMAT_ZT_1));
|
sfMessageVo.setRECORD__c(mailMerge.getRecord());
|
sfMessageVo.setRECORD_TYPE__c(mailMerge.getRecordType());
|
sfMessageVo.setSWO__c(mailMerge.getSwo());
|
sfMessageVo.setCaseF__c(mailMerge.getCaseF());
|
sfMessageVo.setQuotes__c(mailMerge.getQuotes());
|
|
sfMessageVo.setEMAIL_SENT__c(mailMerge.getEmailSent());
|
|
return sfMessageVo;
|
}
|
|
|
//fileMap to SFFileAddressVo
|
private List<SFFileAddressVo> fileMapToSFFileAddressVo(Map<String, String> fileMap){
|
|
ArrayList<SFFileAddressVo> sfFileAddressVos = new ArrayList<>();
|
for (String fileKey:fileMap.keySet()) {
|
SFFileAddressVo sfFileAddressVo = new SFFileAddressVo();
|
String fileName = fileMap.get(fileKey);
|
sfFileAddressVo.setAWS_File_Key__c(fileKey);
|
sfFileAddressVo.setFileName__c(fileName);
|
sfFileAddressVo.setParentRecordId__c("@{NewMailMerge.id}");
|
sfFileAddressVo.setDownloadLink__c(fileUrl+"download?key="+fileKey+"&fileName="+fileName);
|
sfFileAddressVo.setViewLink__c(fileUrl+"preview?key="+fileKey);
|
sfFileAddressVos.add(sfFileAddressVo);
|
}
|
return sfFileAddressVos;
|
}
|
|
/**
|
* 将String转换为脱敏字符串和加密字符串
|
*
|
* @param s
|
* @return
|
*/
|
private static Map<String,String> parseStringToDesensitive(String s,DesensitiveType desensitiveType){
|
|
HashMap<String, String> map = new HashMap<>();
|
if("".equals(s) || s==null){
|
map.put("desensitive",s);
|
map.put("encrypt",s);
|
return map;
|
}
|
|
// 脱敏内容
|
StringBuilder desensitiveS = new StringBuilder();
|
// 加密内容
|
StringBuilder encryptS = new StringBuilder();
|
//twtyypmb;twtyypmb66;-;-;
|
String[] split = s.split(";");
|
for (String name:split) {
|
if(!"-".equals(name)){
|
desensitiveS.append(DesensitiveUtils.getFieldDesensitive(desensitiveType)).append(";");
|
String encryptStr = SM4Utils.encryptStr(name);
|
encryptS.append(encryptStr).append(";");
|
}else {
|
desensitiveS.append(name).append(";");
|
encryptS.append(name).append(";");
|
}
|
}
|
// 判断是否需要加;
|
if(!s.endsWith(";") && s.length()>0){
|
desensitiveS.delete(desensitiveS.length()-1,desensitiveS.length());
|
encryptS.delete(encryptS.length()-1,encryptS.length());
|
}
|
map.put("desensitive",desensitiveS.toString());
|
map.put("encrypt",encryptS.toString());
|
return map;
|
}
|
|
|
private void generateMessage(MimeMessage message,MessageVo messageVo) throws Exception {
|
this.getInit();
|
message.setSubject(messageVo.getSubjectCopy(), "UTF-8");
|
message.setFrom(new InternetAddress(username));
|
if(!ObjectUtils.isEmpty(messageVo.getFrom())) {
|
message.addHeader("Sender", messageVo.getFrom());
|
message.addHeader("Return-Path", messageVo.getFrom());
|
message.setReplyTo(new InternetAddress[]{new InternetAddress(messageVo.getFrom(), messageVo.getFromName()),new InternetAddress(username, "-")});
|
// message.addHeader("In-Reply-To", messageVo.getFrom());
|
// message.addHeader("Reply-To", messageVo.getFrom());
|
}
|
if(StringUtils.isNotEmpty(messageVo.getRecipient())) {
|
String[] addressList=messageVo.getRecipient().split(";");
|
String[] nameList=messageVo.getToName().split(";");
|
for (int i = 0; i < addressList.length; i++) {
|
try {
|
message.addRecipient(Message.RecipientType.TO, new InternetAddress(addressList[i],nameList[i]));
|
} catch (Exception e) {
|
log.error("添加收件人失败,from:"+messageVo.getFrom()+",to:"+addressList[i]+",subject:"+messageVo.getSubjectCopy());
|
log.error("添加收件人失败",e);
|
}
|
}
|
}
|
if(StringUtils.isNotEmpty(messageVo.getRecipient())) {
|
// 添加监听邮件
|
String cc = messageVo.getCc();
|
String ccName = messageVo.getCcName();
|
if(cc==null || "".equals(cc)){
|
cc = username;
|
ccName = username.substring(0,username.indexOf("@"));
|
}else if(!cc.contains(username)){
|
// cc列表中没有olympus公邮,将公邮添加到cc中
|
cc += ";"+username;
|
ccName += ";"+username.substring(0,username.indexOf("@"));
|
}
|
String[] addressList=cc.split(";");
|
String[] nameList=ccName.split(";");
|
for (int i = 0; i < addressList.length; i++) {
|
try {
|
message.addRecipient(Message.RecipientType.CC, new InternetAddress(addressList[i],nameList[i]));
|
} catch (Exception e) {
|
log.error("添加CC收件人失败,from:"+messageVo.getFrom()+",cc:"+addressList[i]+",subject:"+messageVo.getSubjectCopy());
|
log.error("添加收件人失败",e);
|
}
|
}
|
}
|
if(StringUtils.isNotEmpty(messageVo.getBcc())) {
|
String[] addressList=messageVo.getBcc().split(";");
|
String[] nameList=messageVo.getBccName().split(";");
|
for (int i = 0; i < addressList.length; i++) {
|
try {
|
message.addRecipient(Message.RecipientType.BCC, new InternetAddress(addressList[i],nameList[i]));
|
} catch (Exception e) {
|
log.error("添加收件人失败,from:"+messageVo.getFrom()+",bcc:"+addressList[i]+",subject:"+messageVo.getSubjectCopy());
|
log.error("添加收件人失败",e);
|
}
|
}
|
}
|
|
// Create a wrapper for the HTML and text parts
|
MimeBodyPart wrap = new MimeBodyPart();
|
|
// Add the child container to the wrapper object
|
wrap.setContent(messageVo.getMessage(), "text/plain; charset=UTF-8");
|
|
// Create a multipart/mixed parent container
|
MimeMultipart msg = new MimeMultipart("mixed");
|
|
// Add the multipart/alternative part to the message
|
msg.addBodyPart(wrap);
|
// Define the attachment
|
if(CollectionUtil.isNotEmpty(messageVo.getFileMap())){
|
messageVo.getFileMap().forEach((fileKey,fileName) ->{
|
try {
|
ResponseBytes<GetObjectResponse> objectBytes = S3Util.downloadFile(fileKey, bucketName);
|
byte[] fileContent = objectBytes.asByteArray();
|
MimeBodyPart att = new MimeBodyPart();
|
DataSource fds = new ByteArrayDataSource(fileContent, ContentInfoUtil.findExtensionMatch(fileName).getMimeType());
|
att.setDataHandler(new DataHandler(fds));
|
att.setFileName(fileName);
|
// Add the attachment to the message.
|
MimeBodyPart attachFileBodypart = new MimeBodyPart();
|
MimeMultipart attachFileMMP = new MimeMultipart("related");
|
attachFileMMP.addBodyPart(att);
|
attachFileBodypart.setContent(attachFileMMP,"text/html;charset=UTF-8");
|
msg.addBodyPart(attachFileBodypart);
|
}catch (Exception e){
|
log.error("添加附件失败,from:"+messageVo.getFrom()+",to:"+messageVo.getRecipient()+",subject:"+messageVo.getSubjectCopy()+",fileName:"+fileName+",fileKey:"+fileKey);
|
log.error("添加附件失败:",e);
|
}
|
});
|
}
|
// Add the parent container to the message
|
message.setContent(msg);
|
message.saveChanges();
|
}
|
private String username = "";
|
private String password = "";
|
private void getInit(){
|
if(StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
|
JSONObject object = secretsManagerUtils.getSecret(env.getProperty("aws.secrets.mailauth"));
|
username = object.getString("mail_username");
|
password = object.getString("mail_password");
|
}
|
}
|
}
|