Fixed 7tv & Twitch reconnection. Added adbreak, follow, subscription handlers for Twitch. Added multi-chat support. Added support to unsubscribe from Twitch event subs.

This commit is contained in:
Tom
2024-08-06 19:29:29 +00:00
parent 75fcb8e0f8
commit 8014c12bc5
60 changed files with 1064 additions and 672 deletions

View File

@ -1,4 +1,6 @@
public class Account {
public string Id { get; set; }
public string Username { get; set; }
public string Role { get; set; }
public string? BroadcasterId { get; set; }
}

View File

@ -1,6 +1,7 @@
namespace TwitchChatTTS.Hermes
{
public interface ICustomDataManager {
public interface ICustomDataManager
{
void Add(string key, object value, string type);
void Change(string key, object value);
void Delete(string key);
@ -11,7 +12,8 @@ namespace TwitchChatTTS.Hermes
{
private IDictionary<string, DataInfo> _data;
public CustomDataManager() {
public CustomDataManager()
{
_data = new Dictionary<string, DataInfo>();
}
@ -37,8 +39,9 @@ namespace TwitchChatTTS.Hermes
}
}
// type: text (string), whole number (int), number (double), boolean, formula (string, data type of number)
public struct DataInfo {
// type: text (string), whole number (int), number (double), boolean, formula (string, data type of number)
public struct DataInfo
{
public string Id { get; set; }
public string Type { get; set; }
public object Value { get; set; }

View File

@ -10,7 +10,7 @@ public class HermesApiClient
private readonly TwitchBotAuth _token;
private readonly WebClientWrap _web;
private readonly ILogger _logger;
public const string BASE_URL = "tomtospeech.com";
public HermesApiClient(TwitchBotAuth token, Configuration configuration, ILogger logger)
@ -31,7 +31,7 @@ public class HermesApiClient
}
public async Task<bool> AuthorizeTwitch()
public async Task<TwitchBotAuth?> AuthorizeTwitch()
{
try
{
@ -51,10 +51,9 @@ public class HermesApiClient
else if (authorize != null)
{
_logger.Error("Twitch API Authorization failed: " + authorize.AccessToken + " | " + authorize.RefreshToken + " | " + authorize.UserId + " | " + authorize.BroadcasterId);
return false;
return null;
}
_logger.Debug($"Authorized Twitch API.");
return true;
return _token;
}
catch (JsonException)
{
@ -64,7 +63,7 @@ public class HermesApiClient
{
_logger.Error(e, "Failed to authorize to Twitch API.");
}
return false;
return null;
}
public async Task<TTSVersion?> GetLatestTTSVersion()
@ -74,7 +73,10 @@ public class HermesApiClient
public async Task<Account> FetchHermesAccountDetails()
{
var account = await _web.GetJson<Account>($"https://{BASE_URL}/api/account");
var account = await _web.GetJson<Account>($"https://{BASE_URL}/api/account", new JsonSerializerOptions()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
});
if (account == null || account.Id == null || account.Username == null)
throw new NullReferenceException("Invalid value found while fetching for hermes account data.");
return account;

View File

@ -18,7 +18,6 @@ namespace TwitchChatTTS.Hermes.Socket.Handlers
public class RequestAckHandler : IWebSocketHandler
{
private User _user;
//private readonly RedemptionManager _redemptionManager;
private readonly ICallbackManager<HermesRequestData> _callbackManager;
private readonly IServiceProvider _serviceProvider;
private readonly JsonSerializerOptions _options;
@ -30,16 +29,16 @@ namespace TwitchChatTTS.Hermes.Socket.Handlers
public RequestAckHandler(
User user,
ICallbackManager<HermesRequestData> callbackManager,
IServiceProvider serviceProvider,
User user,
JsonSerializerOptions options,
ILogger logger
)
{
_user = user;
_callbackManager = callbackManager;
_serviceProvider = serviceProvider;
_user = user;
_options = options;
_logger = logger;
}
@ -263,15 +262,15 @@ namespace TwitchChatTTS.Hermes.Socket.Handlers
re.Match(string.Empty);
filter.Regex = re;
}
catch (Exception e) { }
catch (Exception) { }
}
_user.RegexFilters = filters;
_logger.Information($"TTS word filters [count: {_user.RegexFilters.Count()}] have been refreshed.");
}
else if (message.Request.Type == "update_tts_voice_state")
{
string voiceId = message.Request.Data["voice"].ToString();
bool state = message.Request.Data["state"].ToString().ToLower() == "true";
string voiceId = message.Request.Data?["voice"].ToString()!;
bool state = message.Request.Data?["state"].ToString()!.ToLower() == "true";
if (!_user.VoicesAvailable.TryGetValue(voiceId, out string? voiceName) || voiceName == null)
{
@ -305,14 +304,14 @@ namespace TwitchChatTTS.Hermes.Socket.Handlers
_logger.Warning("Failed to read the redeemable actions for redemptions.");
return;
}
if (hermesRequestData?.Data == null || !(hermesRequestData.Data["redemptions"] is IEnumerable<Redemption> redemptions))
if (hermesRequestData?.Data == null || hermesRequestData.Data["redemptions"] is not IEnumerable<Redemption> redemptions)
{
_logger.Warning("Failed to read the redemptions while updating redemption actions.");
return;
}
_logger.Information($"Redeemable actions [count: {actions.Count()}] loaded.");
var redemptionManager = _serviceProvider.GetRequiredService<RedemptionManager>();
var redemptionManager = _serviceProvider.GetRequiredService<IRedemptionManager>();
redemptionManager.Initialize(redemptions, actions.ToDictionary(a => a.Name, a => a));
}
else if (message.Request.Type == "get_default_tts_voice")

View File

@ -104,7 +104,8 @@ namespace TwitchChatTTS.Hermes.Socket
});
}
public async Task FetchChatterIdentifiers() {
public async Task FetchChatterIdentifiers()
{
await Send(3, new RequestMessage()
{
Type = "get_chatter_ids",
@ -112,7 +113,8 @@ namespace TwitchChatTTS.Hermes.Socket
});
}
public async Task FetchDefaultTTSVoice() {
public async Task FetchDefaultTTSVoice()
{
await Send(3, new RequestMessage()
{
Type = "get_default_tts_voice",
@ -120,7 +122,8 @@ namespace TwitchChatTTS.Hermes.Socket
});
}
public async Task FetchEmotes() {
public async Task FetchEmotes()
{
await Send(3, new RequestMessage()
{
Type = "get_emotes",
@ -128,7 +131,8 @@ namespace TwitchChatTTS.Hermes.Socket
});
}
public async Task FetchEnabledTTSVoices() {
public async Task FetchEnabledTTSVoices()
{
await Send(3, new RequestMessage()
{
Type = "get_enabled_tts_voices",
@ -136,7 +140,8 @@ namespace TwitchChatTTS.Hermes.Socket
});
}
public async Task FetchTTSVoices() {
public async Task FetchTTSVoices()
{
await Send(3, new RequestMessage()
{
Type = "get_tts_voices",
@ -144,7 +149,8 @@ namespace TwitchChatTTS.Hermes.Socket
});
}
public async Task FetchTTSChatterVoices() {
public async Task FetchTTSChatterVoices()
{
await Send(3, new RequestMessage()
{
Type = "get_tts_users",
@ -152,7 +158,8 @@ namespace TwitchChatTTS.Hermes.Socket
});
}
public async Task FetchTTSWordFilters() {
public async Task FetchTTSWordFilters()
{
await Send(3, new RequestMessage()
{
Type = "get_tts_word_filters",