2024-03-12 14:05:27 -04:00
|
|
|
using TwitchChatTTS.Helpers;
|
|
|
|
using TwitchChatTTS;
|
|
|
|
using System.Text.Json;
|
2024-06-16 20:19:31 -04:00
|
|
|
using HermesSocketLibrary.Requests.Messages;
|
|
|
|
using TwitchChatTTS.Hermes;
|
2024-08-04 19:46:10 -04:00
|
|
|
using Serilog;
|
2023-12-30 04:27:31 -05:00
|
|
|
|
2024-06-16 20:19:31 -04:00
|
|
|
public class HermesApiClient
|
|
|
|
{
|
2024-08-04 19:46:10 -04:00
|
|
|
private readonly TwitchBotAuth _token;
|
2024-06-24 18:11:36 -04:00
|
|
|
private readonly WebClientWrap _web;
|
2024-08-04 19:46:10 -04:00
|
|
|
private readonly ILogger _logger;
|
2024-08-06 15:29:29 -04:00
|
|
|
|
2024-07-12 13:36:09 -04:00
|
|
|
public const string BASE_URL = "tomtospeech.com";
|
2023-12-30 04:27:31 -05:00
|
|
|
|
2024-08-04 19:46:10 -04:00
|
|
|
public HermesApiClient(TwitchBotAuth token, Configuration configuration, ILogger logger)
|
2024-06-16 20:19:31 -04:00
|
|
|
{
|
|
|
|
if (string.IsNullOrWhiteSpace(configuration.Hermes?.Token))
|
|
|
|
{
|
2023-12-30 04:27:31 -05:00
|
|
|
throw new Exception("Ensure you have written your API key in \".token\" file, in the same folder as this application.");
|
|
|
|
}
|
|
|
|
|
2024-08-04 19:46:10 -04:00
|
|
|
_token = token;
|
2024-06-16 20:19:31 -04:00
|
|
|
_web = new WebClientWrap(new JsonSerializerOptions()
|
|
|
|
{
|
2024-03-12 14:05:27 -04:00
|
|
|
PropertyNameCaseInsensitive = false,
|
|
|
|
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
|
|
|
|
});
|
2024-03-15 08:27:35 -04:00
|
|
|
_web.AddHeader("x-api-key", configuration.Hermes.Token);
|
2024-08-04 19:46:10 -04:00
|
|
|
_logger = logger;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-08-06 15:29:29 -04:00
|
|
|
public async Task<TwitchBotAuth?> AuthorizeTwitch()
|
2024-08-04 19:46:10 -04:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
_logger.Debug($"Attempting to authorize Twitch API...");
|
|
|
|
var authorize = await _web.GetJson<TwitchBotAuth>($"https://{HermesApiClient.BASE_URL}/api/account/reauthorize");
|
|
|
|
if (authorize != null)
|
|
|
|
{
|
|
|
|
_token.AccessToken = authorize.AccessToken;
|
|
|
|
_token.RefreshToken = authorize.RefreshToken;
|
|
|
|
_token.UserId = authorize.UserId;
|
|
|
|
_token.BroadcasterId = authorize.BroadcasterId;
|
|
|
|
_token.ExpiresIn = authorize.ExpiresIn;
|
|
|
|
_token.UpdatedAt = DateTime.Now;
|
|
|
|
_logger.Information("Updated Twitch API tokens.");
|
|
|
|
_logger.Debug($"Twitch API Auth data [user id: {_token.UserId}][id: {_token.BroadcasterId}][expires in: {_token.ExpiresIn}][expires at: {_token.ExpiresAt.ToShortTimeString()}]");
|
|
|
|
}
|
|
|
|
else if (authorize != null)
|
|
|
|
{
|
|
|
|
_logger.Error("Twitch API Authorization failed: " + authorize.AccessToken + " | " + authorize.RefreshToken + " | " + authorize.UserId + " | " + authorize.BroadcasterId);
|
2024-08-06 15:29:29 -04:00
|
|
|
return null;
|
2024-08-04 19:46:10 -04:00
|
|
|
}
|
2024-08-06 15:29:29 -04:00
|
|
|
return _token;
|
2024-08-04 19:46:10 -04:00
|
|
|
}
|
|
|
|
catch (JsonException)
|
|
|
|
{
|
|
|
|
_logger.Debug($"Failed to Authorize Twitch API due to JSON error.");
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
_logger.Error(e, "Failed to authorize to Twitch API.");
|
|
|
|
}
|
2024-08-06 15:29:29 -04:00
|
|
|
return null;
|
2023-12-30 04:27:31 -05:00
|
|
|
}
|
|
|
|
|
2024-07-12 13:36:09 -04:00
|
|
|
public async Task<TTSVersion?> GetLatestTTSVersion()
|
2024-06-16 20:19:31 -04:00
|
|
|
{
|
2024-07-12 13:36:09 -04:00
|
|
|
return await _web.GetJson<TTSVersion>($"https://{BASE_URL}/api/info/version");
|
2024-06-16 20:19:31 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<Account> FetchHermesAccountDetails()
|
|
|
|
{
|
2024-08-06 15:29:29 -04:00
|
|
|
var account = await _web.GetJson<Account>($"https://{BASE_URL}/api/account", new JsonSerializerOptions()
|
|
|
|
{
|
|
|
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
|
|
|
});
|
2024-03-15 08:27:35 -04:00
|
|
|
if (account == null || account.Id == null || account.Username == null)
|
|
|
|
throw new NullReferenceException("Invalid value found while fetching for hermes account data.");
|
|
|
|
return account;
|
2023-12-30 04:27:31 -05:00
|
|
|
}
|
|
|
|
|
2024-06-16 20:19:31 -04:00
|
|
|
public async Task<TwitchBotToken> FetchTwitchBotToken()
|
|
|
|
{
|
2024-07-12 13:36:09 -04:00
|
|
|
var token = await _web.GetJson<TwitchBotToken>($"https://{BASE_URL}/api/token/bot");
|
2024-03-15 08:27:35 -04:00
|
|
|
if (token == null || token.ClientId == null || token.AccessToken == null || token.RefreshToken == null || token.ClientSecret == null)
|
2023-12-30 04:27:31 -05:00
|
|
|
throw new Exception("Failed to fetch Twitch API token from Hermes.");
|
|
|
|
|
|
|
|
return token;
|
|
|
|
}
|
2024-01-05 05:07:41 -05:00
|
|
|
|
2024-06-16 20:19:31 -04:00
|
|
|
public async Task<string> FetchTTSDefaultVoice()
|
|
|
|
{
|
2024-07-12 13:36:09 -04:00
|
|
|
var data = await _web.GetJson<string>($"https://{BASE_URL}/api/settings/tts/default");
|
2024-03-15 08:27:35 -04:00
|
|
|
if (data == null)
|
2024-01-05 05:07:41 -05:00
|
|
|
throw new Exception("Failed to fetch TTS default voice from Hermes.");
|
|
|
|
|
2024-06-16 20:19:31 -04:00
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<IEnumerable<TTSChatterSelectedVoice>> FetchTTSChatterSelectedVoices()
|
|
|
|
{
|
2024-07-12 13:36:09 -04:00
|
|
|
var voices = await _web.GetJson<IEnumerable<TTSChatterSelectedVoice>>($"https://{BASE_URL}/api/settings/tts/selected");
|
2024-06-16 20:19:31 -04:00
|
|
|
if (voices == null)
|
|
|
|
throw new Exception("Failed to fetch TTS chatter selected voices from Hermes.");
|
|
|
|
|
|
|
|
return voices;
|
2024-01-05 05:07:41 -05:00
|
|
|
}
|
|
|
|
|
2024-06-16 20:19:31 -04:00
|
|
|
public async Task<IEnumerable<string>> FetchTTSEnabledVoices()
|
|
|
|
{
|
2024-07-12 13:36:09 -04:00
|
|
|
var voices = await _web.GetJson<IEnumerable<string>>($"https://{BASE_URL}/api/settings/tts");
|
2024-03-15 08:27:35 -04:00
|
|
|
if (voices == null)
|
2024-01-05 05:07:41 -05:00
|
|
|
throw new Exception("Failed to fetch TTS enabled voices from Hermes.");
|
|
|
|
|
|
|
|
return voices;
|
|
|
|
}
|
|
|
|
|
2024-06-16 20:19:31 -04:00
|
|
|
public async Task<IEnumerable<TTSWordFilter>> FetchTTSWordFilters()
|
|
|
|
{
|
2024-07-12 13:36:09 -04:00
|
|
|
var filters = await _web.GetJson<IEnumerable<TTSWordFilter>>($"https://{BASE_URL}/api/settings/tts/filter/words");
|
2024-03-15 08:27:35 -04:00
|
|
|
if (filters == null)
|
2024-01-05 05:07:41 -05:00
|
|
|
throw new Exception("Failed to fetch TTS word filters from Hermes.");
|
|
|
|
|
|
|
|
return filters;
|
|
|
|
}
|
2024-06-24 18:11:36 -04:00
|
|
|
|
|
|
|
public async Task<IEnumerable<Redemption>> FetchRedemptions()
|
|
|
|
{
|
2024-07-12 13:36:09 -04:00
|
|
|
var redemptions = await _web.GetJson<IEnumerable<Redemption>>($"https://{BASE_URL}/api/settings/redemptions", new JsonSerializerOptions()
|
2024-06-24 18:11:36 -04:00
|
|
|
{
|
|
|
|
PropertyNameCaseInsensitive = false,
|
|
|
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
|
|
|
});
|
|
|
|
if (redemptions == null)
|
2024-07-12 13:36:09 -04:00
|
|
|
throw new Exception("Failed to fetch redemptions from Hermes.");
|
2024-06-24 18:11:36 -04:00
|
|
|
|
|
|
|
return redemptions;
|
|
|
|
}
|
|
|
|
|
2024-07-12 13:36:09 -04:00
|
|
|
public async Task<IEnumerable<Group>> FetchGroups()
|
|
|
|
{
|
|
|
|
var groups = await _web.GetJson<IEnumerable<Group>>($"https://{BASE_URL}/api/settings/groups", new JsonSerializerOptions()
|
|
|
|
{
|
|
|
|
PropertyNameCaseInsensitive = false,
|
|
|
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
|
|
|
});
|
|
|
|
if (groups == null)
|
|
|
|
throw new Exception("Failed to fetch groups from Hermes.");
|
|
|
|
|
|
|
|
return groups;
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<IEnumerable<GroupChatter>> FetchGroupChatters()
|
|
|
|
{
|
|
|
|
var chatters = await _web.GetJson<IEnumerable<GroupChatter>>($"https://{BASE_URL}/api/settings/groups/users", new JsonSerializerOptions()
|
|
|
|
{
|
|
|
|
PropertyNameCaseInsensitive = false,
|
|
|
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
|
|
|
});
|
|
|
|
if (chatters == null)
|
|
|
|
throw new Exception("Failed to fetch groups from Hermes.");
|
|
|
|
|
|
|
|
return chatters;
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<IEnumerable<GroupPermission>> FetchGroupPermissions()
|
|
|
|
{
|
|
|
|
var permissions = await _web.GetJson<IEnumerable<GroupPermission>>($"https://{BASE_URL}/api/settings/groups/permissions", new JsonSerializerOptions()
|
|
|
|
{
|
|
|
|
PropertyNameCaseInsensitive = false,
|
|
|
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
|
|
|
});
|
|
|
|
if (permissions == null)
|
|
|
|
throw new Exception("Failed to fetch group permissions from Hermes.");
|
|
|
|
|
|
|
|
return permissions;
|
|
|
|
}
|
|
|
|
|
2024-06-24 18:11:36 -04:00
|
|
|
public async Task<IEnumerable<RedeemableAction>> FetchRedeemableActions()
|
|
|
|
{
|
2024-07-12 13:36:09 -04:00
|
|
|
var actions = await _web.GetJson<IEnumerable<RedeemableAction>>($"https://{BASE_URL}/api/settings/redemptions/actions");
|
2024-06-24 18:11:36 -04:00
|
|
|
if (actions == null)
|
|
|
|
throw new Exception("Failed to fetch redeemable actions from Hermes.");
|
|
|
|
|
|
|
|
return actions;
|
|
|
|
}
|
2023-12-30 04:27:31 -05:00
|
|
|
}
|