package com.pollex.pam.service; import com.fasterxml.jackson.databind.ObjectMapper; import com.pollex.pam.config.ApplicationProperties; import com.pollex.pam.config.ApplicationProperties.SMS; import com.pollex.pam.domain.Appointment; import com.pollex.pam.repository.ConsultantRepository; import com.pollex.pam.service.dto.*; import com.pollex.pam.service.util.HttpRequestUtil; import com.pollex.pam.web.rest.errors.SendEmailFailException; import com.pollex.pam.web.rest.errors.SendSMSFailException; import io.jsonwebtoken.lang.Assert; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import org.thymeleaf.context.Context; import org.thymeleaf.spring5.SpringTemplateEngine; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Base64; import java.util.Base64.Encoder; import java.util.Collections; import java.util.List; import java.util.UUID; @Service public class SendMsgService { private static final Logger log = LoggerFactory.getLogger(SendMsgService.class); private final Encoder encoder = Base64.getEncoder(); private static final String EMAIL_SUBJECT = "保誠媒合平台系統通知:新預約單"; @Autowired ApplicationProperties applicationProperties; @Autowired ConsultantRepository consultantRepository; @Autowired SpringTemplateEngine springTemplateEngine; public void sendAppointmentNotify(Appointment appointment) { Assert.notNull(appointment); log.debug("is need sending notify msg = {}", applicationProperties.isSendNotifyMsg()); if(applicationProperties.isSendNotifyMsg()) { log.debug("sending appointment notify, appointmentId = {}", appointment.getId()); sendAppointmentNotifyBySMS(appointment); sendAppointmentNotifyByEmail(appointment); // todo 需確認保誠是否有需求使用html mail // sendAppointmentNotifyByHtmlEmail(appointment); } } private void sendAppointmentNotifyBySMS(Appointment appointment) throws SendSMSFailException { String msg = getAppointmentNotifyWording(appointment); String consultantMobile = consultantRepository.findOneByAgentNo(appointment.getAgentNo()).get().getPhoneNumber(); try { sendMsgBySMS(consultantMobile, msg); } catch (SendSMSFailException e) { log.debug("send sms failed, appointment Id = {}", appointment.getId(), e); } } private void sendAppointmentNotifyByEmail(Appointment appointment) { // todo 需得知保誠系統寄件信箱 (並改於設定檔中) String senderEmail = applicationProperties.getEmail().getSenderEmail(); String consultantEmail = consultantRepository.findOneByAgentNo(appointment.getAgentNo()).get().getEmail(); String content = getAppointmentNotifyWording(appointment); try { sendMsgByEmail(senderEmail, consultantEmail, EMAIL_SUBJECT, content, false); } catch (SendEmailFailException e) { log.debug("send email failed, appointment Id = {}", appointment.getId(), e); } } private void sendAppointmentNotifyByHtmlEmail(Appointment appointment) { // todo 需得知保誠系統寄件信箱 (並改於設定檔中) String senderEmail = applicationProperties.getEmail().getSenderEmail(); String consultantEmail = consultantRepository.findOneByAgentNo(appointment.getAgentNo()).get().getEmail(); String customerMobile = appointment.getPhone(); String normalContent; if(StringUtils.hasText(customerMobile)) { normalContent = "親愛的顧問您好,您有一筆來自保誠媒合平台的新預約單,該客戶手機號碼為" + customerMobile + "\n"; } else { normalContent = "親愛的顧問您好,您有一筆來自保誠媒合平台的新預約單\n"; } Context context = new Context(); context.setVariable("content", normalContent); context.setVariable("urlHint", getAppointmentDetailUrl(appointment.getId())); String content = springTemplateEngine.process("mail/appointmentNotifyEmail", context); try { sendMsgByEmail(senderEmail, consultantEmail, EMAIL_SUBJECT, content, true); } catch (SendEmailFailException e) { log.debug("send email failed, appointment Id = {}", appointment.getId(), e); } } private String getAppointmentNotifyWording(Appointment appointment) { String normalContent; if(StringUtils.hasText(appointment.getPhone())) { normalContent = "親愛的顧問您好,您有一筆來自保誠媒合平台的新預約單,該客戶手機號碼為" + appointment.getPhone() + "\n"; } else { normalContent = "親愛的顧問您好,您有一筆來自保誠媒合平台的新預約單\n"; } String urlContent = "點擊網址:" + getAppointmentDetailUrl(appointment.getId()) + " 開啟媒合平台查看。"; return normalContent + urlContent; } public SendSMSResponse sendMsgBySMS(String toMobile, String content) throws SendSMSFailException { SMS smsProperties = applicationProperties.getSms(); SendSMSRequest sendSMSRequest = new SendSMSRequest(); sendSMSRequest.setpKey(UUID.randomUUID().toString()); sendSMSRequest.setSourceCode(smsProperties.getSourceCode()); sendSMSRequest.setSender(smsProperties.getSender()); sendSMSRequest.setMsgTypeSet(smsProperties.getSmsType()); sendSMSRequest.setSendTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:00"))); sendSMSRequest.setSubject(""); sendSMSRequest.setActivityId(""); SMSDetail smsDetail = new SMSDetail(); smsDetail.setMobile(toMobile); smsDetail.setContent(encoder.encodeToString(content.getBytes(StandardCharsets.UTF_8))); sendSMSRequest.setDetail(Collections.singletonList(smsDetail)); try { ResponseEntity responseEntity = HttpRequestUtil.postWithJson(smsProperties.getUrl(), sendSMSRequest, SendSMSResponse.class); log.debug("response status code = {}", responseEntity.getStatusCode()); log.debug("smsResponse = {}", responseEntity.getBody()); return responseEntity.getBody(); // todo 可能需要再補上後續錯誤處理,但要先測通 } catch (Exception e) { log.debug("send sms failed!", e); throw new SendSMSFailException(); } } public String sendMsgByHtmlTestTemplateEmail(String from, String to) { Context context = new Context(); context.setVariable("content", "親愛的顧問您好,您有一筆來自保誠媒合平台的新預約單\n"); context.setVariable("urlHint", getAppointmentDetailUrl(0L)); String content = springTemplateEngine.process("mail/appointmentNotifyEmail", context); return sendMsgByEmail(from, to, EMAIL_SUBJECT, content, true); } public String sendMsgByEmail(String from, String to, String subject, String content, boolean htmlFormat) throws SendEmailFailException{ return sendMsgByEmail(from, to, subject, content, htmlFormat, Collections.emptyList(), Collections.emptyList()); } public String sendMsgByEmail( String fromAddress, String toAddress, String subject, String content, boolean htmlFormat, List toCCAddress, List attachments) throws SendEmailFailException { SendMailRequest sendMailRequest = new SendMailRequest(); sendMailRequest.setSendMailAddresses(Collections.singletonList(toAddress)); sendMailRequest.setFrom(fromAddress); sendMailRequest.setContent(content); sendMailRequest.setSubject(subject); sendMailRequest.setSendCCMailAddresses(toCCAddress); sendMailRequest.setAttachments(attachments); sendMailRequest.setHtmlFormat(htmlFormat); sendMailRequest.setFunctionId(applicationProperties.getEmail().getFunctionId()); return sendMsgByEmail(sendMailRequest); } private String sendMsgByEmail(SendMailRequest sendMailRequest) throws SendEmailFailException{ try { ResponseEntity responseEntity = HttpRequestUtil.postWithJson( applicationProperties.getEmail().getUrl(), sendMailRequest, String.class); log.debug("responseEntity = {}", responseEntity); SendMailResponse sendMailResponse = new ObjectMapper().readValue(responseEntity.getBody(), SendMailResponse.class); log.debug("sendMailResponse = {}", sendMailResponse); // if(sendMailResponse == null || sendMailResponse.getData() == null || "ADDED".equalsIgnoreCase(sendMailResponse.getData().getMessageStatus())) { // throw new SendEmailFailException(); // } return responseEntity.getBody(); } catch (SendEmailFailException e) { throw e; } catch (Exception e) { log.debug("send email failed!", e); throw new SendEmailFailException(); } } private String getAppointmentDetailUrl(Long appointmentId) { return applicationProperties.getFrontEndDomain() + "/myAppointmentList/contactedList?appointmentId=" + appointmentId; } }