[SIS-xxx] changing meetup display to use display names instead of mentions

fixing not showing organizer if no description was yet
This commit is contained in:
Sheldan
2025-12-14 21:40:34 +01:00
parent 663d88475a
commit 111a88b091
6 changed files with 220 additions and 99 deletions

View File

@@ -42,7 +42,14 @@ public class MeetupChangeTimeConfirmationListener implements ButtonClickedListen
} }
if(model.getEvent().getComponentId().equals(payload.getConfirmationId())) { if(model.getEvent().getComponentId().equals(payload.getConfirmationId())) {
Meetup meetup = meetupManagementServiceBean.getMeetup(payload.getMeetupId(), payload.getGuildId()); Meetup meetup = meetupManagementServiceBean.getMeetup(payload.getMeetupId(), payload.getGuildId());
meetupServiceBean.changeMeetupTimeAndNotifyParticipants(meetup, Instant.ofEpochSecond(payload.getNewTime())); Long meetupId = meetup.getId().getId();
Long serverId = meetup.getId().getServerId();
meetupServiceBean.changeMeetupTimeAndNotifyParticipants(meetup, Instant.ofEpochSecond(payload.getNewTime())).thenAccept(unused -> {
log.info("Successfully changed time of meetup {} in server {}.", meetupId, serverId);
}).exceptionally(throwable -> {
log.error("Failed to update time of meetup {} in server {}.", meetupId, serverId);
return null;
});
messageService.deleteMessage(model.getEvent().getMessage()); messageService.deleteMessage(model.getEvent().getMessage());
cleanupConfirmationMessagePayloads(payload); cleanupConfirmationMessagePayloads(payload);
} else if(model.getEvent().getComponentId().equals(payload.getCancelId())) { } else if(model.getEvent().getComponentId().equals(payload.getCancelId())) {

View File

@@ -103,18 +103,26 @@ public class MeetupConfirmationListener implements ButtonClickedListener {
String noButtonId = componentService.generateComponentId(); String noButtonId = componentService.generateComponentId();
String maybeButtonId = componentService.generateComponentId(); String maybeButtonId = componentService.generateComponentId();
String noTimeButtonId = componentService.generateComponentId(); String noTimeButtonId = componentService.generateComponentId();
MeetupMessageModel messageModel = meetupServiceBean.getMeetupMessageModel(meetup); Long meetupId = payload.getMeetupId();
messageModel.setYesId(yesButtonId); Long serverId = payload.getGuildId();
messageModel.setNoId(noButtonId);
messageModel.setMaybeId(maybeButtonId);
messageModel.setNoTimeId(noTimeButtonId);
meetup.setYesButtonId(yesButtonId); meetup.setYesButtonId(yesButtonId);
meetup.setMaybeButtonId(maybeButtonId); meetup.setMaybeButtonId(maybeButtonId);
meetup.setNoTimeButtonId(noTimeButtonId); meetup.setNoTimeButtonId(noTimeButtonId);
meetup.setNotInterestedButtonId(noButtonId); meetup.setNotInterestedButtonId(noButtonId);
meetupServiceBean.getMeetupMessageModel(meetup).thenAccept(messageModel -> {
self.postMeetupMessage(model, messageModel, yesButtonId, noButtonId, maybeButtonId, noTimeButtonId, meetupId, serverId);
});
return ButtonClickedListenerResult.ACKNOWLEDGED;
}
@Transactional
public void postMeetupMessage(ButtonClickedListenerModel model, MeetupMessageModel messageModel, String yesButtonId, String noButtonId,
String maybeButtonId, String noTimeButtonId, Long meetupId, Long serverId) {
messageModel.setYesId(yesButtonId);
messageModel.setNoId(noButtonId);
messageModel.setMaybeId(maybeButtonId);
messageModel.setNoTimeId(noTimeButtonId);
messageModel.setCancelled(false); messageModel.setCancelled(false);
Long meetupId = payload.getMeetupId();
Long serverId = payload.getGuildId();
MessageToSend messageToSend = meetupServiceBean.getMeetupMessage(messageModel, model.getServerId()); MessageToSend messageToSend = meetupServiceBean.getMeetupMessage(messageModel, model.getServerId());
List<CompletableFuture<Message>> messageFutures = channelService.sendMessageToSendToChannel(messageToSend, model.getEvent().getMessageChannel()); List<CompletableFuture<Message>> messageFutures = channelService.sendMessageToSendToChannel(messageToSend, model.getEvent().getMessageChannel());
FutureUtils.toSingleFutureGeneric(messageFutures).thenAccept(unused -> { FutureUtils.toSingleFutureGeneric(messageFutures).thenAccept(unused -> {
@@ -129,7 +137,6 @@ public class MeetupConfirmationListener implements ButtonClickedListener {
log.error("Failed to send meetup message for meetup {}.", meetupId, throwable); log.error("Failed to send meetup message for meetup {}.", meetupId, throwable);
return null; return null;
}); });
return ButtonClickedListenerResult.ACKNOWLEDGED;
} }
private void cleanupConfirmationMessagePayloads(MeetupConfirmationPayload payload) { private void cleanupConfirmationMessagePayloads(MeetupConfirmationPayload payload) {

View File

@@ -20,8 +20,10 @@ import dev.sheldan.sissi.module.meetup.service.MeetupServiceBean;
import dev.sheldan.sissi.module.meetup.service.management.MeetupManagementServiceBean; import dev.sheldan.sissi.module.meetup.service.management.MeetupManagementServiceBean;
import dev.sheldan.sissi.module.meetup.service.management.MeetupParticipatorManagementServiceBean; import dev.sheldan.sissi.module.meetup.service.management.MeetupParticipatorManagementServiceBean;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@@ -45,11 +47,15 @@ public class MeetupDecisionListener implements ButtonClickedListener {
@Autowired @Autowired
private ChannelService channelService; private ChannelService channelService;
@Autowired
private MeetupDecisionListener self;
@Override @Override
public ButtonClickedListenerResult execute(ButtonClickedListenerModel model) { public ButtonClickedListenerResult execute(ButtonClickedListenerModel model) {
MeetupDecisionPayload payload = (MeetupDecisionPayload) model.getDeserializedPayload(); MeetupDecisionPayload payload = (MeetupDecisionPayload) model.getDeserializedPayload();
Meetup meetup = meetupManagementServiceBean.getMeetup(payload.getMeetupId(), payload.getGuildId()); Meetup meetup = meetupManagementServiceBean.getMeetup(payload.getMeetupId(), payload.getGuildId());
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(model.getEvent().getMember()); Member member = model.getEvent().getMember();
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(member);
Optional<MeetupParticipant> participationOptional = meetupParticipatorManagementServiceBean.getParticipation(meetup, userInAServer); Optional<MeetupParticipant> participationOptional = meetupParticipatorManagementServiceBean.getParticipation(meetup, userInAServer);
if(participationOptional.isPresent()) { if(participationOptional.isPresent()) {
@@ -57,19 +63,28 @@ public class MeetupDecisionListener implements ButtonClickedListener {
} else { } else {
meetupParticipatorManagementServiceBean.createParticipation(meetup, userInAServer, payload.getMeetupDecision()); meetupParticipatorManagementServiceBean.createParticipation(meetup, userInAServer, payload.getMeetupDecision());
} }
MeetupMessageModel meetupMessageModel = meetupServiceBean.getMeetupMessageModel(meetup); Long meetupMessageId = meetup.getMessageId();
addParticipationToModel(meetupMessageModel, userInAServer, payload.getMeetupDecision()); Long meetupId = meetup.getId().getId();
MessageToSend messageToSend = meetupServiceBean.getMeetupMessage(meetupMessageModel, model.getServerId()); Long meetupServerId = meetup.getServer().getId();
channelService.editMessageInAChannelFuture(messageToSend, model.getEvent().getChannel(), meetup.getMessageId()) meetupServiceBean.getMeetupMessageModel(meetup).thenAccept(meetupMessageModel -> {
.thenAccept(message -> log.info("Updated message of meetup {} in channel {} in server {}.", meetup.getId().getId(), meetup.getMeetupChannel().getId(), meetup.getServer().getId())) self.updateMeetupMessage(model, meetupMessageModel, member, payload, meetupMessageId, meetupId, meetupServerId);
.exceptionally(throwable -> {
log.info("Failed to update message of meetup {} in channel {} in server {}.", meetup.getId().getId(), meetup.getMeetupChannel().getId(), meetup.getServer().getId(), throwable);
return null;
}); });
return ButtonClickedListenerResult.ACKNOWLEDGED; return ButtonClickedListenerResult.ACKNOWLEDGED;
} }
private void addParticipationToModel(MeetupMessageModel model, AUserInAServer aUserInAServer, MeetupDecision decision) { @Transactional
public void updateMeetupMessage(ButtonClickedListenerModel model, MeetupMessageModel meetupMessageModel, Member member, MeetupDecisionPayload payload, Long meetupMessageId, Long meetupId, Long meetupServerId) {
addParticipationToModel(meetupMessageModel, member, payload.getMeetupDecision());
MessageToSend messageToSend = meetupServiceBean.getMeetupMessage(meetupMessageModel, model.getServerId());
channelService.editMessageInAChannelFuture(messageToSend, model.getEvent().getChannel(), meetupMessageId)
.thenAccept(message -> log.info("Updated message of meetup {} in channel {} in server {}.", meetupId, meetupMessageId, meetupServerId))
.exceptionally(throwable -> {
log.info("Failed to update message of meetup {} in channel {} in server {}.", meetupId, meetupMessageId, meetupServerId, throwable);
return null;
});
}
private void addParticipationToModel(MeetupMessageModel model, Member aUserInAServer, MeetupDecision decision) {
if(decision.equals(MeetupDecision.NO)) { if(decision.equals(MeetupDecision.NO)) {
addIfMissing(model.getDeclinedParticipants(), aUserInAServer); addIfMissing(model.getDeclinedParticipants(), aUserInAServer);
} else if(decision.equals(MeetupDecision.YES)) { } else if(decision.equals(MeetupDecision.YES)) {
@@ -80,9 +95,9 @@ public class MeetupDecisionListener implements ButtonClickedListener {
addIfMissing(model.getNoTimeParticipants(), aUserInAServer); addIfMissing(model.getNoTimeParticipants(), aUserInAServer);
} }
private void addIfMissing(List<MemberDisplay> list, AUserInAServer aUserInAServer) { private void addIfMissing(List<MemberDisplay> list, Member aUserInAServer) {
if(list.stream().noneMatch(memberDisplay -> memberDisplay.getUserId().equals(aUserInAServer.getUserReference().getId()))) { if(list.stream().noneMatch(memberDisplay -> memberDisplay.getUserId().equals(aUserInAServer.getIdLong()))) {
list.add(MemberDisplay.fromAUserInAServer(aUserInAServer)); list.add(MemberDisplay.fromMember(aUserInAServer));
} }
} }

View File

@@ -10,6 +10,7 @@ import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.ServerManagementService; import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend; import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService; import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
import dev.sheldan.abstracto.core.utils.FileService; import dev.sheldan.abstracto.core.utils.FileService;
import dev.sheldan.abstracto.core.utils.FutureUtils; import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.scheduling.model.JobParameters; import dev.sheldan.abstracto.scheduling.model.JobParameters;
@@ -32,6 +33,8 @@ import dev.sheldan.sissi.module.meetup.service.management.MeetupComponentManagem
import dev.sheldan.sissi.module.meetup.service.management.MeetupManagementServiceBean; import dev.sheldan.sissi.module.meetup.service.management.MeetupManagementServiceBean;
import dev.sheldan.sissi.module.meetup.service.management.MeetupParticipatorManagementServiceBean; import dev.sheldan.sissi.module.meetup.service.management.MeetupParticipatorManagementServiceBean;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -48,6 +51,8 @@ import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Component @Component
@@ -109,8 +114,16 @@ public class MeetupServiceBean {
@Autowired @Autowired
private MeetupComponentManagementServiceBean meetupComponentManagementServiceBean; private MeetupComponentManagementServiceBean meetupComponentManagementServiceBean;
@Autowired
private MemberService memberService;
private static final String ICS_TIME_STAMP_FORMAT = "yMMdd'T'kkmmss'Z'"; private static final String ICS_TIME_STAMP_FORMAT = "yMMdd'T'kkmmss'Z'";
private static final ZoneId UTC = ZoneId.of("UTC");
private static final DateTimeFormatter ICS_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(ICS_TIME_STAMP_FORMAT); private static final DateTimeFormatter ICS_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(ICS_TIME_STAMP_FORMAT);
private static final Predicate<MeetupParticipant> MAYBE_OR_YES_PARTICIPATOR = meetupParticipator ->
meetupParticipator.getDecision().equals(MeetupDecision.MAYBE) ||
meetupParticipator.getDecision().equals(MeetupDecision.YES);
public void storeMeetupConfirmation(MeetupConfirmationModel model) { public void storeMeetupConfirmation(MeetupConfirmationModel model) {
AServer server = serverManagementService.loadServer(model.getGuildId()); AServer server = serverManagementService.loadServer(model.getGuildId());
@@ -142,11 +155,11 @@ public class MeetupServiceBean {
} }
private MeetupIcsModel getMeetupICSModel(Meetup meetup) { private MeetupIcsModel getMeetupICSModel(Meetup meetup) {
ZonedDateTime startTime = meetup.getMeetupTime().atZone(ZoneId.of("UTC")); ZonedDateTime startTime = meetup.getMeetupTime().atZone(UTC);
ZonedDateTime endTime = meetup.getMeetupTime().plus(1, ChronoUnit.HOURS).atZone(ZoneId.of("UTC")); ZonedDateTime endTime = meetup.getMeetupTime().plus(1, ChronoUnit.HOURS).atZone(UTC);
String icsFormattedStartTime = startTime.format(ICS_DATE_TIME_FORMATTER); String icsFormattedStartTime = startTime.format(ICS_DATE_TIME_FORMATTER);
String icsFormattedEndTime = endTime.format(ICS_DATE_TIME_FORMATTER); String icsFormattedEndTime = endTime.format(ICS_DATE_TIME_FORMATTER);
String icsFormattedMeetupCreationTime = Instant.now().atZone(ZoneId.of("UTC")) String icsFormattedMeetupCreationTime = Instant.now().atZone(UTC)
.format(ICS_DATE_TIME_FORMATTER); .format(ICS_DATE_TIME_FORMATTER);
boolean attachIcsFile = featureModeService.featureModeActive(MeetupFeatureDefinition.MEETUP, meetup.getServer().getId(), MeetupFeatureMode.ATTACH_ICS_FILE); boolean attachIcsFile = featureModeService.featureModeActive(MeetupFeatureDefinition.MEETUP, meetup.getServer().getId(), MeetupFeatureMode.ATTACH_ICS_FILE);
return MeetupIcsModel return MeetupIcsModel
@@ -158,26 +171,36 @@ public class MeetupServiceBean {
.build(); .build();
} }
public MeetupMessageModel getMeetupMessageModel(Meetup meetup) { public CompletableFuture<MeetupMessageModel> getMeetupMessageModel(Meetup meetup) {
List<MeetupParticipant> allParticipants = meetup.getParticipants(); List<MeetupParticipant> allParticipants = meetup.getParticipants();
List<MeetupParticipant> participating = allParticipants Long serverId = meetup.getServer().getId();
Function<MeetupParticipant, Long> mapToUserId = (p) -> p.getParticipator().getUserReference().getId();
List<Long> participating = allParticipants
.stream() .stream()
.filter(meetupParticipator -> meetupParticipator.getDecision().equals(MeetupDecision.YES)) .filter(meetupParticipator -> meetupParticipator.getDecision().equals(MeetupDecision.YES))
.collect(Collectors.toList()); .map(mapToUserId)
List<MeetupParticipant> maybe = allParticipants .toList();
List<Long> maybe = allParticipants
.stream() .stream()
.filter(meetupParticipator -> meetupParticipator.getDecision().equals(MeetupDecision.MAYBE)) .filter(meetupParticipator -> meetupParticipator.getDecision().equals(MeetupDecision.MAYBE))
.collect(Collectors.toList()); .map(mapToUserId)
List<MeetupParticipant> notParticipating = allParticipants .toList();
List<Long> notParticipating = allParticipants
.stream() .stream()
.filter(meetupParticipator -> meetupParticipator.getDecision().equals(MeetupDecision.NO)) .filter(meetupParticipator -> meetupParticipator.getDecision().equals(MeetupDecision.NO))
.collect(Collectors.toList()); .map(mapToUserId)
List<MeetupParticipant> notTimeParticipating = allParticipants .toList();
List<Long> notTimeParticipating = allParticipants
.stream() .stream()
.filter(meetupParticipator -> meetupParticipator.getDecision().equals(MeetupDecision.NO_TIME)) .filter(meetupParticipator -> meetupParticipator.getDecision().equals(MeetupDecision.NO_TIME))
.collect(Collectors.toList()); .map(mapToUserId)
.toList();
String rawLocation = java.net.URLDecoder.decode(meetup.getLocation(), StandardCharsets.UTF_8); String rawLocation = java.net.URLDecoder.decode(meetup.getLocation(), StandardCharsets.UTF_8);
return MeetupMessageModel List<Long> participantIds = allParticipants
.stream()
.map(mapToUserId)
.collect(Collectors.toList());
MeetupMessageModel.MeetupMessageModelBuilder builder = MeetupMessageModel
.builder() .builder()
.description(meetup.getDescription()) .description(meetup.getDescription())
.topic(meetup.getTopic()) .topic(meetup.getTopic())
@@ -189,20 +212,63 @@ public class MeetupServiceBean {
.noId(meetup.getNotInterestedButtonId()) .noId(meetup.getNotInterestedButtonId())
.meetupTime(meetup.getMeetupTime()) .meetupTime(meetup.getMeetupTime())
.meetupId(meetup.getId().getId()) .meetupId(meetup.getId().getId())
.participants(getMemberDisplays(participating))
.declinedParticipants(getMemberDisplays(notParticipating))
.noTimeParticipants(getMemberDisplays(notTimeParticipating))
.maybeParticipants(getMemberDisplays(maybe))
.cancelled(meetup.getState().equals(MeetupState.CANCELLED)) .cancelled(meetup.getState().equals(MeetupState.CANCELLED))
.organizer(MemberDisplay.fromAUserInAServer(meetup.getOrganizer())) .meetupIcsModel(getMeetupICSModel(meetup));
.meetupIcsModel(getMeetupICSModel(meetup)) Long organizerId = meetup.getOrganizer().getUserReference().getId();
.build(); participantIds.add(organizerId);
// only supports 100 members at once, should be enough
CompletableFuture<List<Member>> membersInServerAsync = memberService.getMembersInServerAsync(serverId, participantIds);
return membersInServerAsync.thenCompose(members -> {
Set<Long> foundMembers = members
.stream()
.map(Member::getIdLong)
.collect(Collectors.toSet());
Set<Long> participatingMembers = new HashSet<>(participantIds);
participatingMembers.removeAll(foundMembers);
CompletableFuture<List<User>> userLoading = new CompletableFuture<>();
if(!participatingMembers.isEmpty()) {
CompletableFutureList<User> userFutureList = userService.retrieveUsers(new ArrayList<>(participatingMembers));
userFutureList.getMainFuture().thenAccept(unused -> {
userLoading.complete(userFutureList.getObjects());
});
} else {
userLoading.complete(new ArrayList<>());
} }
private List<MemberDisplay> getMemberDisplays(List<MeetupParticipant> participants) { return userLoading.thenApply(users ->
builder
.participants(getMemberDisplays(members, users, participating, serverId))
.declinedParticipants(getMemberDisplays(members, users, notParticipating, serverId))
.noTimeParticipants(getMemberDisplays(members, users, notTimeParticipating, serverId))
.maybeParticipants(getMemberDisplays(members, users, maybe, serverId))
.organizer(getMemberDisplays(members, users, Arrays.asList(organizerId), serverId).get(0))
.build());
});
}
private List<MemberDisplay> getMemberDisplays(List<Member> members, List<User> users, List<Long> participants, Long serverId) {
Map<Long, Member> memberMap = members.stream()
.collect(Collectors.toMap(Member::getIdLong, Function.identity()));
Map<Long, User> userMap = users.stream()
.collect(Collectors.toMap(User::getIdLong, Function.identity()));
return participants return participants
.stream() .stream()
.map(meetupParticipator -> MemberDisplay.fromAUserInAServer(meetupParticipator.getParticipator())) .map(meetupParticipator -> {
if(memberMap.containsKey(meetupParticipator)) {
return MemberDisplay.fromMember(memberMap.get(meetupParticipator));
} else if(userMap.containsKey(meetupParticipator)) {
User user = userMap.get(meetupParticipator);
// a user display would be more appropriate, but I dont want to deal with the implications
return MemberDisplay
.builder()
.serverId(serverId)
.userId(user.getIdLong())
.name(user.getEffectiveName())
.avatarUrl(user.getEffectiveAvatarUrl())
.build();
}
return MemberDisplay.fromIds(serverId, meetupParticipator);
})
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@@ -214,32 +280,35 @@ public class MeetupServiceBean {
Long serverId = meetup.getServer().getId(); Long serverId = meetup.getServer().getId();
Long meetupId = meetup.getId().getId(); Long meetupId = meetup.getId().getId();
GuildMessageChannel channel = channelService.getMessageChannelFromServer(serverId, meetup.getMeetupChannel().getId()); GuildMessageChannel channel = channelService.getMessageChannelFromServer(serverId, meetup.getMeetupChannel().getId());
MeetupMessageModel model = getMeetupMessageModel(meetup);
List<String> componentPayloads = meetup List<String> componentPayloads = meetup
.getMeetupComponents() .getMeetupComponents()
.stream() .stream()
.map(meetupComponent -> meetupComponent.getId().getComponentId()) .map(meetupComponent -> meetupComponent.getId().getComponentId())
.collect(Collectors.toList()); .collect(Collectors.toList());
Long meetupMessageId = meetup.getMessageId();
return getMeetupMessageModel(meetup).thenCompose(model -> {
model.setCancelled(true); model.setCancelled(true);
MessageToSend meetupMessage = getMeetupMessage(model, serverId); MessageToSend meetupMessage = getMeetupMessage(model, serverId);
return messageService.editMessageInChannel(channel, meetupMessage, meetup.getMessageId()) return messageService.editMessageInChannel(channel, meetupMessage, meetupMessageId)
.thenAccept(unused -> self.notifyParticipants(meetupId, serverId)) .thenAccept(unused -> self.notifyParticipants(meetupId, serverId))
.thenAccept(unused -> self.cleanupMeetup(meetupId, serverId, componentPayloads)); .thenAccept(unused -> self.cleanupMeetup(meetupId, serverId, componentPayloads));
});
} }
@Transactional @Transactional
public void notifyParticipants(Long meetupId, Long serverId) { public void notifyParticipants(Long meetupId, Long serverId) {
Meetup meetup = meetupManagementServiceBean.getMeetup(meetupId, serverId); Meetup meetup = meetupManagementServiceBean.getMeetup(meetupId, serverId);
MeetupMessageModel model = getMeetupMessageModel(meetup); List<Long> participatorIds = getYesOrMaybeParticipants(meetup);
getMeetupMessageModel(meetup).thenAccept(model -> {
self.sendNotifications(meetupId, serverId, model, participatorIds);
});
}
@Transactional
public void sendNotifications(Long meetupId, Long serverId, MeetupMessageModel model, List<Long> participatorIds) {
MessageToSend messageToSend = templateService.renderEmbedTemplate(MEETUP_CANCELLATION_TEMPLATE, model, serverId); MessageToSend messageToSend = templateService.renderEmbedTemplate(MEETUP_CANCELLATION_TEMPLATE, model, serverId);
meetup participatorIds.forEach(userId -> {
.getParticipants()
.stream()
.filter(meetupParticipator ->
meetupParticipator.getDecision().equals(MeetupDecision.MAYBE) ||
meetupParticipator.getDecision().equals(MeetupDecision.YES))
.forEach(meetupParticipator -> {
Long userId = meetupParticipator.getParticipator().getUserReference().getId();
userService.retrieveUserForId(userId) userService.retrieveUserForId(userId)
.thenCompose(user -> messageService.sendMessageToSendToUser(user, messageToSend)) .thenCompose(user -> messageService.sendMessageToSendToUser(user, messageToSend))
.thenAccept(message -> log.info("Notified user {} about cancellation of meetup {} in server {}.", userId, meetupId, serverId)) .thenAccept(message -> log.info("Notified user {} about cancellation of meetup {} in server {}.", userId, meetupId, serverId))
@@ -318,22 +387,31 @@ public class MeetupServiceBean {
@Transactional @Transactional
public void remindParticipants(Long meetupId, Long serverId) { public void remindParticipants(Long meetupId, Long serverId) {
Meetup meetup = meetupManagementServiceBean.getMeetup(meetupId, serverId); Meetup meetup = meetupManagementServiceBean.getMeetup(meetupId, serverId);
MeetupMessageModel model = getMeetupMessageModel(meetup); List<Long> participatorIds = getYesOrMaybeParticipants(meetup);
getMeetupMessageModel(meetup).thenAccept(model -> {
self.sendMeetupReminderMessages(meetupId, serverId, model, participatorIds);
});
}
@Transactional
public void sendMeetupReminderMessages(Long meetupId, Long serverId, MeetupMessageModel model, List<Long> participatorIds) {
MessageToSend messageToSend = templateService.renderEmbedTemplate(MEETUP_REMINDER_TEMPLATE, model, serverId); MessageToSend messageToSend = templateService.renderEmbedTemplate(MEETUP_REMINDER_TEMPLATE, model, serverId);
meetup participatorIds.forEach(userId -> {
.getParticipants()
.stream()
.filter(meetupParticipator ->
meetupParticipator.getDecision().equals(MeetupDecision.MAYBE) ||
meetupParticipator.getDecision().equals(MeetupDecision.YES))
.forEach(meetupParticipator -> {
Long userId = meetupParticipator.getParticipator().getUserReference().getId();
userService.retrieveUserForId(userId) userService.retrieveUserForId(userId)
.thenCompose(user -> messageService.sendMessageToSendToUser(user, messageToSend)) .thenCompose(user -> messageService.sendMessageToSendToUser(user, messageToSend))
.thenAccept(message -> log.info("Notified user {} about incoming meetup {} in server {}.", userId, meetupId, serverId)); .thenAccept(message -> log.info("Notified user {} about incoming meetup {} in server {}.", userId, meetupId, serverId));
}); });
} }
private List<Long> getYesOrMaybeParticipants(Meetup meetup) {
return meetup
.getParticipants()
.stream()
.filter(MAYBE_OR_YES_PARTICIPATOR)
.map(meetupParticipant -> meetupParticipant.getParticipator().getUserReference().getId())
.toList();
}
@Transactional @Transactional
public void cleanupMeetups() { public void cleanupMeetups() {
Instant time = Instant.now().minus(1, ChronoUnit.DAYS); Instant time = Instant.now().minus(1, ChronoUnit.DAYS);
@@ -376,11 +454,12 @@ public class MeetupServiceBean {
Long serverId = meetup.getServer().getId(); Long serverId = meetup.getServer().getId();
Long meetupMessageId = meetup.getMessageId();
ServerChannelMessage meetupMessage = ServerChannelMessage ServerChannelMessage meetupMessage = ServerChannelMessage
.builder() .builder()
.serverId(serverId) .serverId(serverId)
.channelId(meetup.getMeetupChannel().getId()) .channelId(meetup.getMeetupChannel().getId())
.messageId(meetup.getMessageId()) .messageId(meetupMessageId)
.build(); .build();
MeetupTimeChangedNotificationModel notificationModel = MeetupTimeChangedNotificationModel MeetupTimeChangedNotificationModel notificationModel = MeetupTimeChangedNotificationModel
.builder() .builder()
@@ -418,18 +497,24 @@ public class MeetupServiceBean {
.toList(); .toList();
meetup meetup
.getParticipants().removeIf(meetupParticipant -> userInServerIds.contains(meetupParticipant.getParticipator().getUserInServerId())); .getParticipants().removeIf(meetupParticipant -> userInServerIds.contains(meetupParticipant.getParticipator().getUserInServerId()));
MeetupMessageModel meetupMessageModel = getMeetupMessageModel(meetup); Long meetupChannelId = meetup.getMeetupChannel().getId();
return getMeetupMessageModel(meetup).thenCompose(meetupMessageModel ->
self.changeMeetupTimeInternal(meetupMessageModel, serverId, meetupChannelId, meetupMessageId, meetupId));
}
@Transactional
public CompletableFuture<Void> changeMeetupTimeInternal(MeetupMessageModel meetupMessageModel, Long serverId, Long meetupChannelId, Long meetupMessageId, Long meetupId) {
meetupMessageModel.setParticipants(new ArrayList<>()); meetupMessageModel.setParticipants(new ArrayList<>());
meetupMessageModel.setMaybeParticipants(new ArrayList<>()); meetupMessageModel.setMaybeParticipants(new ArrayList<>());
meetupMessageModel.setNoTimeParticipants(new ArrayList<>()); meetupMessageModel.setNoTimeParticipants(new ArrayList<>());
MessageToSend updatedMeetupMessage = getMeetupMessage(meetupMessageModel, serverId); MessageToSend updatedMeetupMessage = getMeetupMessage(meetupMessageModel, serverId);
GuildMessageChannel meetupChannel = channelService.getMessageChannelFromServer(serverId, meetup.getMeetupChannel().getId()); GuildMessageChannel meetupChannel = channelService.getMessageChannelFromServer(serverId, meetupChannelId);
return channelService.editMessageInAChannelFuture(updatedMeetupMessage, meetupChannel, meetup.getMessageId()) return channelService.editMessageInAChannelFuture(updatedMeetupMessage, meetupChannel, meetupMessageId)
.thenAccept(message -> log.info("Updated message of meetup {} in channel {} in server {}.", meetupId, meetup.getMeetupChannel().getId(), serverId)) .thenAccept(message -> log.info("Updated message of meetup {} in channel {} in server {}.", meetupId, meetupChannelId, serverId))
.thenAccept(unused -> fileService.safeDeleteIgnoreException(updatedMeetupMessage.getAttachedFiles().get(0).getFile())) .thenAccept(unused -> fileService.safeDeleteIgnoreException(updatedMeetupMessage.getAttachedFiles().get(0).getFile()))
.exceptionally(throwable -> { .exceptionally(throwable -> {
log.info("Failed to update message of meetup {} in channel {} in server {}.", meetupId, meetup.getMeetupChannel().getId(), serverId, throwable); log.info("Failed to update message of meetup {} in channel {} in server {}.", meetupId, meetupChannelId, serverId, throwable);
return null; return null;
}); });
} }
@@ -456,14 +541,21 @@ public class MeetupServiceBean {
private CompletableFuture<Void> updateMeetupMessage(Meetup meetup) { private CompletableFuture<Void> updateMeetupMessage(Meetup meetup) {
Long meetupId = meetup.getId().getId(); Long meetupId = meetup.getId().getId();
Long serverId = meetup.getId().getServerId(); Long serverId = meetup.getId().getServerId();
MeetupMessageModel meetupMessageModel = getMeetupMessageModel(meetup); Long meetupChannelId = meetup.getMeetupChannel().getId();
Long meetupMessageId = meetup.getMessageId();
return getMeetupMessageModel(meetup).thenCompose(meetupMessageModel ->
self.updateMessageInternal(meetupMessageModel, serverId, meetupChannelId, meetupMessageId, meetupId));
}
@Transactional
public CompletableFuture<Void> updateMessageInternal(MeetupMessageModel meetupMessageModel, Long serverId, Long meetupChannelId, Long meetupMessageId, Long meetupId) {
MessageToSend updatedMeetupMessage = getMeetupMessage(meetupMessageModel, serverId); MessageToSend updatedMeetupMessage = getMeetupMessage(meetupMessageModel, serverId);
GuildMessageChannel meetupChannel = channelService.getMessageChannelFromServer(serverId, meetup.getMeetupChannel().getId()); GuildMessageChannel meetupChannel = channelService.getMessageChannelFromServer(serverId, meetupChannelId);
return channelService.editMessageInAChannelFuture(updatedMeetupMessage, meetupChannel, meetup.getMessageId()) return channelService.editMessageInAChannelFuture(updatedMeetupMessage, meetupChannel, meetupMessageId)
.thenAccept(message -> log.info("Updated message of meetup {} in channel {} in server {}.", meetupId, meetup.getMeetupChannel().getId(), serverId)) .thenAccept(message -> log.info("Updated message of meetup {} in channel {} in server {}.", meetupId, meetupChannelId, serverId))
.thenAccept(unused -> fileService.safeDeleteIgnoreException(updatedMeetupMessage.getAttachedFiles().get(0).getFile())) .thenAccept(unused -> fileService.safeDeleteIgnoreException(updatedMeetupMessage.getAttachedFiles().get(0).getFile()))
.exceptionally(throwable -> { .exceptionally(throwable -> {
log.info("Failed to update message of meetup {} in channel {} in server {}.", meetupId, meetup.getMeetupChannel().getId(), serverId, throwable); log.info("Failed to update message of meetup {} in channel {} in server {}.", meetupId, meetupChannelId, serverId, throwable);
return null; return null;
}); });
} }

View File

@@ -1,19 +1,18 @@
<#include "format_instant"> <#include "format_instant">
{ {
<#macro display_user member_to_display><#if member_to_display.name??>${member_to_display.name}<#else>${member_to_display.memberMention}</#if></#macro>
"components": [ "components": [
{ {
"type": "textDisplay", "type": "textDisplay",
<#assign roleMention="<@&371419588619141121>"/> <#assign roleMention="<@&371419588619141121>"/>
"content": "<#if cancelled>~~</#if>${roleMention?json_string} ${topic?json_string} - <@safe_include "meetup_message_id_display"/><#if cancelled>~~</#if>" "content": "<#if cancelled>~~</#if>${roleMention?json_string} ${topic?json_string} - <@safe_include "meetup_message_id_display"/><#if cancelled>~~</#if>"
}, },
<#if description?has_content>
{ {
<#assign descriptionText>${description?json_string}</#assign> <#assign descriptionText><#if description?has_content>${description?json_string}<#else><@safe_include "meetup_description_no_description"/></#if></#assign>
<#assign organizerText>${organizer.memberMention}</#assign> <#assign organizerText><@display_user member_to_display=organizer/></#assign>
"type": "textDisplay", "type": "textDisplay",
"content": "<#if cancelled>~~</#if><@safe_include "meetup_description_component"/><#if cancelled>~~</#if>" "content": "<#if cancelled>~~</#if><@safe_include "meetup_description_component"/><#if cancelled>~~</#if>"
}, },
</#if>
{ {
<#assign time><@format_instant_long_date_time instant=meetupTime/></#assign> <#assign time><@format_instant_long_date_time instant=meetupTime/></#assign>
<#assign timeRelative><@format_instant_relative instant=meetupTime/></#assign> <#assign timeRelative><@format_instant_relative instant=meetupTime/></#assign>
@@ -54,10 +53,10 @@
} }
} }
</#macro> </#macro>
<#assign participantsText> (${participants?size}) <#list participants as member>${member.memberMention}<#sep>, </#sep><#else><#include "meetup_message_no_member"></#list></#assign> <#assign participantsText> (${participants?size}) <#list participants as member><@display_user member_to_display=member/><#sep>, </#sep><#else><#include "meetup_message_no_member"></#list></#assign>
<#assign maybeParticipantsText> (${maybeParticipants?size}) <#list maybeParticipants as member>${member.memberMention}<#sep>, </#sep><#else><#include "meetup_message_no_member"></#list></#assign> <#assign maybeParticipantsText> (${maybeParticipants?size}) <#list maybeParticipants as member><@display_user member_to_display=member/><#sep>, </#sep><#else><#include "meetup_message_no_member"></#list></#assign>
<#assign noTimeParticipantsText> (${noTimeParticipants?size}) <#list noTimeParticipants as member>${member.memberMention}<#sep>, </#sep><#else><#include "meetup_message_no_member"></#list></#assign> <#assign noTimeParticipantsText> (${noTimeParticipants?size}) <#list noTimeParticipants as member><@display_user member_to_display=member/><#sep>, </#sep><#else><#include "meetup_message_no_member"></#list></#assign>
<#assign declinedParticipantsText> (${declinedParticipants?size}) <#list declinedParticipants as member>${member.memberMention}<#sep>, </#sep><#else><#include "meetup_message_no_member"></#list></#assign> <#assign declinedParticipantsText> (${declinedParticipants?size}) <#list declinedParticipants as member><@display_user member_to_display=member/><#sep>, </#sep><#else><#include "meetup_message_no_member"></#list></#assign>
,<@decision_component yesId "success" "meetup_message_yes_button_label" "meetup_user_display_participants" participantsText/> ,<@decision_component yesId "success" "meetup_message_yes_button_label" "meetup_user_display_participants" participantsText/>
,<@decision_component maybeId "secondary" "meetup_message_maybe_button_label" "meetup_user_display_maybe_participants" maybeParticipantsText/> ,<@decision_component maybeId "secondary" "meetup_message_maybe_button_label" "meetup_user_display_maybe_participants" maybeParticipantsText/>
,<@decision_component noId "danger" "meetup_message_no_button_label" "meetup_user_display_declined_participants" declinedParticipantsText/> ,<@decision_component noId "danger" "meetup_message_no_button_label" "meetup_user_display_declined_participants" declinedParticipantsText/>