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
                });
            }
        }
Example #2
0
        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
                });
            }
        }
Example #3
0
        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
                    });
                }
            }
        }
Example #4
0
        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
                });
            }
        }
Example #5
0
        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)); });
        }
Example #7
0
        /// <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)); });
        }