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 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 handleEmail(Message msg, String recordId, String type, boolean isSend, Map fileMap) throws MessagingException { log.info("------------- save email -------------"); try { //保存邮件 MailMerge mailMerge = saveMailMerge(msg, recordId, type, isSend); //接收到的邮件->保存附件到s3 if (!isSend) { //解析到邮件中的附件,key为附件,value为filename Map 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 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 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 mailAddressMap = getMailAddressMap(msg, type); Set addressSet = mailAddressMap.keySet(); for (String address:addressSet) { mailaddr.append(address).append(";"); } return mailaddr.toString(); } /** * 获得邮件的收件人,抄送,和密送的地址,根据所传递的参数的不同 "to"----收件人 "cc"---抄送人地址 "bcc"---密送人地址 * * @return key:邮件地址,value:发送人名称 */ public Map getMailAddressMap(Message msg,String type) throws Exception { HashMap 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 toAddress,Map ccAddresses,Map 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 key:mailMergeId/fileAddressId,value:salesforce保存后返回的id,如果有多个附件,id用","分隔 */ public Map postMailToSF(MailMerge mailMerge,Map fileMap){ HashMap 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 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 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 desensitiveAllMemberMap = parseStringToDesensitive(mailMerge.getAllMember(),DesensitiveType.EMAIL); sfMessageVo.setALL_MEMBER__c(desensitiveAllMemberMap.get("desensitive")); sfMessageVo.setALL_MEMBER_Encrypted__c(desensitiveAllMemberMap.get("encrypt")); Map desensitiveCcMap = parseStringToDesensitive(mailMerge.getCc(),DesensitiveType.EMAIL); sfMessageVo.setCC__c(desensitiveCcMap.get("desensitive")); sfMessageVo.setCC_Encrypted__c(desensitiveCcMap.get("encrypt")); Map desensitiveBccMap = parseStringToDesensitive(mailMerge.getBcc(),DesensitiveType.EMAIL); sfMessageVo.setBCC__c(desensitiveBccMap.get("desensitive")); sfMessageVo.setBCC_Encrypted__c(desensitiveBccMap.get("encrypt")); Map 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 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 desensitiveBccNameMap = parseStringToDesensitive(mailMerge.getBccName(),DesensitiveType.CHINESE_NAME); sfMessageVo.setBccName__c(desensitiveBccNameMap.get("desensitive")); sfMessageVo.setBccName_Encrypted__c(desensitiveBccNameMap.get("encrypt")); Map desensitiveCcNameMap = parseStringToDesensitive(mailMerge.getCcName(),DesensitiveType.CHINESE_NAME); sfMessageVo.setCcName__c(desensitiveCcNameMap.get("desensitive")); sfMessageVo.setCcName_Encrypted__c(desensitiveCcNameMap.get("encrypt")); Map 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 fileMapToSFFileAddressVo(Map fileMap){ ArrayList 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 parseStringToDesensitive(String s,DesensitiveType desensitiveType){ HashMap 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 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"); } } }