[AB-xxx] adding ability to refresh twitch stream notification texts

This commit is contained in:
Sheldan
2026-05-03 00:28:02 +02:00
parent 2ae2542c71
commit 96cbe2db87
9 changed files with 69 additions and 4 deletions

View File

@@ -13,6 +13,7 @@ import dev.sheldan.abstracto.core.service.management.UserInServerManagementServi
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
import dev.sheldan.abstracto.core.utils.ParseUtils;
import dev.sheldan.abstracto.twitch.config.TwitchFeatureConfig;
import dev.sheldan.abstracto.twitch.config.TwitchFeatureDefinition;
import dev.sheldan.abstracto.twitch.config.TwitchFeatureMode;
@@ -26,6 +27,8 @@ import dev.sheldan.abstracto.twitch.model.template.*;
import dev.sheldan.abstracto.twitch.service.management.StreamSessionManagementService;
import dev.sheldan.abstracto.twitch.service.management.StreamSessionSectionManagementService;
import dev.sheldan.abstracto.twitch.service.management.StreamerManagementService;
import java.time.Duration;
import java.time.Instant;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
@@ -92,6 +95,9 @@ public class StreamerServiceBean implements StreamerService {
@Autowired
private MessageService messageService;
@Autowired
private ConfigService configService;
@Autowired
private StreamerServiceBean self;
@@ -277,6 +283,8 @@ public class StreamerServiceBean implements StreamerService {
log.debug("Searching through {} servers for twitch notifications and {} have twitch feature enabled.", servers.size(), serversWithEnabledFeature.size());
serversWithEnabledFeature.forEach(server -> {
List<Streamer> streamersInServer = streamerManagementService.getStreamersForServer(server);
String refreshDurationString = configService.getStringValueOrConfigDefault(TwitchFeatureConfig.TWITCH_REFRESH_INTERVAL, server.getId());
Duration refreshDuration = ParseUtils.parseDuration(refreshDurationString);
Map<Long, Streamer> streamerIdMap = streamersInServer
.stream()
.collect(Collectors.toMap(Streamer::getId, Function.identity()));
@@ -295,7 +303,7 @@ public class StreamerServiceBean implements StreamerService {
List<Stream> streamsOfUsers = twitchService.getStreamsByUserIds(userIds);
Set<Long> onlineStreamers = new HashSet<>();
Map<Long, Boolean> updateNotificationFlagValues = new HashMap<>();
streamsOfUsers.forEach(stream -> self.processOnlineStreamer(server, streamerMap, onlineStreamers, updateNotificationFlagValues, stream));
streamsOfUsers.forEach(stream -> self.processOnlineStreamer(server, streamerMap, onlineStreamers, updateNotificationFlagValues, stream, refreshDuration));
Set<Long> allStreamersInServer = streamerIdMap.keySet();
allStreamersInServer.removeAll(onlineStreamers); // then we have those that went offline
Map<Long, Boolean> deleteFlagValues = new HashMap<>();
@@ -370,7 +378,8 @@ public class StreamerServiceBean implements StreamerService {
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void processOnlineStreamer(AServer server, Map<String, Streamer> streamerMap, Set<Long> onlineStreamers, Map<Long, Boolean> updateNotificationFlagValues, Stream stream) {
public void processOnlineStreamer(AServer server, Map<String, Streamer> streamerMap, Set<Long> onlineStreamers, Map<Long, Boolean> updateNotificationFlagValues,
Stream stream, Duration refreshDuration) {
Streamer streamer = streamerMap.get(stream.getUserId());
Long streamerId = streamer.getId();
onlineStreamers.add(streamerId);
@@ -378,18 +387,19 @@ public class StreamerServiceBean implements StreamerService {
// that is the case if you add an online streamer
User streamerUser = twitchService.getStreamerById(stream.getUserId());
StreamSession currentSession = streamer.getCurrentSession();
Long serverId = streamer.getServer().getId();
if (Boolean.TRUE.equals(streamer.getOnline()) && currentSession != null) {
// we already know that this streamer is online
log.debug("Not notifying for streamer {} in server {} - streamer is already online.", streamerId, server.getId());
if(!stream.getGameId().equals(streamer.getCurrentGameId())) {
log.info("Streamer {} changed game from {} to {} - storing new section.", streamerId, streamer.getCurrentGameId(), stream.getGameId());
streamSessionSectionService.createSectionFromStream(currentSession, stream);
currentSession.setLastUpdated(Instant.now());
if (updateNotificationFlagValues.computeIfAbsent(streamer.getServer().getId(),
aLong -> featureModeService.featureModeActive(TwitchFeatureDefinition.TWITCH, aLong, TwitchFeatureMode.UPDATE_NOTIFICATION))) {
log.info("Updating notification is enabled - updating notification for streamer {}.", streamer.getId());
Long notificationMessageId = currentSession.getId();
Long notificationChannelId = currentSession.getChannel().getId();
Long serverId = streamer.getServer().getId();
updateExistingNotification(stream, streamer, streamerUser).thenAccept(unused -> {
log.info("Updating existing notification {} for server {} in channel {} about streamer {}.",
notificationMessageId, serverId, notificationChannelId, streamerId);
@@ -400,6 +410,20 @@ public class StreamerServiceBean implements StreamerService {
});
}
streamer.setCurrentGameId(stream.getGameId());
} else if(currentSession.getLastUpdated().isBefore(Instant.now().minus(refreshDuration)) &&
updateNotificationFlagValues.computeIfAbsent(streamer.getServer().getId(),
serverIdKey -> featureModeService.featureModeActive(TwitchFeatureDefinition.TWITCH, serverIdKey, TwitchFeatureMode.UPDATE_NOTIFICATION))) {
Long notificationMessageId = currentSession.getId();
currentSession.setLastUpdated(Instant.now());
Long notificationChannelId = currentSession.getChannel().getId();
updateExistingNotification(stream, streamer, streamerUser).thenAccept(unused -> {
log.info("Updating existing notification {} for server {} in channel {} about streamer {}.",
notificationMessageId, serverId, notificationChannelId, streamerId);
}).exceptionally(throwable -> {
log.error("Failed to update existing notification {} for server {} in channel {} about streamer {}.",
notificationMessageId, serverId, notificationChannelId, streamerId, throwable);
return null;
});
}
} else if(currentSession == null &&
!postTargetService.postTargetUsableInServer(TwitchPostTarget.TWITCH_LIVE_NOTIFICATION, server.getId())) {

View File

@@ -6,6 +6,7 @@ import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.twitch.model.database.Streamer;
import dev.sheldan.abstracto.twitch.model.database.StreamSession;
import dev.sheldan.abstracto.twitch.repository.StreamSessionRepository;
import java.time.Instant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -26,6 +27,7 @@ public class StreamSessionManagementServiceBean implements StreamSessionManageme
.id(messageId)
.startTime(stream.getStartedAtInstant())
.channel(channel)
.lastUpdated(Instant.now())
.streamer(streamer)
.streamId(stream.getId())
.build();

View File

@@ -0,0 +1,6 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<include file="tables/tables.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,12 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<changeSet author="Sheldan" id="stream_session-add_last_updated">
<addColumn tableName="stream_session">
<column name="last_updated" type="TIMESTAMP WITHOUT TIME ZONE" defaultValueComputed="CURRENT_TIMESTAMP">
<constraints nullable="false" />
</column>
</addColumn>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,6 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<include file="stream_session.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -3,4 +3,5 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<include file="1.4.27/collection.xml" relativeToChangelogFile="true"/>
<include file="1.6.25/collection.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -12,4 +12,7 @@ abstracto.featureModes.deleteNotification.enabled=true
abstracto.featureModes.updateNotification.featureName=twitch
abstracto.featureModes.updateNotification.mode=updateNotification
abstracto.featureModes.updateNotification.enabled=true
abstracto.featureModes.updateNotification.enabled=true
abstracto.systemConfigs.twitchRefreshInterval.name=twitchRefreshInterval
abstracto.systemConfigs.twitchRefreshInterval.stringValue=30m

View File

@@ -11,6 +11,9 @@ import java.util.List;
@Component
public class TwitchFeatureConfig implements FeatureConfig {
public static final String TWITCH_REFRESH_INTERVAL = "twitchRefreshInterval";
@Override
public FeatureDefinition getFeature() {
return TwitchFeatureDefinition.TWITCH;
@@ -25,4 +28,9 @@ public class TwitchFeatureConfig implements FeatureConfig {
public List<FeatureMode> getAvailableModes() {
return Arrays.asList(TwitchFeatureMode.DELETE_NOTIFICATION, TwitchFeatureMode.UPDATE_NOTIFICATION);
}
@Override
public List<String> getRequiredSystemConfigKeys() {
return List.of(TWITCH_REFRESH_INTERVAL);
}
}

View File

@@ -39,6 +39,9 @@ public class StreamSession {
@Column(name = "updated", insertable = false, updatable = false)
private Instant updated;
@Column(name = "lastUpdated")
private Instant lastUpdated;
@Column(name = "startTime", nullable = false)
private Instant startTime;