public override async Task OnSent(HttpSentContext context) { if (!FollowValidtor(context)) { return; } var uri = context.Uri; var locationUri = GetLocationUri(uri, context.Result); var ctx = new FollowLocationContext { StatusCode = context.Result.StatusCode, RequestMessage = context.Result.RequestMessage, LocationUri = locationUri, CurrentUri = uri }; if (ctx.LocationUri == null) { return; } OnFollow?.Invoke(ctx); if (!ctx.ShouldFollow) { return; } context.Builder.WithUri(ctx.LocationUri).AsGet().WithContent(string.Empty); // dispose of previous response ObjectHelpers.Dispose(context.Result); context.Result = await context.Builder.RecursiveResultAsync(context.Token); }
/// <summary> /// Parses the message. /// </summary> /// <param name="message">The message.</param> private void ParseMessage(string message) { var type = JObject.Parse(message).SelectToken("type")?.ToString(); switch (type?.ToLower()) { case "response": var resp = new Models.Responses.Response(message); if (_previousRequests.Count != 0) { bool handled = false; _previousRequestsSemaphore.WaitOne(); try { for (int i = 0; i < _previousRequests.Count;) { var request = _previousRequests[i]; if (string.Equals(request.Nonce, resp.Nonce, StringComparison.CurrentCulture)) { //Remove the request. _previousRequests.RemoveAt(i); _topicToChannelId.TryGetValue(request.Topic, out var requestChannelId); OnListenResponse?.Invoke(this, new OnListenResponseArgs { Response = resp, Topic = request.Topic, Successful = resp.Successful, ChannelId = requestChannelId }); handled = true; } else { i++; } } } finally { _previousRequestsSemaphore.Release(); } if (handled) { return; } } break; case "message": var msg = new Models.Responses.Message(message); _topicToChannelId.TryGetValue(msg.Topic, out var channelId); channelId = channelId ?? ""; switch (msg.Topic.Split('.')[0]) { case "user-moderation-notifications": var userModerationNotifications = msg.MessageData as UserModerationNotifications; switch (userModerationNotifications.Type) { case UserModerationNotificationsType.AutomodCaughtMessage: var automodCaughtMessage = userModerationNotifications.Data as Models.Responses.Messages.UserModerationNotificationsTypes.AutomodCaughtMessage; OnAutomodCaughtUserMessage?.Invoke(this, new OnAutomodCaughtUserMessage { ChannelId = channelId, UserId = msg.Topic.Split('.')[2], AutomodCaughtMessage = automodCaughtMessage }); break; case UserModerationNotificationsType.Unknown: break; } return; case "automod-queue": var automodQueue = msg.MessageData as AutomodQueue; switch (automodQueue.Type) { case AutomodQueueType.CaughtMessage: var caughtMessage = automodQueue.Data as AutomodCaughtMessage; OnAutomodCaughtMessage?.Invoke(this, new OnAutomodCaughtMessageArgs { ChannelId = channelId, AutomodCaughtMessage = caughtMessage }); break; case AutomodQueueType.Unknown: UnaccountedFor($"Unknown automod queue type. Msg: {automodQueue.RawData}"); break; } return; case "channel-subscribe-events-v1": var subscription = msg.MessageData as ChannelSubscription; OnChannelSubscription?.Invoke(this, new OnChannelSubscriptionArgs { Subscription = subscription, ChannelId = channelId }); return; case "whispers": var whisper = (Whisper)msg.MessageData; OnWhisper?.Invoke(this, new OnWhisperArgs { Whisper = whisper, ChannelId = channelId }); return; case "chat_moderator_actions": var cma = msg.MessageData as ChatModeratorActions; var reason = ""; switch (cma?.ModerationAction.ToLower()) { case "timeout": if (cma.Args.Count > 2) { reason = cma.Args[2]; } OnTimeout?.Invoke(this, new OnTimeoutArgs { TimedoutBy = cma.CreatedBy, TimedoutById = cma.CreatedByUserId, TimedoutUserId = cma.TargetUserId, TimeoutDuration = TimeSpan.FromSeconds(int.Parse(cma.Args[1])), TimeoutReason = reason, TimedoutUser = cma.Args[0], ChannelId = channelId }); return; case "ban": if (cma.Args.Count > 1) { reason = cma.Args[1]; } OnBan?.Invoke(this, new OnBanArgs { BannedBy = cma.CreatedBy, BannedByUserId = cma.CreatedByUserId, BannedUserId = cma.TargetUserId, BanReason = reason, BannedUser = cma.Args[0], ChannelId = channelId }); return; case "delete": OnMessageDeleted?.Invoke(this, new OnMessageDeletedArgs { DeletedBy = cma.CreatedBy, DeletedByUserId = cma.CreatedByUserId, TargetUserId = cma.TargetUserId, TargetUser = cma.Args[0], Message = cma.Args[1], MessageId = cma.Args[2], ChannelId = channelId }); return; case "unban": OnUnban?.Invoke(this, new OnUnbanArgs { UnbannedBy = cma.CreatedBy, UnbannedByUserId = cma.CreatedByUserId, UnbannedUserId = cma.TargetUserId, UnbannedUser = cma.Args[0], ChannelId = channelId }); return; case "untimeout": OnUntimeout?.Invoke(this, new OnUntimeoutArgs { UntimeoutedBy = cma.CreatedBy, UntimeoutedByUserId = cma.CreatedByUserId, UntimeoutedUserId = cma.TargetUserId, UntimeoutedUser = cma.Args[0], ChannelId = channelId }); return; case "host": OnHost?.Invoke(this, new OnHostArgs { HostedChannel = cma.Args[0], Moderator = cma.CreatedBy, ChannelId = channelId }); return; case "subscribers": OnSubscribersOnly?.Invoke(this, new OnSubscribersOnlyArgs { Moderator = cma.CreatedBy, ChannelId = channelId }); return; case "subscribersoff": OnSubscribersOnlyOff?.Invoke(this, new OnSubscribersOnlyOffArgs { Moderator = cma.CreatedBy, ChannelId = channelId }); return; case "clear": OnClear?.Invoke(this, new OnClearArgs { Moderator = cma.CreatedBy, ChannelId = channelId }); return; case "emoteonly": OnEmoteOnly?.Invoke(this, new OnEmoteOnlyArgs { Moderator = cma.CreatedBy, ChannelId = channelId }); return; case "emoteonlyoff": OnEmoteOnlyOff?.Invoke(this, new OnEmoteOnlyOffArgs { Moderator = cma.CreatedBy, ChannelId = channelId }); return; case "r9kbeta": OnR9kBeta?.Invoke(this, new OnR9kBetaArgs { Moderator = cma.CreatedBy, ChannelId = channelId }); return; case "r9kbetaoff": OnR9kBetaOff?.Invoke(this, new OnR9kBetaOffArgs { Moderator = cma.CreatedBy, ChannelId = channelId }); return; } break; case "channel-bits-events-v1": if (msg.MessageData is ChannelBitsEvents cbe) { OnBitsReceived?.Invoke(this, new OnBitsReceivedArgs { BitsUsed = cbe.BitsUsed, ChannelId = cbe.ChannelId, ChannelName = cbe.ChannelName, ChatMessage = cbe.ChatMessage, Context = cbe.Context, Time = cbe.Time, TotalBitsUsed = cbe.TotalBitsUsed, UserId = cbe.UserId, Username = cbe.Username }); return; } break; case "channel-bits-events-v2": if (msg.MessageData is ChannelBitsEventsV2 cbev2) { OnBitsReceivedV2?.Invoke(this, new OnBitsReceivedV2Args { IsAnonymous = cbev2.IsAnonymous, BitsUsed = cbev2.BitsUsed, ChannelId = cbev2.ChannelId, ChannelName = cbev2.ChannelName, ChatMessage = cbev2.ChatMessage, Context = cbev2.Context, Time = cbev2.Time, TotalBitsUsed = cbev2.TotalBitsUsed, UserId = cbev2.UserId, UserName = cbev2.UserName }); return; } break; case "channel-commerce-events-v1": if (msg.MessageData is ChannelCommerceEvents cce) { OnChannelCommerceReceived?.Invoke(this, new OnChannelCommerceReceivedArgs { Username = cce.Username, DisplayName = cce.DisplayName, ChannelName = cce.ChannelName, UserId = cce.UserId, ChannelId = cce.ChannelId, Time = cce.Time, ItemImageURL = cce.ItemImageURL, ItemDescription = cce.ItemDescription, SupportsChannel = cce.SupportsChannel, PurchaseMessage = cce.PurchaseMessage }); return; } break; case "channel-ext-v1": var cEB = msg.MessageData as ChannelExtensionBroadcast; OnChannelExtensionBroadcast?.Invoke(this, new OnChannelExtensionBroadcastArgs { Messages = cEB.Messages, ChannelId = channelId }); return; case "video-playback-by-id": var vP = msg.MessageData as VideoPlayback; switch (vP?.Type) { case VideoPlaybackType.StreamDown: OnStreamDown?.Invoke(this, new OnStreamDownArgs { ServerTime = vP.ServerTime, ChannelId = channelId }); return; case VideoPlaybackType.StreamUp: OnStreamUp?.Invoke(this, new OnStreamUpArgs { PlayDelay = vP.PlayDelay, ServerTime = vP.ServerTime, ChannelId = channelId }); return; case VideoPlaybackType.ViewCount: OnViewCount?.Invoke(this, new OnViewCountArgs { ServerTime = vP.ServerTime, Viewers = vP.Viewers, ChannelId = channelId }); return; case VideoPlaybackType.Commercial: OnCommercial?.Invoke(this, new OnCommercialArgs { ServerTime = vP.ServerTime, Length = vP.Length, ChannelId = channelId }); return; } break; case "following": var f = (Following)msg.MessageData; f.FollowedChannelId = msg.Topic.Split('.')[1]; OnFollow?.Invoke(this, new OnFollowArgs { FollowedChannelId = f.FollowedChannelId, DisplayName = f.DisplayName, UserId = f.UserId, Username = f.Username }); return; case "community-points-channel-v1": var cpc = msg.MessageData as CommunityPointsChannel; switch (cpc?.Type) { case CommunityPointsChannelType.RewardRedeemed: OnRewardRedeemed?.Invoke(this, new OnRewardRedeemedArgs { TimeStamp = cpc.TimeStamp, ChannelId = cpc.ChannelId, Login = cpc.Login, DisplayName = cpc.DisplayName, Message = cpc.Message, RewardId = cpc.RewardId, RewardTitle = cpc.RewardTitle, RewardPrompt = cpc.RewardPrompt, RewardCost = cpc.RewardCost, Status = cpc.Status, RedemptionId = cpc.RedemptionId }); return; case CommunityPointsChannelType.CustomRewardUpdated: OnCustomRewardUpdated?.Invoke(this, new OnCustomRewardUpdatedArgs { TimeStamp = cpc.TimeStamp, ChannelId = cpc.ChannelId, RewardId = cpc.RewardId, RewardTitle = cpc.RewardTitle, RewardPrompt = cpc.RewardPrompt, RewardCost = cpc.RewardCost }); return; case CommunityPointsChannelType.CustomRewardCreated: OnCustomRewardCreated?.Invoke(this, new OnCustomRewardCreatedArgs { TimeStamp = cpc.TimeStamp, ChannelId = cpc.ChannelId, RewardId = cpc.RewardId, RewardTitle = cpc.RewardTitle, RewardPrompt = cpc.RewardPrompt, RewardCost = cpc.RewardCost }); return; case CommunityPointsChannelType.CustomRewardDeleted: OnCustomRewardDeleted?.Invoke(this, new OnCustomRewardDeletedArgs { TimeStamp = cpc.TimeStamp, ChannelId = cpc.ChannelId, RewardId = cpc.RewardId, RewardTitle = cpc.RewardTitle, RewardPrompt = cpc.RewardPrompt }); return; } return; case "channel-points-channel-v1": var channelPointsChannel = msg.MessageData as ChannelPointsChannel; switch (channelPointsChannel.Type) { case ChannelPointsChannelType.RewardRedeemed: var rewardRedeemed = channelPointsChannel.Data as RewardRedeemed; OnChannelPointsRewardRedeemed?.Invoke(this, new OnChannelPointsRewardRedeemedArgs { ChannelId = rewardRedeemed.Redemption.ChannelId, RewardRedeemed = rewardRedeemed }); break; case ChannelPointsChannelType.Unknown: UnaccountedFor($"Unknown channel points type. Msg: {channelPointsChannel.RawData}"); break; } return; case "leaderboard-events-v1": var lbe = msg.MessageData as LeaderboardEvents; switch (lbe?.Type) { case LeaderBoardType.BitsUsageByChannel: OnLeaderboardBits?.Invoke(this, new OnLeaderboardEventArgs { ChannelId = lbe.ChannelId, TopList = lbe.Top }); return; case LeaderBoardType.SubGiftSent: OnLeaderboardSubs?.Invoke(this, new OnLeaderboardEventArgs { ChannelId = lbe.ChannelId, TopList = lbe.Top }); return; } return; case "raid": var r = msg.MessageData as RaidEvents; switch (r?.Type) { case RaidType.RaidUpdate: OnRaidUpdate?.Invoke(this, new OnRaidUpdateArgs { Id = r.Id, ChannelId = r.ChannelId, TargetChannelId = r.TargetChannelId, AnnounceTime = r.AnnounceTime, RaidTime = r.RaidTime, RemainingDurationSeconds = r.RemainigDurationSeconds, ViewerCount = r.ViewerCount }); return; case RaidType.RaidUpdateV2: OnRaidUpdateV2?.Invoke(this, new OnRaidUpdateV2Args { Id = r.Id, ChannelId = r.ChannelId, TargetChannelId = r.TargetChannelId, TargetLogin = r.TargetLogin, TargetDisplayName = r.TargetDisplayName, TargetProfileImage = r.TargetProfileImage, ViewerCount = r.ViewerCount }); return; case RaidType.RaidGo: OnRaidGo?.Invoke(this, new OnRaidGoArgs { Id = r.Id, ChannelId = r.ChannelId, TargetChannelId = r.TargetChannelId, TargetLogin = r.TargetLogin, TargetDisplayName = r.TargetDisplayName, TargetProfileImage = r.TargetProfileImage, ViewerCount = r.ViewerCount }); return; } return; case "predictions-channel-v1": var pred = msg.MessageData as PredictionEvents; switch (pred?.Type) { case PredictionType.EventCreated: OnPrediction?.Invoke(this, new OnPredictionArgs { CreatedAt = pred.CreatedAt, Title = pred.Title, ChannelId = pred.ChannelId, EndedAt = pred.EndedAt, Id = pred.Id, Outcomes = pred.Outcomes, LockedAt = pred.LockedAt, PredictionTime = pred.PredictionTime, Status = pred.Status, WinningOutcomeId = pred.WinningOutcomeId, Type = pred.Type }); return; case PredictionType.EventUpdated: OnPrediction?.Invoke(this, new OnPredictionArgs { CreatedAt = pred.CreatedAt, Title = pred.Title, ChannelId = pred.ChannelId, EndedAt = pred.EndedAt, Id = pred.Id, Outcomes = pred.Outcomes, LockedAt = pred.LockedAt, PredictionTime = pred.PredictionTime, Status = pred.Status, WinningOutcomeId = pred.WinningOutcomeId, Type = pred.Type }); return; case null: UnaccountedFor("Prediction Type: null"); break; default: UnaccountedFor($"Prediction Type: {pred.Type}"); break; } return; } break; case "pong": _pongReceived = true; return; case "reconnect": _socket.Close(); break; } UnaccountedFor(message); }
public PubSub(EndPoint proxy = null) : base(null) { ThreadDispatcher.EnsureCreated(); base.OnPubSubServiceConnected += ((object sender, EventArgs e) => { ThreadDispatcher.Enqueue(() => OnPubSubServiceConnected?.Invoke(sender, e)); }); base.OnPubSubServiceError += ((object sender, OnPubSubServiceErrorArgs e) => { ThreadDispatcher.Enqueue(() => OnPubSubServiceError?.Invoke(sender, e)); }); base.OnPubSubServiceClosed += ((object sender, EventArgs e) => { ThreadDispatcher.Enqueue(() => OnPubSubServiceClosed?.Invoke(sender, e)); }); base.OnListenResponse += ((object sender, OnListenResponseArgs e) => { ThreadDispatcher.Enqueue(() => OnListenResponse?.Invoke(sender, e)); }); base.OnTimeout += ((object sender, OnTimeoutArgs e) => { ThreadDispatcher.Enqueue(() => OnTimeout?.Invoke(sender, e)); }); base.OnBan += ((object sender, OnBanArgs e) => { ThreadDispatcher.Enqueue(() => OnBan?.Invoke(sender, e)); }); base.OnUnban += ((object sender, OnUnbanArgs e) => { ThreadDispatcher.Enqueue(() => OnUnban?.Invoke(sender, e)); }); base.OnUntimeout += ((object sender, OnUntimeoutArgs e) => { ThreadDispatcher.Enqueue(() => OnUntimeout?.Invoke(sender, e)); }); base.OnHost += ((object sender, OnHostArgs e) => { ThreadDispatcher.Enqueue(() => OnHost?.Invoke(sender, e)); }); base.OnSubscribersOnly += ((object sender, OnSubscribersOnlyArgs e) => { ThreadDispatcher.Enqueue(() => OnSubscribersOnly?.Invoke(sender, e)); }); base.OnSubscribersOnlyOff += ((object sender, OnSubscribersOnlyOffArgs e) => { ThreadDispatcher.Enqueue(() => OnSubscribersOnlyOff?.Invoke(sender, e)); }); base.OnClear += ((object sender, OnClearArgs e) => { ThreadDispatcher.Enqueue(() => OnClear?.Invoke(sender, e)); }); base.OnEmoteOnly += ((object sender, OnEmoteOnlyArgs e) => { ThreadDispatcher.Enqueue(() => OnEmoteOnly?.Invoke(sender, e)); }); base.OnEmoteOnlyOff += ((object sender, OnEmoteOnlyOffArgs e) => { ThreadDispatcher.Enqueue(() => OnEmoteOnlyOff?.Invoke(sender, e)); }); base.OnR9kBeta += ((object sender, OnR9kBetaArgs e) => { ThreadDispatcher.Enqueue(() => OnR9kBeta?.Invoke(sender, e)); }); base.OnR9kBetaOff += ((object sender, OnR9kBetaOffArgs e) => { ThreadDispatcher.Enqueue(() => OnR9kBetaOff?.Invoke(sender, e)); }); base.OnBitsReceived += ((object sender, OnBitsReceivedArgs e) => { ThreadDispatcher.Enqueue(() => OnBitsReceived?.Invoke(sender, e)); }); base.OnStreamUp += ((object sender, OnStreamUpArgs arg) => { ThreadDispatcher.Enqueue(() => OnStreamUp(sender, arg)); }); base.OnStreamDown += ((object sender, OnStreamDownArgs e) => { ThreadDispatcher.Enqueue(() => OnStreamDown?.Invoke(sender, e)); }); base.OnViewCount += ((object sender, OnViewCountArgs e) => { ThreadDispatcher.Enqueue(() => OnViewCount?.Invoke(sender, e)); }); base.OnWhisper += ((object sender, OnWhisperArgs e) => { ThreadDispatcher.Enqueue(() => OnWhisper?.Invoke(sender, e)); }); base.OnChannelSubscription += ((object sender, OnChannelSubscriptionArgs e) => { ThreadDispatcher.Enqueue(() => OnChannelSubscription?.Invoke(sender, e)); }); base.OnChannelCommerceReceived += ((object sender, OnChannelCommerceReceivedArgs e) => { ThreadDispatcher.Enqueue(() => OnChannelCommerceReceived?.Invoke(sender, e)); }); base.OnChannelExtensionBroadcast += ((object sender, OnChannelExtensionBroadcastArgs e) => { ThreadDispatcher.Enqueue(() => OnChannelExtensionBroadcast?.Invoke(sender, e)); }); base.OnFollow += ((object sender, OnFollowArgs e) => { ThreadDispatcher.Enqueue(() => OnFollow?.Invoke(sender, e)); }); base.OnCustomRewardCreated += ((object sender, OnCustomRewardCreatedArgs e) => { ThreadDispatcher.Enqueue(() => OnCustomRewardCreated?.Invoke(sender, e)); }); base.OnCustomRewardUpdated += ((object sender, OnCustomRewardUpdatedArgs e) => { ThreadDispatcher.Enqueue(() => OnCustomRewardUpdated?.Invoke(sender, e)); }); base.OnCustomRewardDeleted += ((object sender, OnCustomRewardDeletedArgs e) => { ThreadDispatcher.Enqueue(() => OnCustomRewardDeleted?.Invoke(sender, e)); }); base.OnRewardRedeemed += ((object sender, OnRewardRedeemedArgs e) => { ThreadDispatcher.Enqueue(() => OnRewardRedeemed?.Invoke(sender, e)); }); base.OnBitsReceivedV2 += ((object sender, OnBitsReceivedV2Args e) => { ThreadDispatcher.Enqueue(() => OnBitsReceivedV2?.Invoke(sender, e)); }); base.OnLeaderboardSubs += ((object sender, OnLeaderboardEventArgs e) => { ThreadDispatcher.Enqueue(() => OnLeaderboardSubs?.Invoke(sender, e)); }); base.OnLeaderboardBits += ((object sender, OnLeaderboardEventArgs e) => { ThreadDispatcher.Enqueue(() => OnLeaderboardBits?.Invoke(sender, e)); }); base.OnRaidUpdate += ((object sender, OnRaidUpdateArgs e) => { ThreadDispatcher.Enqueue(() => OnRaidUpdate?.Invoke(sender, e)); }); base.OnRaidUpdateV2 += ((object sender, OnRaidUpdateV2Args e) => { ThreadDispatcher.Enqueue(() => OnRaidUpdateV2?.Invoke(sender, e)); }); base.OnRaidGo += ((object sender, OnRaidGoArgs e) => { ThreadDispatcher.Enqueue(() => OnRaidGo?.Invoke(sender, e)); }); base.OnMessageDeleted += ((object sender, OnMessageDeletedArgs e) => { ThreadDispatcher.Enqueue(() => OnMessageDeleted?.Invoke(sender, e)); }); base.OnLog += ((object sender, OnLogArgs e) => { ThreadDispatcher.Enqueue(() => OnLog?.Invoke(sender, e)); }); base.OnCommercial += ((object sender, OnCommercialArgs e) => { ThreadDispatcher.Enqueue(() => OnCommercial?.Invoke(sender, e)); }); base.OnPrediction += ((object sender, OnPredictionArgs e) => { ThreadDispatcher.Enqueue(() => OnPrediction?.Invoke(sender, e)); }); }
/// <summary> /// Parses the message. /// </summary> /// <param name="message">The message.</param> private void ParseMessage(string message) { var type = JObject.Parse(message).SelectToken("type")?.ToString(); switch (type?.ToLower()) { case "response": var resp = new Models.Responses.Response(message); if (_previousRequests.Count != 0) { bool handled = false; foreach (var request in _previousRequests) { if (string.Equals(request.Nonce, resp.Nonce, StringComparison.CurrentCulture)) { OnListenResponse?.Invoke(this, new OnListenResponseArgs { Response = resp, Topic = request.Topic, Successful = resp.Successful }); handled = true; } } if (handled) { return; } } break; case "message": var msg = new Models.Responses.Message(message); _topicToChannelId.TryGetValue(msg.Topic, out var channelId); channelId = channelId ?? ""; switch (msg.Topic.Split('.')[0]) { case "channel-subscribe-events-v1": var subscription = msg.MessageData as ChannelSubscription; OnChannelSubscription?.Invoke(this, new OnChannelSubscriptionArgs { Subscription = subscription, ChannelId = channelId }); return; case "whispers": var whisper = (Whisper)msg.MessageData; OnWhisper?.Invoke(this, new OnWhisperArgs { Whisper = whisper, ChannelId = channelId }); return; case "chat_moderator_actions": var cma = msg.MessageData as ChatModeratorActions; var reason = ""; var targetChannelId = msg.Topic.Split('.')[2]; switch (cma?.ModerationAction.ToLower()) { case "timeout": if (cma.Args.Count > 2) { reason = cma.Args[2]; } OnTimeout?.Invoke(this, new OnTimeoutArgs { TimedoutBy = cma.CreatedBy, TimedoutById = cma.CreatedByUserId, TimedoutUserId = cma.TargetUserId, TimeoutDuration = TimeSpan.FromSeconds(int.Parse(cma.Args[1])), TimeoutReason = reason, TimedoutUser = cma.Args[0], ChannelId = channelId }); return; case "ban": if (cma.Args.Count > 1) { reason = cma.Args[1]; } OnBan?.Invoke(this, new OnBanArgs { BannedBy = cma.CreatedBy, BannedByUserId = cma.CreatedByUserId, BannedUserId = cma.TargetUserId, BanReason = reason, BannedUser = cma.Args[0], ChannelId = channelId }); return; case "delete": OnMessageDeleted?.Invoke(this, new OnMessageDeletedArgs { DeletedBy = cma.CreatedBy, DeletedByUserId = cma.CreatedByUserId, TargetUserId = cma.TargetUserId, TargetUser = cma.Args[0], Message = cma.Args[1], MessageId = cma.Args[2], ChannelId = channelId }); return; case "unban": OnUnban?.Invoke(this, new OnUnbanArgs { UnbannedBy = cma.CreatedBy, UnbannedByUserId = cma.CreatedByUserId, UnbannedUserId = cma.TargetUserId, UnbannedUser = cma.Args[0], ChannelId = channelId }); return; case "untimeout": OnUntimeout?.Invoke(this, new OnUntimeoutArgs { UntimeoutedBy = cma.CreatedBy, UntimeoutedByUserId = cma.CreatedByUserId, UntimeoutedUserId = cma.TargetUserId, UntimeoutedUser = cma.Args[0], ChannelId = channelId }); return; case "host": OnHost?.Invoke(this, new OnHostArgs { HostedChannel = cma.Args[0], Moderator = cma.CreatedBy, ChannelId = channelId }); return; case "subscribers": OnSubscribersOnly?.Invoke(this, new OnSubscribersOnlyArgs { Moderator = cma.CreatedBy, ChannelId = channelId }); return; case "subscribersoff": OnSubscribersOnlyOff?.Invoke(this, new OnSubscribersOnlyOffArgs { Moderator = cma.CreatedBy, ChannelId = channelId }); return; case "clear": OnClear?.Invoke(this, new OnClearArgs { Moderator = cma.CreatedBy, ChannelId = channelId }); return; case "emoteonly": OnEmoteOnly?.Invoke(this, new OnEmoteOnlyArgs { Moderator = cma.CreatedBy, ChannelId = channelId }); return; case "emoteonlyoff": OnEmoteOnlyOff?.Invoke(this, new OnEmoteOnlyOffArgs { Moderator = cma.CreatedBy, ChannelId = channelId }); return; case "r9kbeta": OnR9kBeta?.Invoke(this, new OnR9kBetaArgs { Moderator = cma.CreatedBy, ChannelId = channelId }); return; case "r9kbetaoff": OnR9kBetaOff?.Invoke(this, new OnR9kBetaOffArgs { Moderator = cma.CreatedBy, ChannelId = channelId }); return; } break; case "channel-bits-events-v1": if (msg.MessageData is ChannelBitsEvents cbe) { OnBitsReceived?.Invoke(this, new OnBitsReceivedArgs { BitsUsed = cbe.BitsUsed, ChannelId = cbe.ChannelId, ChannelName = cbe.ChannelName, ChatMessage = cbe.ChatMessage, Context = cbe.Context, Time = cbe.Time, TotalBitsUsed = cbe.TotalBitsUsed, UserId = cbe.UserId, Username = cbe.Username }); return; } break; case "channel-commerce-events-v1": if (msg.MessageData is ChannelCommerceEvents cce) { OnChannelCommerceReceived?.Invoke(this, new OnChannelCommerceReceivedArgs { Username = cce.Username, DisplayName = cce.DisplayName, ChannelName = cce.ChannelName, UserId = cce.UserId, ChannelId = cce.ChannelId, Time = cce.Time, ItemImageURL = cce.ItemImageURL, ItemDescription = cce.ItemDescription, SupportsChannel = cce.SupportsChannel, PurchaseMessage = cce.PurchaseMessage }); return; } break; case "channel-ext-v1": var cEB = msg.MessageData as ChannelExtensionBroadcast; OnChannelExtensionBroadcast?.Invoke(this, new OnChannelExtensionBroadcastArgs { Messages = cEB.Messages, ChannelId = channelId }); return; case "video-playback": case "video-playback-by-id": var vP = msg.MessageData as VideoPlayback; switch (vP?.Type) { case VideoPlaybackType.StreamDown: OnStreamDown?.Invoke(this, new OnStreamDownArgs { ChannelId = channelId, ServerTime = vP.ServerTime }); return; case VideoPlaybackType.StreamUp: OnStreamUp?.Invoke(this, new OnStreamUpArgs { ChannelId = channelId, PlayDelay = vP.PlayDelay, ServerTime = vP.ServerTime }); return; case VideoPlaybackType.ViewCount: OnViewCount?.Invoke(this, new OnViewCountArgs { ChannelId = channelId, ServerTime = vP.ServerTime, Viewers = vP.Viewers }); return; case VideoPlaybackType.Commercial: OnCommercial?.Invoke(this, new OnCommercialArgs { ChannelId = channelId, ServerTime = vP.ServerTime, Length = vP.Length }); return; case VideoPlaybackType.WatchPartyVod: OnWatchPartyVod?.Invoke(this, new OnWatchPartyVodArgs { ChannelId = channelId, WpId = vP.WpId, WpType = vP.WpType, IncrementUrl = vP.IncrementUrl, VodId = vP.VodId, Title = vP.Title, BroadcastType = vP.BroadcastType, Viewable = vP.Viewable }); return; } break; case "broadcast-settings-update": var bsu = msg.MessageData as BroadcastSettingsUpdate; switch (bsu?.Type) { case BroadcastSettingsUpdateType.BroadcastSettingsUpdate: OnBroadcastSettingsUpdate?.Invoke(this, new OnBroadcastSettingsUpdateArgs { ChannelId = channelId, Channel = bsu.Channel, Game = bsu.Game, GameId = bsu.GameId, OldGame = bsu.OldGame, OldGameId = bsu.OldGameId, OldStatus = bsu.OldStatus, Status = bsu.Status }); return; } break; case "following": var f = (Following)msg.MessageData; f.FollowedChannelId = msg.Topic.Split('.')[1]; OnFollow?.Invoke(this, new OnFollowArgs { FollowedChannelId = f.FollowedChannelId, DisplayName = f.DisplayName, UserId = f.UserId, Username = f.Username }); return; case "community-points-channel-v1": var cpc = msg.MessageData as CommunityPointsChannel; switch (cpc?.Type) { case CommunityPointsChannelType.RewardRedeemed: OnRewardRedeemed?.Invoke(this, new OnRewardRedeemedArgs { TimeStamp = cpc.TimeStamp, ChannelId = cpc.ChannelId, Login = cpc.Login, DisplayName = cpc.DisplayName, Message = cpc.Message, RewardId = cpc.RewardId, RewardTitle = cpc.RewardTitle, RewardPrompt = cpc.RewardPrompt, RewardCost = cpc.RewardCost, Status = cpc.Status }); return; case CommunityPointsChannelType.CustomRewardUpdated: OnCustomRewardUpdated?.Invoke(this, new OnCustomRewardUpdatedArgs { TimeStamp = cpc.TimeStamp, ChannelId = cpc.ChannelId, RewardId = cpc.RewardId, RewardTitle = cpc.RewardTitle, RewardPrompt = cpc.RewardPrompt, RewardCost = cpc.RewardCost }); return; case CommunityPointsChannelType.CustomRewardCreated: OnCustomRewardCreated?.Invoke(this, new OnCustomRewardCreatedArgs { TimeStamp = cpc.TimeStamp, ChannelId = cpc.ChannelId, RewardId = cpc.RewardId, RewardTitle = cpc.RewardTitle, RewardPrompt = cpc.RewardPrompt, RewardCost = cpc.RewardCost }); return; case CommunityPointsChannelType.CustomRewardDeleted: OnCustomRewardDeleted?.Invoke(this, new OnCustomRewardDeletedArgs { TimeStamp = cpc.TimeStamp, ChannelId = cpc.ChannelId, RewardId = cpc.RewardId, RewardTitle = cpc.RewardTitle, RewardPrompt = cpc.RewardPrompt }); return; } return; case "leaderboard-events-v1": var lbe = msg.MessageData as LeaderboardEvents; switch (lbe?.Type) { case LeaderBoardType.BitsUsageByChannel: OnLeaderboardBits?.Invoke(this, new OnLeaderboardEventArgs { ChannelId = lbe.ChannelId, TopList = lbe.Top }); return; case LeaderBoardType.SubGiftSent: OnLeaderboardSubs?.Invoke(this, new OnLeaderboardEventArgs { ChannelId = lbe.ChannelId, TopList = lbe.Top }); return; } return; case "raid": var r = msg.MessageData as RaidEvents; switch (r?.Type) { case RaidType.RaidUpdate: OnRaidUpdate?.Invoke(this, new OnRaidUpdateArgs { Id = r.Id, ChannelId = r.ChannelId, TargetChannelId = r.TargetChannelId, AnnounceTime = r.AnnounceTime, RaidTime = r.RaidTime, RemainingDurationSeconds = r.RemainigDurationSeconds, ViewerCount = r.ViewerCount }); return; case RaidType.RaidUpdateV2: OnRaidUpdateV2?.Invoke(this, new OnRaidUpdateV2Args { Id = r.Id, ChannelId = r.ChannelId, TargetChannelId = r.TargetChannelId, TargetLogin = r.TargetLogin, TargetDisplayName = r.TargetDisplayName, TargetProfileImage = r.TargetProfileImage, ViewerCount = r.ViewerCount }); return; case RaidType.RaidGo: OnRaidGo?.Invoke(this, new OnRaidGoArgs { Id = r.Id, ChannelId = r.ChannelId, TargetChannelId = r.TargetChannelId, TargetLogin = r.TargetLogin, TargetDisplayName = r.TargetDisplayName, TargetProfileImage = r.TargetProfileImage, ViewerCount = r.ViewerCount }); return; } return; } break; } UnaccountedFor(message); }
private async void WebhookServer_PostReceived(WebhookEventArgs e) { try { #if !DEBUG const string signatureHeader = "X-Twitter-Webhooks-Signature"; if (!e.Request.Headers.Keys.Contains(signatureHeader)) { Logger.LogWarning(Resources.InvalidSignature); InvalidPostReceived?.Invoke(e); return; } var signature = e.Request.Headers[signatureHeader][0]; if (!VerifySignature(signature, e.BodyRaw)) { Logger.LogWarning(Resources.InvalidSignature); InvalidPostReceived?.Invoke(e); return; } #endif e.IsValid = true; if (Recipient != 0) { RecipientChecker check = e.Body.FromJson <RecipientChecker>(); if (Recipient != check.Recipient) { return; } } WebhookEvent webhookEvent = e.Body.FromJson <WebhookEvent>(); if (webhookEvent.DirectMessageEvents != null) { if (OnMessage != null) { foreach (var item in webhookEvent.DirectMessageEvents) { MessageEventArgs args = new MessageEventArgs() { Recipient = webhookEvent.Recipient, Message = item.ToMessage() }; await Task.Run(() => { OnMessage.Invoke(args); }); } } } if (webhookEvent.FollowEvents != null) { foreach (var item in webhookEvent.FollowEvents) { if (item.Type == "follow" && OnFollow != null) { FollowEventArgs args = new FollowEventArgs() { Recipient = webhookEvent.Recipient, Timestamp = item.Timestamp, Type = FollowType.Follow, Target = item.Target, Source = item.Source }; await Task.Run(() => { OnFollow.Invoke(args); }); } if (item.Type == "unfollow" && OnUnFollow != null) { FollowEventArgs args = new FollowEventArgs() { Recipient = webhookEvent.Recipient, Timestamp = item.Timestamp, Type = FollowType.Unfollow, Target = item.Target, Source = item.Source }; await Task.Run(() => { OnUnFollow.Invoke(args); }); } } } if (webhookEvent.TweetCreateEvents != null) { foreach (var item in webhookEvent.TweetCreateEvents) { TweetEventArgs args = new TweetEventArgs() { Recipient = webhookEvent.Recipient, Tweet = item }; bool processed = false; if (item.RetweetedFrom != null) { if (OnRetweet != null) { await Task.Run(() => { OnRetweet.Invoke(args); }); } processed = true; } if (item.QuotedFrom != null) { if (OnQuote != null) { await Task.Run(() => { OnQuote.Invoke(args); }); } processed = true; } if (item.ReplyToUserId != null && item.ReplyToStatusId != null) { if (OnComment != null) { await Task.Run(() => { OnComment.Invoke(args); }); } processed = true; } if (item.ReplyToUserId != null && item.ReplyToStatusId == null) { if (OnMention != null) { await Task.Run(() => { OnMention.Invoke(args); }); } processed = true; } if (!processed) { if (OnTweet != null) { await Task.Run(() => { OnTweet.Invoke(args); }); } } } #region //if (Tweeted != null) //{ // foreach (var item in webhookEvent.TweetCreateEvents) // { // TweetCreateEventArgs args = new TweetCreateEventArgs() // { // Tweet = item // }; // Tweeted.Invoke(args); // } //} #endregion } if (webhookEvent.LikeEvents != null) { if (OnLike != null) { foreach (var item in webhookEvent.LikeEvents) { LikeEventArgs args = new LikeEventArgs() { Recipient = webhookEvent.Recipient, Id = item.Id, Timestamp = item.Timestamp, Tweet = item.Tweet, User = item.User }; await Task.Run(() => { OnLike.Invoke(args); }); } } } } catch (Exception ex) { Logger.LogError(EventId, ex, ex.Message); } }
/// <summary> /// Passes <see cref="OnFollow"/> events down to subscribed plugins. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">An <see cref="OnFollowArgs"/> object.</param> private void TwitchPubSub_OnFollow(object sender, OnFollowArgs e) => OnFollow?.Invoke(this, e);
private void ParseMessage(string message) { var type = JObject.Parse(message).SelectToken("type")?.ToString(); switch (type?.ToLower()) { case "response": var resp = new Models.Responses.Response(message); if (_previousRequests.Count != 0) { foreach (var request in _previousRequests) { if (string.Equals(request.Nonce, resp.Nonce, StringComparison.CurrentCultureIgnoreCase)) { OnListenResponse?.Invoke(this, new OnListenResponseArgs { Response = resp, Topic = request.Topic, Successful = resp.Successful }); } } return; } break; case "message": var msg = new Models.Responses.Message(message); switch (msg.Topic.Split('.')[0]) { case "channel-subscribe-events-v1": var subscription = msg.MessageData as ChannelSubscription; OnChannelSubscription?.Invoke(this, new OnChannelSubscriptionArgs { Subscription = subscription }); return; case "whispers": var whisper = (Whisper)msg.MessageData; OnWhisper?.Invoke(this, new OnWhisperArgs { Whisper = whisper }); return; case "chat_moderator_actions": var cma = msg.MessageData as ChatModeratorActions; var reason = ""; switch (cma?.ModerationAction.ToLower()) { case "timeout": if (cma.Args.Count > 2) { reason = cma.Args[2]; } OnTimeout?.Invoke(this, new OnTimeoutArgs { TimedoutBy = cma.CreatedBy, TimedoutById = cma.CreatedByUserId, TimedoutUserId = cma.TargetUserId, TimeoutDuration = TimeSpan.FromSeconds(int.Parse(cma.Args[1])), TimeoutReason = reason, TimedoutUser = cma.Args[0] }); return; case "ban": if (cma.Args.Count > 1) { reason = cma.Args[1]; } OnBan?.Invoke(this, new OnBanArgs { BannedBy = cma.CreatedBy, BannedByUserId = cma.CreatedByUserId, BannedUserId = cma.TargetUserId, BanReason = reason, BannedUser = cma.Args[0] }); return; case "unban": OnUnban?.Invoke(this, new OnUnbanArgs { UnbannedBy = cma.CreatedBy, UnbannedByUserId = cma.CreatedByUserId, UnbannedUserId = cma.TargetUserId, UnbannedUser = cma.Args[0] }); return; case "untimeout": OnUntimeout?.Invoke(this, new OnUntimeoutArgs { UntimeoutedBy = cma.CreatedBy, UntimeoutedByUserId = cma.CreatedByUserId, UntimeoutedUserId = cma.TargetUserId, UntimeoutedUser = cma.Args[0] }); return; case "host": OnHost?.Invoke(this, new OnHostArgs { HostedChannel = cma.Args[0], Moderator = cma.CreatedBy }); return; case "subscribers": OnSubscribersOnly?.Invoke(this, new OnSubscribersOnlyArgs { Moderator = cma.CreatedBy }); return; case "subscribersoff": OnSubscribersOnlyOff?.Invoke(this, new OnSubscribersOnlyOffArgs { Moderator = cma.CreatedBy }); return; case "clear": OnClear?.Invoke(this, new OnClearArgs { Moderator = cma.CreatedBy }); return; case "emoteonly": OnEmoteOnly?.Invoke(this, new OnEmoteOnlyArgs { Moderator = cma.CreatedBy }); return; case "emoteonlyoff": OnEmoteOnlyOff?.Invoke(this, new OnEmoteOnlyOffArgs { Moderator = cma.CreatedBy }); return; case "r9kbeta": OnR9kBeta?.Invoke(this, new OnR9kBetaArgs { Moderator = cma.CreatedBy }); return; case "r9kbetaoff": OnR9kBetaOff?.Invoke(this, new OnR9kBetaOffArgs { Moderator = cma.CreatedBy }); return; } break; case "channel-bits-events-v1": if (msg.MessageData is ChannelBitsEvents cbe) { OnBitsReceived?.Invoke(this, new OnBitsReceivedArgs { BitsUsed = cbe.BitsUsed, ChannelId = cbe.ChannelId, ChannelName = cbe.ChannelName, ChatMessage = cbe.ChatMessage, Context = cbe.Context, Time = cbe.Time, TotalBitsUsed = cbe.TotalBitsUsed, UserId = cbe.UserId, Username = cbe.Username }); } return; case "channel-commerce-events-v1": if (msg.MessageData is ChannelCommerceEvents cce) { OnChannelCommerceReceived?.Invoke(this, new OnChannelCommerceReceivedArgs { Username = cce.Username, DisplayName = cce.DisplayName, ChannelName = cce.ChannelName, UserId = cce.UserId, ChannelId = cce.ChannelId, Time = cce.Time, ItemImageURL = cce.ItemImageURL, ItemDescription = cce.ItemDescription, SupportsChannel = cce.SupportsChannel, PurchaseMessage = cce.PurchaseMessage }); } return; case "channel-ext-v1": var cEB = msg.MessageData as ChannelExtensionBroadcast; OnChannelExtensionBroadcast?.Invoke(this, new OnChannelExtensionBroadcastArgs { Messages = cEB.Messages }); break; case "video-playback": var vP = msg.MessageData as VideoPlayback; switch (vP?.Type) { case VideoPlaybackType.StreamDown: OnStreamDown?.Invoke(this, new OnStreamDownArgs { ServerTime = vP.ServerTime }); return; case VideoPlaybackType.StreamUp: OnStreamUp?.Invoke(this, new OnStreamUpArgs { PlayDelay = vP.PlayDelay, ServerTime = vP.ServerTime }); return; case VideoPlaybackType.ViewCount: OnViewCount?.Invoke(this, new OnViewCountArgs { ServerTime = vP.ServerTime, Viewers = vP.Viewers }); return; } break; case "following": var f = msg.MessageData as Following; f.FollowedChannelId = msg.Topic.Split('.')[1]; OnFollow?.Invoke(this, new OnFollowArgs { FollowedChannelId = f.FollowedChannelId, DisplayName = f.DisplayName, UserId = f.UserId, Username = f.Username }); break; } break; } UnaccountedFor(message); }
private void onMessage(object sender, MessageEventArgs e) { if (!e.IsText) { return; } JObject json = JObject.Parse(e.Data); if (json.SelectToken("type") != null) { switch (json.SelectToken("type").ToString()) { case "command": OnPing?.Invoke(client, new Events.Client.OnPingArgs { UUID = json.SelectToken("extra").SelectToken("uuid").ToString() }); break; case "follow": OnFollow?.Invoke(client, new Events.Client.OnFollowArgs { Channel = json.SelectToken("channel").ToString(), Date = Internal.Common.DateTimeStringToObject(json.SelectToken("date").ToString()), Message = json.SelectToken("message")?.ToString(), UserMessage = json.SelectToken("user_message")?.ToString(), Extra = new Models.Client.Follow.Extra(json.SelectToken("extra")), Viewer = new Models.Client.Viewer(json.SelectToken("viewer")) }); break; case "subscribe": OnSubscriber?.Invoke(client, new Events.Client.OnSubscriberArgs { Channel = json.SelectToken("channel").ToString(), Date = Internal.Common.DateTimeStringToObject(json.SelectToken("date").ToString()), Message = json.SelectToken("message")?.ToString(), UserMessage = json.SelectToken("user_message")?.ToString(), Extra = new Models.Client.Sub.Extra(json.SelectToken("extra")), Viewer = new Models.Client.Viewer(json.SelectToken("viewer")) }); break; case "points_given": OnBits?.Invoke(client, new Events.Client.OnBitsArgs { Channel = json.SelectToken("channel").ToString(), Date = Internal.Common.DateTimeStringToObject(json.SelectToken("date").ToString()), Message = json.SelectToken("message")?.ToString(), UserMessage = json.SelectToken("user_message")?.ToString(), Extra = new Models.Client.Bits.Extra(json.SelectToken("extra")), Viewer = new Models.Client.Viewer(json.SelectToken("viewer")) }); break; case "session_change": OnSessionChanged?.Invoke(client, new Events.Client.OnSessionChangeArgs { Channel = json.SelectToken("channel").ToString(), Date = Internal.Common.DateTimeStringToObject(json.SelectToken("date").ToString()), Message = json.SelectToken("message")?.ToString(), UserMessage = json.SelectToken("user_message")?.ToString(), Extra = new Models.Client.SessionChange.Extra(json.SelectToken("extra")) }); break; case "hosted": OnHosted?.Invoke(client, new Events.Client.OnHostedArgs { Channel = json.SelectToken("channel").ToString(), Date = Internal.Common.DateTimeStringToObject(json.SelectToken("date").ToString()), Message = json.SelectToken("message")?.ToString(), UserMessage = json.SelectToken("user_message")?.ToString(), Extra = new Models.Client.Hosted.Extra(json.SelectToken("extra")), Viewer = new Models.Client.Viewer(json.SelectToken("viewer")) }); break; case "donate": OnDonation?.Invoke(client, new Events.Client.OnDonationArgs { Channel = json.SelectToken("channel").ToString(), Date = Internal.Common.DateTimeStringToObject(json.SelectToken("date").ToString()), Message = json.SelectToken("message")?.ToString(), UserMessage = json.SelectToken("user_message")?.ToString(), Extra = new Models.Client.Donation.Extra(json.SelectToken("extra")), Viewer = new Models.Client.Viewer(json.SelectToken("viewer")) }); break; } } }
public static void InvokeFolowTest() { OnFollow?.Invoke("Carlson"); }