Skip to content

Commit

Permalink
Add command to provide birthdays of active members for a given month
Browse files Browse the repository at this point in the history
  • Loading branch information
SoAJeff committed Jun 8, 2022
1 parent e136572 commit f3604d3
Show file tree
Hide file tree
Showing 7 changed files with 319 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package com.soa.rs.discordbot.v3.commands;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Month;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.soa.rs.discordbot.v3.api.annotation.Interaction;
import com.soa.rs.discordbot.v3.api.command.AbstractCommand;
import com.soa.rs.discordbot.v3.ipb.member.ForumRank;
import com.soa.rs.discordbot.v3.ipb.member.Member;
import com.soa.rs.discordbot.v3.ipb.member.MemberFetcher;
import com.soa.rs.discordbot.v3.ipb.member.MemberResults;
import com.soa.rs.discordbot.v3.util.SoaLogging;

import discord4j.core.event.domain.interaction.ChatInputInteractionEvent;
import discord4j.core.event.domain.interaction.ModalSubmitInteractionEvent;
import discord4j.core.event.domain.message.MessageCreateEvent;
import discord4j.core.object.command.ApplicationCommandInteractionOption;
import discord4j.core.object.command.ApplicationCommandInteractionOptionValue;
import reactor.core.publisher.Mono;

@Interaction(trigger = "birthdays")
public class BirthdayInteraction extends AbstractCommand {

@Override
public void initialize() {
setEnabled(true);
}

@Override
public Mono<Void> execute(MessageCreateEvent event) {
return null;
}

@Override
public Mono<Void> execute(ChatInputInteractionEvent event) {
String month = event.getOption("month").flatMap(ApplicationCommandInteractionOption::getValue)
.map(ApplicationCommandInteractionOptionValue::asString).get();

return event.deferReply().withEphemeral(true).then(Mono.fromCallable(() -> performForumLookup(month))
.flatMap(s -> event.createFollowup(s).withEphemeral(true))).onErrorResume(throwable -> {
SoaLogging.getLogger(this).error("Error when getting birthdays", throwable);
return event.createFollowup("Error when looking up birthdays, you may have spelled the month wrong.")
.withEphemeral(true).then(Mono.empty());
}).then();
}

private String performForumLookup(String month) {
int[] groups = { ForumRank.ELDAR.getId(), ForumRank.LIAN.getId(), ForumRank.ADMINISTRATOR.getId(),
ForumRank.ARQUENDI.getId(), ForumRank.ADELE.getId(), ForumRank.VORONWE.getId(),
ForumRank.ELENDUR.getId(), ForumRank.SADRON.getId(), ForumRank.ATHEM.getId(), ForumRank.MYRTH.getId(),
ForumRank.TYLAR.getId() };

List<MemberBirthdate> members = new ArrayList<>();
MemberFetcher fetcher = new MemberFetcher();
int monthInt = Month.valueOf(month.toUpperCase()).getValue();

MemberResults results = fetcher.fetchMembers(1, groups);
int pages = results.getTotalPages();
reviewResults(members, monthInt, results);
for (int i = 2; i <= pages; i++) {
results = fetcher.fetchMembers(i, groups);
reviewResults(members, monthInt, results);
}

SoaLogging.getLogger(this).debug("Total number of members with birthdays this month: " + members.size());

Collections.sort(members);

StringBuilder sb = new StringBuilder();
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd");
SimpleDateFormat finaldate = new SimpleDateFormat("MMMM dd");
sb.append("The following forum members have birthdays during the month of " + month);
sb.append("\n");
for (MemberBirthdate d : members) {
try {
sb.append(d.getName() + ": " + finaldate.format(sdf.parse(d.getDate())) + "\n");
} catch (ParseException ignored) {
}
}

return sb.toString().trim();
}

private void reviewResults(List<MemberBirthdate> members, int monthInt, MemberResults results) {
for (Member member : results.getResults()) {
if (member.getBirthday() != null && !member.getBirthday().isEmpty()) {
SoaLogging.getLogger(this)
.trace("Member: " + member.getName() + " And Birthday " + member.getBirthday());
String[] d = member.getBirthday().split("/");
if (Integer.parseInt(d[0]) == monthInt) {
MemberBirthdate memb = new MemberBirthdate(member.getName(), member.getBirthday());
members.add(memb);
}
}
}
}

@Override
public Mono<Void> execute(ModalSubmitInteractionEvent event) {
return null;
}

private static class MemberBirthdate implements Comparable<MemberBirthdate> {
private final String name;
private String date;

public MemberBirthdate(String name, String date) {
this.name = name;
this.date = date;
}

public String getName() {
return name;
}

public String getDate() {
return date;
}

public void setDate(String date) {
this.date = date;
}

public Integer getMonthNumb(MemberBirthdate memberBirthdate) {
String[] d = memberBirthdate.getDate().split("/");
if (d.length == 3) {
memberBirthdate.setDate(d[0] + "/" + d[1]);
}
return Integer.parseInt(d[1]);
}

@Override
public int compareTo(MemberBirthdate o) {
return getMonthNumb(this).compareTo(getMonthNumb(o));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.soa.rs.discordbot.v3.ipb.member;

public enum ForumRank {
ONTARI(22, "Ontari"),
ELDAR(4, "Eldar"),
LIAN(7, "Lian"),
ADMINISTRATOR(34, "Administrator"),
ARQUENDI(6, "Arquendi"),
ADELE(31, "Adele"),
VORONWE(44, "Voronwë"),
ELENDUR(37, "Elendur"),
SADRON(24, "Sadron"),
ATHEM(8, "Athem"),
MYRTH(9, "Myrth"),
BAEL(15, "Bael"),
TYLAR(10, "Tylar"),
APPLICANT(36, "Applicant"),
REGISTERED(3, "Registered User");

private final int id;
private final String name;
ForumRank(int id, String name) {
this.id = id;
this.name = name;
}

public int getId() {
return id;
}

public String getName() {
return name;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.soa.rs.discordbot.v3.ipb.member;

public class Group {

private int id;
private String name;
private String formattedName;

public int getId() {
return id;
}

public String getName() {
return name;
}

public String getFormattedName() {
return formattedName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.soa.rs.discordbot.v3.ipb.member;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Member {
private int id;
private String name;
private Group primaryGroup;
private String birthday;

public int getId() {
return id;
}

public String getName() {
return name;
}

public Group getPrimaryGroup() {
return primaryGroup;
}

public String getBirthday() {
return birthday;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.soa.rs.discordbot.v3.ipb.member;

import com.soa.rs.discordbot.v3.cfg.DiscordCfgFactory;
import com.soa.rs.discordbot.v3.util.SoaLogging;

import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJsonProvider;

import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.MediaType;

public class MemberFetcher {

public MemberResults fetchMembers(int page, int[] groups) {
Client client = ClientBuilder.newClient();
HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic(
DiscordCfgFactory.getConfig().getEventListingEvent().getApiKey(), "");
client.register(feature);
client.register(JacksonJsonProvider.class);
StringBuilder sb = new StringBuilder();
sb.append("https://forums.soa-rs.com/api/core/members?");
for (int g : groups) {
sb.append("group[]=" + g + "&");
}
sb.append("page=" + page);
sb.append("&perPage=50");
String URL = sb.toString();
SoaLogging.getLogger(this).debug("Sending forums query with URL " + URL);
WebTarget target = client.target(URL);
return target.request(MediaType.APPLICATION_JSON_TYPE).get(MemberResults.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.soa.rs.discordbot.v3.ipb.member;

import java.util.List;

public class MemberResults {
private int page;
private int perPage;
private int totalResults;
private int totalPages;
private List<Member> results;

public int getPage() {
return page;
}

public int getPerPage() {
return perPage;
}

public int getTotalResults() {
return totalResults;
}

public int getTotalPages() {
return totalPages;
}

public List<Member> getResults() {
return results;
}

public void setPage(int page) {
this.page = page;
}

public void setPerPage(int perPage) {
this.perPage = perPage;
}

public void setTotalResults(int totalResults) {
this.totalResults = totalResults;
}

public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}

public void setResults(List<Member> results) {
this.results = results;
}
}
12 changes: 12 additions & 0 deletions soa-discord/src/main/resources/commands/birthdays.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "birthdays",
"description": "Get a list of SoA forum members with birthdays during the provided month",
"options": [
{
"name": "month",
"description": "Month to search (as word)",
"type": 3,
"required": true
}
]
}

0 comments on commit f3604d3

Please sign in to comment.