private async Task TwitchHandshake(ClientWebSocket webSocket, CancellationToken cancellationToken) { var token = await twitchService.GetToken(); if (token == null) { await dashboardService.UpdateStatus(ApiSource.Twitch, BackgroundServiceStatus.Forbidden, cancellationToken); return; } if (token.Status == AccessTokenStatus.Expired && token.HasRefreshToken) { await twitchService.RefreshToken(token); } if (token.Status != AccessTokenStatus.Ok) { await dashboardService.UpdateStatus(ApiSource.Twitch, BackgroundServiceStatus.Forbidden, cancellationToken); return; } await Send(webSocket, cancellationToken, $"PASS oauth:{token.access_token}"); await Send(webSocket, cancellationToken, $"NICK machacoder"); // TODO: get nick from twitch API }
protected override async Task ExecuteAsync(CancellationToken cancellationToken) { pollingInterval = minimumPollingInterval; delay = defaultDelay; cancellationToken.Register(() => { logger.LogDebug($"YoutubeBackgroundService background task is stopping."); }); using (var scope = serviceScopeFactory.CreateScope()) { youtubeService = scope.ServiceProvider.GetRequiredService <YoutubeService>(); chatService = scope.ServiceProvider.GetRequiredService <ChatService>(); dashboardService = scope.ServiceProvider.GetRequiredService <DashboardService>(); while (!cancellationToken.IsCancellationRequested) { try { if (!youtubeService.IsEnabled().Result) { await dashboardService.UpdateStatus(ApiSource.Youtube, BackgroundServiceStatus.Disabled, cancellationToken); await Task.Delay(delay, cancellationToken); continue; } if (!youtubeService.IsConfigured()) { await dashboardService.UpdateStatus(ApiSource.Youtube, BackgroundServiceStatus.NotConfigured, cancellationToken); await Task.Delay(delay, cancellationToken); continue; } var token = await youtubeService.GetToken(); if (token == null) { await dashboardService.UpdateStatus(ApiSource.Youtube, BackgroundServiceStatus.Forbidden, cancellationToken); await Task.Delay(delay, cancellationToken); continue; } if (token.Status == AccessTokenStatus.Expired && token.HasRefreshToken) { await youtubeService.RefreshToken(token); } if (!youtubeService.IsValidToken(token)) { await dashboardService.UpdateStatus(ApiSource.Youtube, BackgroundServiceStatus.Forbidden, cancellationToken); await Task.Delay(delay, cancellationToken); continue; } while (!cancellationToken.IsCancellationRequested && youtubeService.IsEnabled().Result) { if (string.IsNullOrEmpty(liveChatId)) { var liveBroadcast = await youtubeService.GetLiveBroadcast(); if (liveBroadcast == null) { await dashboardService.UpdateStatus(ApiSource.Youtube, BackgroundServiceStatus.Offline, cancellationToken); await Task.Delay(delay, cancellationToken); continue; } liveChatId = liveBroadcast.snippet.liveChatId; } var liveChatMessages = await youtubeService.GetLiveChatMessages(liveChatId); await dashboardService.UpdateStatus(ApiSource.Youtube, BackgroundServiceStatus.Connected, cancellationToken); if (liveChatMessages == null || !liveChatMessages.items.Any()) { await Task.Delay(TimeSpan.FromMilliseconds(pollingInterval), cancellationToken); continue; } foreach (var item in liveChatMessages.items) { await chatService.CreateMessage(youtubeService.MapToChatMessage(item)); } pollingInterval = Math.Max(liveChatMessages.pollingIntervalMillis, minimumPollingInterval); await Task.Delay(pollingInterval, cancellationToken); } await dashboardService.UpdateStatus(ApiSource.Youtube, BackgroundServiceStatus.Stopped, cancellationToken); } catch (Exception ex) { logger.LogError(ex.GetBaseException(), ex.GetBaseException().Message); await dashboardService.UpdateStatus(ApiSource.Youtube, BackgroundServiceStatus.Error, cancellationToken); } await Task.Delay(delay, cancellationToken); } } }
protected override async Task ExecuteAsync(CancellationToken cancellationToken) { cancellationToken.Register(() => { logger.LogDebug($"TwitchBackgroundService background task is stopping."); }); delay = defaultDelay; using (var scope = serviceScopeFactory.CreateScope()) { twitchService = scope.ServiceProvider.GetRequiredService <TwitchService>(); dashboardService = scope.ServiceProvider.GetRequiredService <DashboardService>(); while (!cancellationToken.IsCancellationRequested) { try { if (!await twitchService.IsEnabled()) { await dashboardService.UpdateStatus(ApiSource.Twitch, BackgroundServiceStatus.Disabled, cancellationToken); await Task.Delay(delay, cancellationToken); continue; } if (!twitchService.IsConfigured()) { await dashboardService.UpdateStatus(ApiSource.Twitch, BackgroundServiceStatus.NotConfigured, cancellationToken); await Task.Delay(delay, cancellationToken); continue; } var webSocket = new ClientWebSocket(); if (webSocket.State != WebSocketState.Open) { await webSocket.ConnectAsync(new Uri("wss://irc-ws.chat.twitch.tv:443"), cancellationToken); var timeout = 0; while (webSocket.State == WebSocketState.Connecting && timeout < connectionTimeout && !cancellationToken.IsCancellationRequested) { await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); timeout++; } if (webSocket.State == WebSocketState.Open) { await TwitchHandshake(webSocket, cancellationToken); } } while (!cancellationToken.IsCancellationRequested && await twitchService.IsEnabled()) { await dashboardService.UpdateStatus(ApiSource.Twitch, BackgroundServiceStatus.Connected, cancellationToken); await Send(webSocket, cancellationToken, "JOIN :#machacoder"); await Receive(webSocket, cancellationToken); } } catch (Exception ex) { logger.LogError(ex.GetBaseException(), ex.GetBaseException().Message); await dashboardService.UpdateStatus(ApiSource.Twitch, "Error", cancellationToken); } await Task.Delay(delay, cancellationToken); } } }