From c3e3df622c5787efa451afe5685301b3583eed3a Mon Sep 17 00:00:00 2001 From: orciument Date: Thu, 10 Apr 2025 00:45:08 +0200 Subject: [PATCH] restart the twitch4J every 2 hours so that the oauth doesn't time out --- bot/main/talium/TwitchBot.java | 30 +++++++++--- bot/main/talium/twitch4J/Twitch4JInput.java | 54 +++++++++++++++------ bot/resources/logback.xml | 5 +- wiki | 2 +- 4 files changed, 67 insertions(+), 24 deletions(-) diff --git a/bot/main/talium/TwitchBot.java b/bot/main/talium/TwitchBot.java index 192658e9..f21f4f0f 100644 --- a/bot/main/talium/TwitchBot.java +++ b/bot/main/talium/TwitchBot.java @@ -2,6 +2,7 @@ import jakarta.annotation.PreDestroy; import jakarta.persistence.PreRemove; +import org.apache.commons.lang3.concurrent.BasicThreadFactory; import org.springframework.context.ConfigurableApplicationContext; import talium.tipeeeStream.DonationRepo; import talium.tipeeeStream.TipeeeConfig; @@ -22,6 +23,11 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import talium.twitchCommands.triggerEngine.TriggerProvider; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; + @SpringBootApplication @EnableJpaRepositories public class TwitchBot { @@ -33,6 +39,13 @@ public static void main(String[] args) { startup(); } + private static final ScheduledExecutorService TWITCH4J_PERIODIC_RESTART_EXECUTOR; + + static { + ThreadFactory namedThreadFactory = new BasicThreadFactory.Builder().namingPattern("TWITCH4J_PERIODIC_RESTART_EXECUTOR").build(); + TWITCH4J_PERIODIC_RESTART_EXECUTOR = Executors.newSingleThreadScheduledExecutor(namedThreadFactory); + } + private static ConfigurableApplicationContext ctx; private static BotInput twitch; private static BotInput tipeee; @@ -66,6 +79,11 @@ public static void startup() { //TODO remove all templates that were once registered automatically, but are no longer time.close(); + + TWITCH4J_PERIODIC_RESTART_EXECUTOR.scheduleAtFixedRate(() -> { + logger.info("Starting periodic Twitch reconnect"); + reconnectTwitch(); + }, 120, 120, TimeUnit.MINUTES); } @PreDestroy @@ -98,17 +116,17 @@ private static void stopInput(BotInput input) { } public static boolean reconnectTwitch() { - twitch.shutdown(); - var twitch = new Twitch4JInput( - ctx.getBean(TwitchConfig.class), - ctx.getBean(OauthAccountRepo.class) - ); try { + twitch.shutdown(); + var twitch = new Twitch4JInput( + ctx.getBean(TwitchConfig.class), + ctx.getBean(OauthAccountRepo.class) + ); twitch.startup(); TwitchBot.twitch = twitch; return true; } catch (Exception e) { - TwitchBot.twitch = twitch; + logger.error("Exception reconnecting twitch: {}", e.getMessage()); return false; } } diff --git a/bot/main/talium/twitch4J/Twitch4JInput.java b/bot/main/talium/twitch4J/Twitch4JInput.java index f010570a..a28c2872 100644 --- a/bot/main/talium/twitch4J/Twitch4JInput.java +++ b/bot/main/talium/twitch4J/Twitch4JInput.java @@ -10,18 +10,18 @@ import com.github.twitch4j.chat.events.channel.ChannelMessageEvent; import com.github.twitch4j.helix.TwitchHelix; import org.apache.commons.lang.RandomStringUtils; -import talium.Registrar; -import talium.oauthConnector.OAuthEndpoint; -import talium.oauthConnector.OauthAccount; -import talium.oauthConnector.OauthAccountRepo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import talium.Out; +import talium.Registrar; import talium.eventSystem.EventDispatcher; import talium.eventSystem.Subscriber; import talium.inputSystem.BotInput; import talium.inputSystem.HealthManager; import talium.inputSystem.InputStatus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import talium.oauthConnector.OAuthEndpoint; +import talium.oauthConnector.OauthAccount; +import talium.oauthConnector.OauthAccountRepo; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -74,19 +74,45 @@ public void startup() { logger.warn(STR."Head to \{OAuthEndpoint.getOauthSetupUrl()} to Setup a new Oauth connection"); HealthManager.reportStatus(Twitch4JInput.class, InputStatus.INJURED); creds = createNewOauth(); + //check if still empty after oauth + if (creds.isEmpty()) { + logger.error("Could neither load old credentials, nor create new once, aborting input startup!"); + HealthManager.reportStatus(Twitch4JInput.class, InputStatus.DEAD); + return; + } else { + logger.warn("Created new Oauth. Warning resolved!"); + HealthManager.reportStatus(Twitch4JInput.class, InputStatus.STARTING); + } } - //check if still empty after oauth - if (creds.isEmpty()) { - logger.error("Could neither load old credentials, nor create new once, aborting input startup!"); + oAuth2Credential = creds.get(); + + Optional credentialValid = iProvider.isCredentialValid(oAuth2Credential); + if (credentialValid.isEmpty()) { + logger.error("Failed to check if credential is valid"); + HealthManager.reportStatus(Twitch4JInput.class, InputStatus.DEAD); + return; + } + if (!credentialValid.get()) { + logger.warn("Oauth credential is not valid"); + Optional newCredential = iProvider.refreshCredential(oAuth2Credential); + if (newCredential.isEmpty()) { + logger.error("Failed to refresh credential for unknown reason"); + HealthManager.reportStatus(Twitch4JInput.class, InputStatus.DEAD); + return; + } + oAuth2Credential = newCredential.get(); + } + if (iProvider.getAdditionalCredentialInformation(oAuth2Credential).isEmpty()) { + logger.warn("Oauth additional credentials could not be found: {}", oAuth2Credential); HealthManager.reportStatus(Twitch4JInput.class, InputStatus.DEAD); return; - } else { - logger.warn("Created new Oauth. Warning resolved!"); - HealthManager.reportStatus(Twitch4JInput.class, InputStatus.STARTING); } - oAuth2Credential = creds.get(); + logger.info("Using Valid Credential: {}", oAuth2Credential); TwitchClient twitchClient = TwitchClientBuilder.builder() + .withClientId(config.app_clientID()) + .withClientSecret(config.app_clientSecret()) + .withRedirectUrl(OAuthEndpoint.getRedirectUrl("twitch")) .withEnableHelix(true) .withEnableChat(true) .withDefaultAuthToken(oAuth2Credential) @@ -173,7 +199,7 @@ public static void convertTwitchMessage(ChannelMessageEvent messageEvent) { try { EventDispatcher.dispatch(ChatMessage.fromChannelMessageEvent(messageEvent)); } catch (ChatMessage.ChatMessageMalformedExceptions e) { - logger.error("Error converting Twitch message", e); + logger.error("Error converting Twitch message", e); } } } \ No newline at end of file diff --git a/bot/resources/logback.xml b/bot/resources/logback.xml index 4247f026..53292e53 100644 --- a/bot/resources/logback.xml +++ b/bot/resources/logback.xml @@ -14,9 +14,8 @@ - - - + + diff --git a/wiki b/wiki index cc4b90e8..1c694c3f 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit cc4b90e8ae359e80300ed69be82e3543f1a9ff55 +Subproject commit 1c694c3f2595a8963ee40ca4299235aa501c59ce