问题描述
我想每天使用Spring Boot发送电子邮件,用户指定发送时间,我使用quartz来安排我的工作。 电子邮件的收件人有(id,emailAddress,deadline) 电子邮件将发送给具有deadline = Today + X..(用户指定X)的人。 例如:用户指定 X 是数字 1,所以我们对明天有截止日期的人感兴趣。
第 1 天:该应用向截止日期为今天 +1 的人发送电子邮件。 第 2 天:我希望应用程序在第 2 天将电子邮件发送给新的收件人,但使用下面的代码,将电子邮件发送给在第 1 天收到的人,这不是我需要的。
@PostMapping("/scheduleEmailPeriodic")
public ResponseEntity<ScheduleEmailResponse> SendScheduleEmailPeriodic(
@Valid @RequestBody PeriodicNotification scheduleEmailRequest) throws Exception {
ens.schedulePeriodicNotification(scheduleEmailRequest);
LocalDate localDateTime = LocalDate.Now();
LocalTime localTime = LocalTime.parse(scheduleEmailRequest.getSendingTime());
try {
zoneddatetime dateTime = zoneddatetime.of(localDateTime,localTime,ZoneId.of("Africa/Casablanca"));
if (dateTime.isBefore(zoneddatetime.Now())) {
ScheduleEmailResponse scheduleEmailResponse = new ScheduleEmailResponse(false,"dateTime must be after current time");
return ResponseEntity.badRequest().body(scheduleEmailResponse);
}
JobDetail jobDetail = buildPeriodicJobDetail(scheduleEmailRequest);
Trigger trigger = buildJobTriggerPeriodic(jobDetail,dateTime);
scheduler.scheduleJob(jobDetail,trigger);
ScheduleEmailResponse scheduleEmailResponse = new ScheduleEmailResponse(true,jobDetail.getKey().getName(),jobDetail.getKey().getGroup(),"Email Scheduled Successfully!");
return ResponseEntity.ok(scheduleEmailResponse);
} catch (SchedulerException ex) {
logger.error("Error scheduling email",ex);
ScheduleEmailResponse scheduleEmailResponse = new ScheduleEmailResponse(false,"Error scheduling email. Please try later!");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(scheduleEmailResponse);
}
}
private JobDetail buildPeriodicJobDetail(PeriodicNotification scheduleEmailRequest) {
JobDataMap jobDataMap = new JobDataMap();
List<String> recipients = fileRepo.findWantedEmails(scheduleEmailRequest.getDaysNum());
if(recipients.isEmpty()) {
throw new RuntimeException("Aucun destinataire trouvé");
}
String[] to = recipients.stream().toArray(String[]::new);
jobDataMap.put("recipients",to);
jobDataMap.put("subject",scheduleEmailRequest.getSubject());
jobDataMap.put("body",scheduleEmailRequest.getMessage());
return JobBuilder.newJob(EmailJob.class).withIdentity(UUID.randomUUID().toString(),"email-jobs")
.withDescription("Send Email Job").usingJobData(jobDataMap).storeDurably().build();
}
private Trigger buildJobTriggerPeriodic(JobDetail jobDetail,zoneddatetime startAt) {
return TriggerBuilder.newTrigger().forJob(jobDetail)
.withIdentity(jobDetail.getKey().getName(),"email-triggers")
.withDescription("Send Periodic Email Trigger")
.withSchedule(SimpleScheduleBuilder
.repeatHourlyForever(24))
.startAt(Date.from(startAt.toInstant()))
.build();
}
这是电子邮件作业:
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
logger.info("Executing Job with key {}",context.getJobDetail().getKey());
JobDataMap jobDataMap = context.getMergedJobDataMap();
String subject = jobDataMap.getString("subject");
String body = jobDataMap.getString("body");
String[] recipients = (String[])jobDataMap.get("recipients");
sendMail("smsender4@gmail.com",recipients,subject,body);
}
private void sendMail(String fromEmail,String[] toEmail,String subject,String body) {
try {
logger.info("Sending Email to {}",Arrays.toString(toEmail));
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper messageHelper = new MimeMessageHelper(message,StandardCharsets.UTF_8.toString());
messageHelper.setSubject(subject);
messageHelper.setText(body,true);
messageHelper.setFrom(fromEmail);
messageHelper.setTo(toEmail);
mailSender.send(message);
} catch (MessagingException ex) {
logger.error("Failed to send email to {}",Arrays.toString(toEmail));
}
}
}
我真的需要帮助,我需要每天都有新的收件人,而不是将电子邮件发送给相同的收件人。
解决方法
您是根据日期发送电子邮件 - 但您不会跟踪为特定用户发送电子邮件的时间。因此,如果您今天向 user1 发送一封电子邮件 - 那么 user1 在第二天仍将处于该状态。您需要添加一个标志(或其他一些逻辑),说明已经为该用户发送了电子邮件