sxcybot

Discord bot for OSRS based channels
git clone git://git.wimdupont.com/sxcybot.git
Log | Files | Refs | README | LICENSE

commit 57de9eca96751f356782ecf133641e30fffb134c
parent 167e8215738762c7f9a919d1a664c2cb1e840a91
Author: Wim Dupont <wim@wimdupont.com>
Date:   Mon, 19 Feb 2024 18:28:08 +0100

added monitor by email

Diffstat:
Mpom.xml | 6++++++
Msrc/main/java/com/wimdupont/sxcybot/SxcyBotApplication.java | 4++--
Asrc/main/java/com/wimdupont/sxcybot/config/MailConfig.java | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/main/java/com/wimdupont/sxcybot/services/MailService.java | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/main/java/com/wimdupont/sxcybot/services/OsrsMonitoringService.java | 16++++++++++++----
Msrc/main/resources/application.properties | 9+++++++++
6 files changed, 177 insertions(+), 6 deletions(-)

diff --git a/pom.xml b/pom.xml @@ -18,6 +18,7 @@ <java.version>21</java.version> <jda-utilities-commons.version>3.0.5</jda-utilities-commons.version> <dv8ation.jda.version>4.4.0_350</dv8ation.jda.version> + <jakarta.mail.version>2.0.1</jakarta.mail.version> </properties> <dependencies> @@ -39,6 +40,11 @@ <artifactId>mariadb-java-client</artifactId> </dependency> <dependency> + <groupId>com.sun.mail</groupId> + <artifactId>jakarta.mail</artifactId> + <version>${jakarta.mail.version}</version> + </dependency> + <dependency> <groupId>com.jagrosh</groupId> <artifactId>jda-utilities-commons</artifactId> <version>${jda-utilities-commons.version}</version> diff --git a/src/main/java/com/wimdupont/sxcybot/SxcyBotApplication.java b/src/main/java/com/wimdupont/sxcybot/SxcyBotApplication.java @@ -20,7 +20,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.ComponentScan; +import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; import javax.security.auth.login.LoginException; @@ -28,7 +28,7 @@ import java.util.Arrays; @SpringBootApplication @EnableScheduling -@ComponentScan +@EnableAsync public class SxcyBotApplication implements CommandLineRunner { private static final Logger LOGGER = LoggerFactory.getLogger(SxcyBotApplication.class); diff --git a/src/main/java/com/wimdupont/sxcybot/config/MailConfig.java b/src/main/java/com/wimdupont/sxcybot/config/MailConfig.java @@ -0,0 +1,73 @@ +package com.wimdupont.sxcybot.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "mail") +public class MailConfig { + + private boolean enabled; + private String from; + private String to; + private String username; + private String password; + private String host; + private String port; + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public String getPort() { + return port; + } + + public void setPort(String port) { + this.port = port; + } +} diff --git a/src/main/java/com/wimdupont/sxcybot/services/MailService.java b/src/main/java/com/wimdupont/sxcybot/services/MailService.java @@ -0,0 +1,75 @@ +package com.wimdupont.sxcybot.services; + +import com.wimdupont.sxcybot.config.MailConfig; +import jakarta.el.PropertyNotFoundException; +import jakarta.mail.Authenticator; +import jakarta.mail.Message; +import jakarta.mail.MessagingException; +import jakarta.mail.PasswordAuthentication; +import jakarta.mail.Session; +import jakarta.mail.Transport; +import jakarta.mail.internet.InternetAddress; +import jakarta.mail.internet.MimeMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.util.Properties; + +@Service +public class MailService { + + private static final Logger LOGGER = LoggerFactory.getLogger(MailService.class); + + private final MailConfig mailConfig; + + public MailService(MailConfig mailConfig) { + this.mailConfig = mailConfig; + if (mailConfig.isEnabled() + && (mailConfig.getFrom() == null + || mailConfig.getTo() == null + || mailConfig.getUsername() == null + || mailConfig.getPassword() == null + || mailConfig.getHost() == null + || mailConfig.getPort() == null)) { + throw new PropertyNotFoundException("Mail is enabled and required properties are missing."); + } + } + + @Async + public void sendMail(String subject, String body) { + if (mailConfig.isEnabled()) { + var properties = new Properties(); + properties.put("mail.smtp.auth", "true"); + properties.put("mail.smtp.starttls.enable", "true"); + properties.put("mail.smtp.host", mailConfig.getHost()); + properties.put("mail.smtp.port", mailConfig.getPort()); + var session = Session.getInstance(properties, getAuthenticator()); + + try { + var message = new MimeMessage(session); + message.setFrom(new InternetAddress(mailConfig.getFrom())); + message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(mailConfig.getTo())); + message.setSubject(subject); + message.setText(body); + Transport.send(message); + LOGGER.info("Email sent successfully."); + } catch (MessagingException e) { + throw new RuntimeException(e); + } + } else { + LOGGER.info("Mail is disabled - no mail sent for subject {} ", subject); + } + } + + private Authenticator getAuthenticator() { + return new Authenticator() { + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication( + mailConfig.getUsername(), + mailConfig.getPassword()); + } + }; + } +} diff --git a/src/main/java/com/wimdupont/sxcybot/services/OsrsMonitoringService.java b/src/main/java/com/wimdupont/sxcybot/services/OsrsMonitoringService.java @@ -25,6 +25,7 @@ public class OsrsMonitoringService { private final Logger LOGGER = LoggerFactory.getLogger("monitor"); private final HiScoreClient hiScoreClient; private final PvmRoleUserService pvmRoleUserService; + private final MailService mailService; private final String monitorUserName; private final String monitorBossName; private final String monitorBossKc; @@ -32,12 +33,14 @@ public class OsrsMonitoringService { public OsrsMonitoringService(HiScoreClient hiScoreClient, PvmRoleUserService pvmRoleUserService, + MailService mailService, @Value("${monitor.user.name}") String monitorUserName, @Value("${monitor.boss.name}") String monitorBossName, @Value("${monitor.boss.kc}") String monitorBossKc, ChannelDetailService channelDetailService) { this.hiScoreClient = hiScoreClient; this.pvmRoleUserService = pvmRoleUserService; + this.mailService = mailService; this.monitorUserName = monitorUserName; this.monitorBossName = monitorBossName; this.monitorBossKc = monitorBossKc; @@ -84,10 +87,10 @@ public class OsrsMonitoringService { private void messageDiscordMemberResults(List<PvmRoleUser> unfound, PrivateChannel privateChannel) { if (privateChannel == null) { if (!unfound.isEmpty()) { - LOGGER.error("No Discord member found for: {}", unfound.stream() + handleError(String.format("No Discord member found for: %s", unfound.stream() .map(pvmRoleUser -> String.format("DiscordId: %s , Rsn: %s", pvmRoleUser.getDiscordId(), pvmRoleUser.getRsn())) - .toList()); + .toList())); } else { LOGGER.info("All PvM Role competitors have been found in discord."); } @@ -109,7 +112,7 @@ public class OsrsMonitoringService { private void messageHiScoreResults(List<PvmRoleUser> unfound, PrivateChannel privateChannel) { if (privateChannel == null) { if (!unfound.isEmpty()) { - LOGGER.error("No hiScores found for: {}", unfound.stream().map(PvmRoleUser::getRsn).toList()); + handleError(String.format("No hiScores found for: %s", unfound.stream().map(PvmRoleUser::getRsn).toList())); } else { LOGGER.info("All PvM Role competitors have been found in the hiscores."); } @@ -139,8 +142,13 @@ public class OsrsMonitoringService { if (wintertodtBossKc.kc().equals(monitorBossKc)) { LOGGER.info(String.format("Hiscores check is OK. (%s has %s kc on %s)", monitorUserName, monitorBossKc, monitorBossName)); } else { - LOGGER.error(String.format("Hiscores check not OK: %s kc for user %s is not %s, but is %s", + handleError(String.format("Hiscores check not OK: %s kc for user %s is not %s, but is %s", monitorBossName, monitorUserName, monitorBossKc, wintertodtBossKc.kc())); } } + + private void handleError(String message) { + mailService.sendMail("SxcyBot Monitoring", message); + LOGGER.error(message); + } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties @@ -20,3 +20,12 @@ pvm.role.schedule=0 0 1 1,15 * * #spring.flyway.password= #discord.bot.token= #server.port=8080 + +##### mail ##### +mail.enabled=false +#mail.from= +#mail.to= +#mail.username= +#mail.password= +#mail.host= +#mail.port=