EmailEngineUtil.java 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. package com.fjhx.utils;
  2. import cn.hutool.core.bean.BeanUtil;
  3. import cn.hutool.core.lang.Assert;
  4. import cn.hutool.http.HttpUtil;
  5. import com.alibaba.fastjson.JSON;
  6. import com.alibaba.fastjson.JSONObject;
  7. import com.fjhx.config.exception.EmailEngineException;
  8. import com.fjhx.vo.*;
  9. import com.sun.istack.internal.NotNull;
  10. import lombok.extern.slf4j.Slf4j;
  11. import org.springframework.beans.factory.annotation.Value;
  12. import org.springframework.http.HttpStatus;
  13. import org.springframework.http.client.ClientHttpResponse;
  14. import org.springframework.stereotype.Component;
  15. import org.springframework.web.client.ResponseErrorHandler;
  16. import org.springframework.web.client.RestTemplate;
  17. import java.io.*;
  18. import java.util.HashMap;
  19. import java.util.Map;
  20. @Slf4j
  21. @Component
  22. public class EmailEngineUtil {
  23. public static String urlPrefix;
  24. public static String attachmentPath;
  25. private static final RestTemplate restTemplate = new RestTemplate();
  26. static {
  27. restTemplate.setErrorHandler(new ResponseErrorHandler() {
  28. @Override
  29. public boolean hasError(@NotNull ClientHttpResponse response) throws IOException {
  30. HttpStatus.Series series = response.getStatusCode().series();
  31. return !HttpStatus.Series.SUCCESSFUL.equals(series);
  32. }
  33. @Override
  34. public void handleError(@NotNull ClientHttpResponse response) throws IOException {
  35. InputStream body = response.getBody();
  36. byte[] bytes = new byte[body.available()];
  37. body.read(bytes);
  38. String result = new String(bytes);
  39. HttpStatus.Series series = response.getStatusCode().series();
  40. if (HttpStatus.Series.CLIENT_ERROR.equals(series)) {
  41. throw new RuntimeException(result);
  42. }
  43. throw new EmailEngineException(result);
  44. }
  45. });
  46. }
  47. @Value("${config.urlPrefix}")
  48. public void setUrlPrefix(String urlPrefix) {
  49. EmailEngineUtil.urlPrefix = urlPrefix;
  50. }
  51. @Value("${config.attachmentPath}")
  52. public void setAttachmentPath(String attachmentPath) {
  53. EmailEngineUtil.attachmentPath = attachmentPath;
  54. }
  55. /**
  56. * 生成邮箱
  57. */
  58. public static void createAccount(BindingVo bindingVo) {
  59. // 验证邮件配置参数
  60. VerifyVo verifyVo = createVerifyVo(bindingVo);
  61. // 验证邮件配置是否正确
  62. VerifyResult verifyResult = post("v1/verifyAccount", verifyVo, VerifyResult.class);
  63. // 解析验证结果
  64. parsingVerifyResult(verifyResult);
  65. // 生成添加账号入参
  66. AddAccountVo addAccountVo = createAddAccountVo(verifyVo, bindingVo.getEmail(), bindingVo.getPath());
  67. // 添加邮箱
  68. AddAccountResult addAccountResult = post("v1/account", addAccountVo, AddAccountResult.class);
  69. // 验证邮箱添加状态
  70. parsingAddAccountResult(addAccountResult);
  71. }
  72. /**
  73. * 删除邮箱
  74. */
  75. public static void deleteAccount(String email) {
  76. delete("v1/account/" + email, new HashMap<>());
  77. }
  78. /**
  79. * 查看文件夹的所有邮件
  80. */
  81. public static MessageVo getMessageList(String email, String path, int page, int size) {
  82. String url = "/v1/account/" + email + "/messages?path=" + path + "&page=" + page + "&pageSize=" + size + "&documentStore=true";
  83. return get(url, MessageVo.class);
  84. }
  85. /**
  86. * 获取邮件明细
  87. */
  88. public static MessageDetailVo getMessageDetail(String email, String messageId) {
  89. String url = "v1/account/" + email + "/message/" + messageId + "?textType=html&embedAttachedImages=true&documentStore=false";
  90. return get(url, MessageDetailVo.class);
  91. }
  92. /**
  93. * 下载附件
  94. */
  95. public static boolean downloadAttachment(String email, String attachmentId, String fileName) {
  96. try {
  97. File file = new File(attachmentPath + email);
  98. if (!file.exists()) {
  99. boolean mkdir = file.mkdir();
  100. Assert.isTrue(mkdir, "创建文件夹失败");
  101. return false;
  102. }
  103. FileOutputStream fileOutputStream = new FileOutputStream(attachmentPath + fileName);
  104. download("v1/account/" + email + "/attachment/" + attachmentId, fileOutputStream);
  105. return true;
  106. } catch (Exception e) {
  107. throw new EmailEngineException("下载附件失败");
  108. }
  109. }
  110. public static void submit(SubmitVo submitVo) {
  111. String address = submitVo.getFrom().getAddress();
  112. JSONObject submitJson = JSON.parseObject(JSON.toJSONString(submitVo));
  113. post("v1/account/" + address + "/submit", submitJson, String.class);
  114. }
  115. /**
  116. * 生成验证邮箱配置实体
  117. */
  118. private static VerifyVo createVerifyVo(BindingVo bindingVo) {
  119. VerifyVo verifyVo = new VerifyVo();
  120. VerifyVo.Auth auth = new VerifyVo.Auth();
  121. auth.setUser(bindingVo.getEmail());
  122. auth.setPass(bindingVo.getSecretKey());
  123. VerifyVo.Tls tls = new VerifyVo.Tls();
  124. tls.setRejectUnauthorized(true);
  125. tls.setMinVersion("TLSv1.2");
  126. VerifyVo.Imap imap = new VerifyVo.Imap();
  127. imap.setAuth(auth);
  128. imap.setPort(bindingVo.getImapPort());
  129. imap.setHost(bindingVo.getImapHost());
  130. imap.setTls(tls);
  131. imap.setSecure(true);
  132. verifyVo.setImap(imap);
  133. VerifyVo.Smtp smtp = new VerifyVo.Smtp();
  134. smtp.setAuth(auth);
  135. smtp.setPort(bindingVo.getSmtpPort());
  136. smtp.setHost(bindingVo.getSmtpHost());
  137. smtp.setTls(tls);
  138. smtp.setSecure(true);
  139. verifyVo.setSmtp(smtp);
  140. return verifyVo;
  141. }
  142. /**
  143. * 解析验证结果
  144. */
  145. private static void parsingVerifyResult(VerifyResult verifyResult) {
  146. VerifyResult.Status imap = verifyResult.getImap();
  147. VerifyResult.Status smtp = verifyResult.getSmtp();
  148. Assert.notNull(imap, "imap解析结果为空");
  149. Assert.notNull(smtp, "smtp解析结果为空");
  150. Assert.isTrue(imap.getSuccess(), "imap解析失败:error:{} ;code:{};", imap.getError(), imap.getCode());
  151. Assert.isTrue(smtp.getSuccess(), "smtp解析失败:error:{} ;code:{};", smtp.getError(), smtp.getCode());
  152. }
  153. /**
  154. * 生成添加账号入参
  155. */
  156. private static AddAccountVo createAddAccountVo(VerifyVo verifyVo, String email, String path) {
  157. AddAccountVo addAccountVo = BeanUtil.copyProperties(verifyVo, AddAccountVo.class);
  158. addAccountVo.setAccount(email);
  159. addAccountVo.setName(email);
  160. addAccountVo.setEmail(email);
  161. addAccountVo.setPath(path);
  162. return addAccountVo;
  163. }
  164. /**
  165. * 验证添加状态
  166. */
  167. private static void parsingAddAccountResult(AddAccountResult addAccountResult) {
  168. String state = addAccountResult.getState();
  169. Assert.isTrue("new".equals(state) || "existing".equals(state),
  170. "邮箱添加失败,account:{},state:{}",
  171. addAccountResult.getAccount(),
  172. addAccountResult.getState());
  173. }
  174. private static void download(String url, OutputStream outputStream) {
  175. HttpUtil.download(urlPrefix + url, outputStream, true);
  176. }
  177. public static <T> T get(String url, Class<T> cls) {
  178. return RetryUtil.execute(() -> restTemplate.getForObject(urlPrefix + url, cls), 5, 5000L);
  179. }
  180. public static <T> T post(String url, Object paramObj, Class<T> cls) {
  181. return RetryUtil.execute(() -> restTemplate.postForObject(urlPrefix + url, paramObj, cls), 5, 3000L);
  182. }
  183. public static void delete(String url, Map<String, Object> map) {
  184. RetryUtil.execute(() -> {
  185. restTemplate.delete(urlPrefix + url, map);
  186. return null;
  187. }, 5, 3000L);
  188. }
  189. }