private async Task TimerTick() { ChannelFollowers channelFollowers; string id; lock (lockObject) id = channel.Id; try { channelFollowers = await api.V5.Channels.GetChannelFollowersAsync(id, 100); } catch (Exception ex) { logger.Error($"{ex.GetType().Name}: {ex.Message}"); Thread.Sleep(1000); return; } var newFollowers = channelFollowers.Follows.Where(x => !currentFollowerIds.Contains(x.User.Id)).ToList(); if (newFollowers.Count > 0) { lock (lockObject) { CurrentFollowers.AddRange(newFollowers); currentFollowerIds.AddRange(newFollowers.Select(x => x.User.Id)); } OnNewFollowersDetected?.Invoke(this, new NewFollowerDetectedArgs { NewFollowers = newFollowers }); } }
private async void _followerServiceTimerElapsed(object sender, ElapsedEventArgs e) { Models.API.Follow.FollowersResponse response; try { response = await TwitchApi.Follows.GetFollowersAsync(Channel, QueryCount); } catch (WebException) { //Logging.Log("Twitch API is unavailable. Skipping FollowerService iteration..."); return; } List <Models.API.Follow.Follower> mostRecentFollowers = response.Followers; List <Models.API.Follow.Follower> newFollowers = new List <Models.API.Follow.Follower>(); foreach (Models.API.Follow.Follower recentFollower in mostRecentFollowers) { bool found = false; foreach (Models.API.Follow.Follower cachedFollower in ActiveCache) { if (recentFollower.User.Name.ToLower() == cachedFollower.User.Name.ToLower()) { found = true; } } if (!found) { newFollowers.Add(recentFollower); } } // Check for new followers if (newFollowers.Count > 0) { // add new followers to active cache ActiveCache.AddRange(newFollowers); // prune cache so we don't use too much space unnecessarily if (ActiveCache.Count > CacheSize) { ActiveCache = ActiveCache.GetRange(ActiveCache.Count - (CacheSize + 1), CacheSize); } // Invoke new followers event OnNewFollowersDetected?.Invoke(this, new OnNewFollowersDetectedArgs { Channel = Channel, CheckIntervalSeconds = CheckIntervalSeconds, QueryCount = QueryCount, NewFollowers = newFollowers }); } }
private async void _followerServiceTimerElapsed(object sender, ElapsedEventArgs e) { FollowersResponse response = await TwitchApi.GetTwitchFollowers(Channel, QueryCount); List <Follower> mostRecentFollowers = response.Followers; List <Follower> newFollowers = new List <Follower>(); if (ActiveCache == null) { ActiveCache = mostRecentFollowers; newFollowers = ActiveCache; } else { foreach (Follower recentFollower in mostRecentFollowers) { bool found = false; foreach (Follower cachedFollower in ActiveCache) { if (recentFollower.User.Name.ToLower() == cachedFollower.User.Name.ToLower()) { found = true; } } if (!found) { newFollowers.Add(recentFollower); } } // Check for new followers if (newFollowers.Count > 0) { // add new followers to active cache ActiveCache.AddRange(newFollowers); // prune cache so we don't use too much space unnecessarily if (ActiveCache.Count > CacheSize) { ActiveCache = ActiveCache.GetRange(ActiveCache.Count - (CacheSize + 1), CacheSize); } // Invoke new followers event OnNewFollowersDetected?.Invoke(this, new OnNewFollowersDetectedArgs { Channel = Channel, CheckIntervalSeconds = CheckIntervalSeconds, QueryCount = QueryCount, NewFollowers = newFollowers }); } } }
private async void _followerServiceTimerElapsed(object sender, ElapsedEventArgs e) { TwitchAPIClasses.FollowersResponse response = await TwitchApi.GetTwitchFollowers(Channel, QueryCount); List <TwitchAPIClasses.Follower> mostRecentFollowers = response.Followers; List <TwitchAPIClasses.Follower> newFollowers = new List <TwitchAPIClasses.Follower>(); if (ActiveCache == null) { ActiveCache = mostRecentFollowers; newFollowers = ActiveCache; } else { if (ActiveCache[0].User.Name != mostRecentFollowers[0].User.Name) { for (int i = 0; i < mostRecentFollowers.Count; i++) { if (mostRecentFollowers[i].User.Name != ActiveCache[0].User.Name) { newFollowers.Add(mostRecentFollowers[i]); } else { break; } } ActiveCache = mostRecentFollowers; } } if (newFollowers.Count > 0) { OnNewFollowersDetected?.Invoke(this, new OnNewFollowersDetectedArgs { Channel = Channel, CheckIntervalSeconds = CheckIntervalSeconds, QueryCount = QueryCount, NewFollowers = newFollowers }); } }
private async void _followerServiceTimerElapsed(object sender, ElapsedEventArgs e) { List <string> mostRecentFollowers = new List <string>(); try { if (ChannelIdentifier == Enums.ChannelIdentifierType.Username) { var followers = await TwitchAPI.Follows.v3.GetFollowers(ChannelData, QueryCount); foreach (var follower in followers.Followers) { mostRecentFollowers.Add(follower.User.Name); } } else { var followers = await TwitchAPI.Channels.v5.GetChannelFollowers(ChannelData, QueryCount); foreach (var follower in followers.Follows) { mostRecentFollowers.Add(follower.User.Name); } } } catch (WebException) { return; } List <string> newFollowers = new List <string>(); foreach (var recentFollower in mostRecentFollowers) { bool found = false; foreach (var cachedFollower in ActiveCache) { if (recentFollower == cachedFollower) { found = true; } } if (!found) { newFollowers.Add(recentFollower); } } // Check for new followers if (newFollowers.Count > 0) { // add new followers to active cache ActiveCache.AddRange(newFollowers); // prune cache so we don't use too much space unnecessarily if (ActiveCache.Count > CacheSize) { ActiveCache = ActiveCache.GetRange(ActiveCache.Count - (CacheSize + 1), CacheSize); } // Invoke new followers event OnNewFollowersDetected?.Invoke(this, new OnNewFollowersDetectedArgs { ChannelIdentifier = ChannelIdentifier, ChannelData = ChannelData, CheckIntervalSeconds = CheckIntervalSeconds, QueryCount = QueryCount, NewFollowers = newFollowers }); } }
public UnityFollowerService(ITwitchAPI api, int checkIntervalSeconds = 60, int queryCount = 25) : base(api, checkIntervalSeconds, queryCount) { ThreadDispatcher.EnsureCreated(); base.OnServiceStarted += ((object sender, OnServiceStartedArgs e) => { ThreadDispatcher.Enqueue(() => OnServiceStarted?.Invoke(sender, e)); }); base.OnServiceStopped += ((object sender, OnServiceStoppedArgs e) => { ThreadDispatcher.Enqueue(() => OnServiceStopped?.Invoke(sender, e)); }); base.OnNewFollowersDetected += ((object sender, OnNewFollowersDetectedArgs e) => { ThreadDispatcher.Enqueue(() => OnNewFollowersDetected?.Invoke(sender, e)); }); }
/// <summary> /// Updates the followerservice with the latest followers. Automatically called internally when service is started. /// </summary> /// <param name="callEvents">Whether to invoke the update events or not.</param> public async Task UpdateLatestFollowersAsync(bool callEvents = true) { if (ChannelsToMonitor == null) { return; } foreach (var channel in ChannelsToMonitor) { List <Follow> newFollowers; var latestFollowers = await GetLatestFollowersAsync(channel); if (latestFollowers.Count == 0) { return; } if (!KnownFollowers.TryGetValue(channel, out var knownFollowers)) { newFollowers = latestFollowers; KnownFollowers[channel] = latestFollowers.Take(CacheSize).ToList(); _lastFollowerDates[channel] = latestFollowers.Last().FollowedAt; } else { var existingFollowerIds = new HashSet <string>(knownFollowers.Select(f => f.FromUserId)); var latestKnownFollowerDate = _lastFollowerDates[channel]; newFollowers = new List <Follow>(); foreach (var follower in latestFollowers) { if (!existingFollowerIds.Add(follower.FromUserId)) { continue; } if (follower.FollowedAt < latestKnownFollowerDate) { continue; } newFollowers.Add(follower); latestKnownFollowerDate = follower.FollowedAt; knownFollowers.Add(follower); } existingFollowerIds.Clear(); existingFollowerIds.TrimExcess(); // prune cache so we don't use too much space unnecessarily if (knownFollowers.Count > CacheSize) { knownFollowers.RemoveRange(0, knownFollowers.Count - CacheSize); } if (newFollowers.Count <= 0) { return; } _lastFollowerDates[channel] = latestKnownFollowerDate; } if (!callEvents) { return; } OnNewFollowersDetected?.Invoke(this, new OnNewFollowersDetectedArgs { Channel = channel, NewFollowers = newFollowers }); } }
public UnityFollowerService(ITwitchAPI api, int checkIntervalSeconds = 60, int queryCount = 25) : base(api, checkIntervalSeconds, queryCount) { _threadDispatcher = new GameObject("ThreadDispatcher"); _threadDispatcher.AddComponent <ThreadDispatcher>(); UnityEngine.Object.DontDestroyOnLoad(_threadDispatcher); base.OnServiceStarted += ((object sender, OnServiceStartedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnServiceStarted?.Invoke(sender, e)); }); base.OnServiceStopped += ((object sender, OnServiceStoppedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnServiceStopped?.Invoke(sender, e)); }); base.OnNewFollowersDetected += ((object sender, OnNewFollowersDetectedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnNewFollowersDetected?.Invoke(sender, e)); }); }