Added Nightbot integration. Changed from client credentials flow to implicit code grant flow.
This commit is contained in:
parent
13bb6a9aa8
commit
0ad063cebd
123
Chat/Commands/NightbotCommand.cs
Normal file
123
Chat/Commands/NightbotCommand.cs
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
using Serilog;
|
||||||
|
using TwitchChatTTS.Hermes.Socket;
|
||||||
|
using TwitchChatTTS.Twitch.Socket.Messages;
|
||||||
|
using static TwitchChatTTS.Chat.Commands.TTSCommands;
|
||||||
|
|
||||||
|
namespace TwitchChatTTS.Chat.Commands
|
||||||
|
{
|
||||||
|
public class NightbotCommand : IChatCommand
|
||||||
|
{
|
||||||
|
private readonly NightbotApiClient _api;
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
public NightbotCommand(NightbotApiClient api, ILogger logger)
|
||||||
|
{
|
||||||
|
_api = api;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name => "nightbot";
|
||||||
|
|
||||||
|
public void Build(ICommandBuilder builder)
|
||||||
|
{
|
||||||
|
builder.CreateCommandTree(Name, b =>
|
||||||
|
{
|
||||||
|
b.CreateStaticInputParameter("play", b =>
|
||||||
|
{
|
||||||
|
b.CreateCommand(new NightbotSongQueueCommand(_api, "play", _logger));
|
||||||
|
})
|
||||||
|
.CreateStaticInputParameter("pause", b =>
|
||||||
|
{
|
||||||
|
b.CreateCommand(new NightbotSongQueueCommand(_api, "pause", _logger));
|
||||||
|
})
|
||||||
|
.CreateStaticInputParameter("skip", b =>
|
||||||
|
{
|
||||||
|
b.CreateCommand(new NightbotSongQueueCommand(_api, "skip", _logger));
|
||||||
|
})
|
||||||
|
.CreateStaticInputParameter("volume", b =>
|
||||||
|
{
|
||||||
|
b.CreateUnvalidatedParameter("volume")
|
||||||
|
.CreateCommand(new NightbotSongQueueCommand(_api, "volume", _logger));
|
||||||
|
})
|
||||||
|
.CreateStaticInputParameter("clear_playlist", b =>
|
||||||
|
{
|
||||||
|
b.CreateCommand(new NightbotSongQueueCommand(_api, "clear_playlist", _logger));
|
||||||
|
})
|
||||||
|
.CreateStaticInputParameter("clear_queue", b =>
|
||||||
|
{
|
||||||
|
b.CreateCommand(new NightbotSongQueueCommand(_api, "volume", _logger));
|
||||||
|
})
|
||||||
|
.CreateStaticInputParameter("clear", b =>
|
||||||
|
{
|
||||||
|
b.CreateStaticInputParameter("playlist", b => b.CreateCommand(new NightbotSongQueueCommand(_api, "clear_playlist", _logger)))
|
||||||
|
.CreateStaticInputParameter("queue", b => b.CreateCommand(new NightbotSongQueueCommand(_api, "clear_queue", _logger)));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class NightbotSongQueueCommand : IChatPartialCommand
|
||||||
|
{
|
||||||
|
private readonly NightbotApiClient _api;
|
||||||
|
private readonly string _command;
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
public bool AcceptCustomPermission { get => true; }
|
||||||
|
|
||||||
|
|
||||||
|
public NightbotSongQueueCommand(NightbotApiClient api, string command, ILogger logger)
|
||||||
|
{
|
||||||
|
_api = api;
|
||||||
|
_command = command.ToLower();
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Execute(IDictionary<string, string> values, ChannelChatMessage message, HermesSocketClient hermes)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_command == "play")
|
||||||
|
{
|
||||||
|
await _api.Play();
|
||||||
|
_logger.Information("Playing Nightbot song queue.");
|
||||||
|
}
|
||||||
|
else if (_command == "pause")
|
||||||
|
{
|
||||||
|
await _api.Pause();
|
||||||
|
_logger.Information("Playing Nightbot song queue.");
|
||||||
|
}
|
||||||
|
else if (_command == "skip")
|
||||||
|
{
|
||||||
|
await _api.Skip();
|
||||||
|
_logger.Information("Skipping Nightbot song queue.");
|
||||||
|
}
|
||||||
|
else if (_command == "volume")
|
||||||
|
{
|
||||||
|
int volume = int.Parse(values["volume"]);
|
||||||
|
await _api.Volume(volume);
|
||||||
|
_logger.Information($"Changed Nightbot volume to {volume}.");
|
||||||
|
}
|
||||||
|
else if (_command == "clear_playlist")
|
||||||
|
{
|
||||||
|
await _api.ClearPlaylist();
|
||||||
|
_logger.Information("Cleared Nightbot playlist.");
|
||||||
|
}
|
||||||
|
else if (_command == "clear_queue")
|
||||||
|
{
|
||||||
|
await _api.ClearQueue();
|
||||||
|
_logger.Information("Cleared Nightbot queue.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (HttpRequestException e)
|
||||||
|
{
|
||||||
|
_logger.Warning("Ensure your Nightbot account is linked to your TTS account.");
|
||||||
|
}
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (OverflowException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
using System.Net.Http.Formatting;
|
||||||
using System.Net.Http.Json;
|
using System.Net.Http.Json;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
@ -44,6 +45,11 @@ namespace TwitchChatTTS.Helpers
|
|||||||
return await _client.PostAsJsonAsync(uri, new object(), Options);
|
return await _client.PostAsJsonAsync(uri, new object(), Options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<HttpResponseMessage> Put<T>(string uri, T data)
|
||||||
|
{
|
||||||
|
return await _client.PutAsJsonAsync(uri, data, Options);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<T?> Delete<T>(string uri)
|
public async Task<T?> Delete<T>(string uri)
|
||||||
{
|
{
|
||||||
return await _client.DeleteFromJsonAsync<T>(uri, Options);
|
return await _client.DeleteFromJsonAsync<T>(uri, Options);
|
||||||
|
@ -8,12 +8,14 @@ namespace TwitchChatTTS.Hermes.Socket.Handlers
|
|||||||
public class LoginAckHandler : IWebSocketHandler
|
public class LoginAckHandler : IWebSocketHandler
|
||||||
{
|
{
|
||||||
private readonly User _user;
|
private readonly User _user;
|
||||||
|
private readonly NightbotApiClient _nightbot;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
public int OperationCode { get; } = 2;
|
public int OperationCode { get; } = 2;
|
||||||
|
|
||||||
public LoginAckHandler(User user, ILogger logger)
|
public LoginAckHandler(User user, NightbotApiClient nightbot, ILogger logger)
|
||||||
{
|
{
|
||||||
_user = user;
|
_user = user;
|
||||||
|
_nightbot = nightbot;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,32 +26,48 @@ namespace TwitchChatTTS.Hermes.Socket.Handlers
|
|||||||
if (sender is not HermesSocketClient client)
|
if (sender is not HermesSocketClient client)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (message.AnotherClient && client.LoggedIn)
|
if (message.AnotherClient)
|
||||||
{
|
{
|
||||||
_logger.Warning("Another client has connected to the same account.");
|
if (client.LoggedIn)
|
||||||
|
_logger.Warning($"Another client has connected to the same account via {(message.WebLogin ? "web login" : "application")}.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (client.LoggedIn)
|
if (client.LoggedIn)
|
||||||
{
|
{
|
||||||
_logger.Warning("Attempted to log in again while still logged in.");
|
_logger.Error("Attempted to log in again while still logged in.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_user.HermesUserId = message.UserId;
|
_user.HermesUserId = message.UserId;
|
||||||
_user.OwnerId = message.OwnerId;
|
_user.OwnerId = message.OwnerId;
|
||||||
|
_user.DefaultTTSVoice = message.DefaultTTSVoice;
|
||||||
|
_user.VoicesAvailable = message.TTSVoicesAvailable;
|
||||||
|
_user.RegexFilters = message.WordFilters.ToArray();
|
||||||
|
_user.VoicesEnabled = new HashSet<string>(message.EnabledTTSVoices);
|
||||||
|
_user.TwitchConnection = message.Connections.FirstOrDefault(c => c.Default && c.Type == "twitch");
|
||||||
|
_user.NightbotConnection = message.Connections.FirstOrDefault(c => c.Default && c.Type == "nightbot");
|
||||||
|
|
||||||
client.LoggedIn = true;
|
client.LoggedIn = true;
|
||||||
_logger.Information($"Logged in as {_user.TwitchUsername} {(message.WebLogin ? "via web" : "via TTS app")}.");
|
_logger.Information($"Logged in as {_user.TwitchUsername} {(message.WebLogin ? "via web" : "via TTS app")}.");
|
||||||
|
|
||||||
await client.FetchTTSVoices();
|
|
||||||
await client.FetchEnabledTTSVoices();
|
|
||||||
await client.FetchTTSWordFilters();
|
|
||||||
await client.FetchTTSChatterVoices();
|
await client.FetchTTSChatterVoices();
|
||||||
await client.FetchDefaultTTSVoice();
|
|
||||||
await client.FetchChatterIdentifiers();
|
await client.FetchChatterIdentifiers();
|
||||||
await client.FetchEmotes();
|
await client.FetchEmotes();
|
||||||
await client.FetchRedemptions();
|
await client.FetchRedemptions();
|
||||||
await client.FetchPermissions();
|
await client.FetchPermissions();
|
||||||
|
|
||||||
|
if (_user.NightbotConnection != null) {
|
||||||
|
_nightbot.Initialize(_user.NightbotConnection.ClientId, _user.NightbotConnection.AccessToken);
|
||||||
|
var span = DateTime.Now - _user.NightbotConnection.ExpiresAt;
|
||||||
|
var timeLeft = span.TotalDays >= 2 ? Math.Floor(span.TotalDays) + " days" : (span.TotalHours >= 2 ? Math.Floor(span.TotalHours) + " hours" : Math.Floor(span.TotalMinutes) + " minutes");
|
||||||
|
if (span.TotalDays >= 3)
|
||||||
|
_logger.Information($"Nightbot connection has {timeLeft} before it is revoked.");
|
||||||
|
else if (span.TotalMinutes >= 0)
|
||||||
|
_logger.Warning($"Nightbot connection has {timeLeft} before it is revoked. Refreshing the token is soon required.");
|
||||||
|
else
|
||||||
|
_logger.Error("Nightbot connection has its permissions revoked. Refresh the token. Anything related to Nightbot from this application will not work.");
|
||||||
|
}
|
||||||
|
|
||||||
_logger.Information("TTS is now ready.");
|
_logger.Information("TTS is now ready.");
|
||||||
client.Ready = true;
|
client.Ready = true;
|
||||||
}
|
}
|
||||||
|
60
Nightbot/NightbotApiClient.cs
Normal file
60
Nightbot/NightbotApiClient.cs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using TwitchChatTTS.Helpers;
|
||||||
|
using Serilog;
|
||||||
|
using TwitchChatTTS;
|
||||||
|
|
||||||
|
public class NightbotApiClient
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
private readonly WebClientWrap _web;
|
||||||
|
|
||||||
|
|
||||||
|
public NightbotApiClient(
|
||||||
|
ILogger logger
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
|
||||||
|
_web = new WebClientWrap(new JsonSerializerOptions()
|
||||||
|
{
|
||||||
|
PropertyNameCaseInsensitive = false,
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Play()
|
||||||
|
{
|
||||||
|
await _web.Post("https://api.nightbot.tv/1/song_requests/queue/play");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Pause()
|
||||||
|
{
|
||||||
|
await _web.Post("https://api.nightbot.tv/1/song_requests/queue/pause");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Skip()
|
||||||
|
{
|
||||||
|
await _web.Post("https://api.nightbot.tv/1/song_requests/queue/skip");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Volume(int volume)
|
||||||
|
{
|
||||||
|
await _web.Put("https://api.nightbot.tv/1/song_requests", new Dictionary<string, object>() { { "volume", volume } });
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ClearPlaylist()
|
||||||
|
{
|
||||||
|
await _web.Delete("https://api.nightbot.tv/1/song_requests/playlist");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ClearQueue()
|
||||||
|
{
|
||||||
|
await _web.Delete("https://api.nightbot.tv/1/song_requests/queue");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialize(string clientId, string accessToken)
|
||||||
|
{
|
||||||
|
_web.AddHeader("Authorization", "Bearer " + accessToken);
|
||||||
|
_web.AddHeader("Client-Id", clientId);
|
||||||
|
}
|
||||||
|
}
|
@ -69,6 +69,7 @@ s.AddSingleton(new JsonSerializerOptions()
|
|||||||
s.AddSingleton<IChatCommand, SkipCommand>();
|
s.AddSingleton<IChatCommand, SkipCommand>();
|
||||||
s.AddSingleton<IChatCommand, VoiceCommand>();
|
s.AddSingleton<IChatCommand, VoiceCommand>();
|
||||||
s.AddSingleton<IChatCommand, RefreshCommand>();
|
s.AddSingleton<IChatCommand, RefreshCommand>();
|
||||||
|
s.AddSingleton<IChatCommand, NightbotCommand>();
|
||||||
s.AddSingleton<IChatCommand, OBSCommand>();
|
s.AddSingleton<IChatCommand, OBSCommand>();
|
||||||
s.AddSingleton<IChatCommand, TTSCommand>();
|
s.AddSingleton<IChatCommand, TTSCommand>();
|
||||||
s.AddSingleton<IChatCommand, VersionCommand>();
|
s.AddSingleton<IChatCommand, VersionCommand>();
|
||||||
@ -107,6 +108,9 @@ s.AddKeyedSingleton<IWebSocketHandler, EndOfStreamHandler>("7tv");
|
|||||||
s.AddKeyedSingleton<MessageTypeManager<IWebSocketHandler>, SevenMessageTypeManager>("7tv");
|
s.AddKeyedSingleton<MessageTypeManager<IWebSocketHandler>, SevenMessageTypeManager>("7tv");
|
||||||
s.AddKeyedSingleton<SocketClient<WebSocketMessage>, SevenSocketClient>("7tv");
|
s.AddKeyedSingleton<SocketClient<WebSocketMessage>, SevenSocketClient>("7tv");
|
||||||
|
|
||||||
|
// Nightbot
|
||||||
|
s.AddSingleton<NightbotApiClient>();
|
||||||
|
|
||||||
// twitch websocket
|
// twitch websocket
|
||||||
s.AddKeyedSingleton<IBackoff>("twitch", new ExponentialBackoff(1000, 120 * 1000));
|
s.AddKeyedSingleton<IBackoff>("twitch", new ExponentialBackoff(1000, 120 * 1000));
|
||||||
s.AddSingleton<ITwitchConnectionManager, TwitchConnectionManager>();
|
s.AddSingleton<ITwitchConnectionManager, TwitchConnectionManager>();
|
||||||
|
@ -17,6 +17,7 @@ namespace TwitchChatTTS.Twitch.Redemptions
|
|||||||
private readonly User _user;
|
private readonly User _user;
|
||||||
private readonly OBSSocketClient _obs;
|
private readonly OBSSocketClient _obs;
|
||||||
private readonly HermesSocketClient _hermes;
|
private readonly HermesSocketClient _hermes;
|
||||||
|
private readonly NightbotApiClient _nightbot;
|
||||||
private readonly AudioPlaybackEngine _playback;
|
private readonly AudioPlaybackEngine _playback;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly Random _random;
|
private readonly Random _random;
|
||||||
@ -27,6 +28,7 @@ namespace TwitchChatTTS.Twitch.Redemptions
|
|||||||
User user,
|
User user,
|
||||||
[FromKeyedServices("obs")] SocketClient<WebSocketMessage> obs,
|
[FromKeyedServices("obs")] SocketClient<WebSocketMessage> obs,
|
||||||
[FromKeyedServices("hermes")] SocketClient<WebSocketMessage> hermes,
|
[FromKeyedServices("hermes")] SocketClient<WebSocketMessage> hermes,
|
||||||
|
NightbotApiClient nightbot,
|
||||||
AudioPlaybackEngine playback,
|
AudioPlaybackEngine playback,
|
||||||
ILogger logger)
|
ILogger logger)
|
||||||
{
|
{
|
||||||
@ -34,6 +36,7 @@ namespace TwitchChatTTS.Twitch.Redemptions
|
|||||||
_user = user;
|
_user = user;
|
||||||
_obs = (obs as OBSSocketClient)!;
|
_obs = (obs as OBSSocketClient)!;
|
||||||
_hermes = (hermes as HermesSocketClient)!;
|
_hermes = (hermes as HermesSocketClient)!;
|
||||||
|
_nightbot = nightbot;
|
||||||
_playback = playback;
|
_playback = playback;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_random = new Random();
|
_random = new Random();
|
||||||
@ -191,6 +194,21 @@ namespace TwitchChatTTS.Twitch.Redemptions
|
|||||||
_playback.PlaySound(action.Data["file_path"]);
|
_playback.PlaySound(action.Data["file_path"]);
|
||||||
_logger.Debug($"Played an audio file for channel point redeem [file: {action.Data["file_path"]}][chatter: {senderDisplayName}][chatter id: {senderId}]");
|
_logger.Debug($"Played an audio file for channel point redeem [file: {action.Data["file_path"]}][chatter: {senderDisplayName}][chatter id: {senderId}]");
|
||||||
break;
|
break;
|
||||||
|
case "NIGHTBOT_PLAY":
|
||||||
|
await _nightbot.Play();
|
||||||
|
break;
|
||||||
|
case "NIGHTBOT_PAUSE":
|
||||||
|
await _nightbot.Pause();
|
||||||
|
break;
|
||||||
|
case "NIGHTBOT_SKIP":
|
||||||
|
await _nightbot.Skip();
|
||||||
|
break;
|
||||||
|
case "NIGHTBOT_CLEAR_PLAYLIST":
|
||||||
|
await _nightbot.ClearPlaylist();
|
||||||
|
break;
|
||||||
|
case "NIGHTBOT_CLEAR_QUEUE":
|
||||||
|
await _nightbot.ClearQueue();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
_logger.Warning($"Unknown redeemable action has occured. Update needed? [type: {action.Type}][chatter: {senderDisplayName}][chatter id: {senderId}]");
|
_logger.Warning($"Unknown redeemable action has occured. Update needed? [type: {action.Type}][chatter: {senderDisplayName}][chatter id: {senderId}]");
|
||||||
break;
|
break;
|
||||||
|
@ -7,14 +7,12 @@ namespace TwitchChatTTS.Twitch.Socket.Handlers
|
|||||||
{
|
{
|
||||||
public string Name => "session_welcome";
|
public string Name => "session_welcome";
|
||||||
|
|
||||||
private readonly HermesApiClient _hermes;
|
|
||||||
private readonly TwitchApiClient _api;
|
private readonly TwitchApiClient _api;
|
||||||
private readonly User _user;
|
private readonly User _user;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
public SessionWelcomeHandler(HermesApiClient hermes, TwitchApiClient api, User user, ILogger logger)
|
public SessionWelcomeHandler(TwitchApiClient api, User user, ILogger logger)
|
||||||
{
|
{
|
||||||
_hermes = hermes;
|
|
||||||
_api = api;
|
_api = api;
|
||||||
_user = user;
|
_user = user;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
@ -32,18 +30,24 @@ namespace TwitchChatTTS.Twitch.Socket.Handlers
|
|||||||
}
|
}
|
||||||
|
|
||||||
int waited = 0;
|
int waited = 0;
|
||||||
while (_user.TwitchUserId <= 0 && ++waited < 3)
|
while ((_user.TwitchUserId <= 0 || _user.TwitchConnection == null) && ++waited < 5)
|
||||||
await Task.Delay(TimeSpan.FromSeconds(1));
|
await Task.Delay(TimeSpan.FromSeconds(1));
|
||||||
|
|
||||||
try
|
if (_user.TwitchConnection == null)
|
||||||
{
|
{
|
||||||
await _hermes.AuthorizeTwitch();
|
_logger.Error("Ensure you have linked either your Twitch account or TTS' bot to your TTS account. Twitch client will not be connecting.");
|
||||||
var token = await _hermes.FetchTwitchBotToken();
|
return;
|
||||||
_api.Initialize(token);
|
|
||||||
}
|
}
|
||||||
catch (Exception)
|
|
||||||
{
|
_api.Initialize(_user.TwitchConnection.ClientId, _user.TwitchConnection.AccessToken);
|
||||||
_logger.Error("Ensure you have your Twitch account linked on TTS. Restart application once you do.");
|
var span = DateTime.Now - _user.TwitchConnection.ExpiresAt;
|
||||||
|
var timeLeft = span.TotalDays >= 2 ? Math.Floor(span.TotalDays) + " days" : (span.TotalHours >= 2 ? Math.Floor(span.TotalHours) + " hours" : Math.Floor(span.TotalMinutes) + " minutes");
|
||||||
|
if (span.TotalDays >= 3)
|
||||||
|
_logger.Information($"Twitch connection has {timeLeft} before it is revoked.");
|
||||||
|
else if (span.TotalMinutes >= 0)
|
||||||
|
_logger.Warning($"Twitch connection has {timeLeft} before it is revoked. Refreshing the token is soon required.");
|
||||||
|
else {
|
||||||
|
_logger.Error("Twitch connection has its permissions revoked. Refresh the token. Twith client will not be connecting.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +92,7 @@ namespace TwitchChatTTS.Twitch.Socket.Handlers
|
|||||||
await Subscribe(sender, subscription, message.Session.Id, broadcasterId, "1");
|
await Subscribe(sender, subscription, message.Session.Id, broadcasterId, "1");
|
||||||
foreach (var subscription in subscriptionsv2)
|
foreach (var subscription in subscriptionsv2)
|
||||||
await Subscribe(sender, subscription, message.Session.Id, broadcasterId, "2");
|
await Subscribe(sender, subscription, message.Session.Id, broadcasterId, "2");
|
||||||
|
|
||||||
await Subscribe(sender, "channel.raid", broadcasterId, async () => await _api.CreateChannelRaidEventSubscription("1", message.Session.Id, to: broadcasterId));
|
await Subscribe(sender, "channel.raid", broadcasterId, async () => await _api.CreateChannelRaidEventSubscription("1", message.Session.Id, to: broadcasterId));
|
||||||
|
|
||||||
sender.Identify(message.Session.Id);
|
sender.Identify(message.Session.Id);
|
||||||
|
@ -95,9 +95,9 @@ public class TwitchApiClient
|
|||||||
return await _web.GetJson<EventResponse<NotificationInfo>>("https://api.twitch.tv/helix/eventsub/subscriptions" + query);
|
return await _web.GetJson<EventResponse<NotificationInfo>>("https://api.twitch.tv/helix/eventsub/subscriptions" + query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(TwitchBotToken token)
|
public void Initialize(string clientId, string accessToken)
|
||||||
{
|
{
|
||||||
_web.AddHeader("Authorization", "Bearer " + token.AccessToken);
|
_web.AddHeader("Authorization", "Bearer " + accessToken);
|
||||||
_web.AddHeader("Client-Id", token.ClientId);
|
_web.AddHeader("Client-Id", clientId);
|
||||||
}
|
}
|
||||||
}
|
}
|
4
User.cs
4
User.cs
@ -1,6 +1,7 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using HermesSocketLibrary.Requests.Messages;
|
using HermesSocketLibrary.Requests.Messages;
|
||||||
|
using HermesSocketLibrary.Socket.Data;
|
||||||
using TwitchChatTTS.Twitch.Socket.Handlers;
|
using TwitchChatTTS.Twitch.Socket.Handlers;
|
||||||
|
|
||||||
namespace TwitchChatTTS
|
namespace TwitchChatTTS
|
||||||
@ -15,6 +16,9 @@ namespace TwitchChatTTS
|
|||||||
public string SevenEmoteSetId { get; set; }
|
public string SevenEmoteSetId { get; set; }
|
||||||
public long? OwnerId { get; set; }
|
public long? OwnerId { get; set; }
|
||||||
|
|
||||||
|
public Connection? TwitchConnection { get; set; }
|
||||||
|
public Connection? NightbotConnection { get; set; }
|
||||||
|
|
||||||
public string DefaultTTSVoice { get; set; }
|
public string DefaultTTSVoice { get; set; }
|
||||||
// voice id -> voice name
|
// voice id -> voice name
|
||||||
public IDictionary<string, string> VoicesAvailable { get => _voicesAvailable; set { _voicesAvailable = value; VoiceNameRegex = GenerateEnabledVoicesRegex(); } }
|
public IDictionary<string, string> VoicesAvailable { get => _voicesAvailable; set { _voicesAvailable = value; VoiceNameRegex = GenerateEnabledVoicesRegex(); } }
|
||||||
|
Loading…
Reference in New Issue
Block a user