Exemplo n.º 1
0
        protected override void RunLoop()
        {
            var sleepMultiplier = 1;

            SetUserCredentials();

            while (!CancellationTokenSource.Token.IsCancellationRequested)
            {
                try
                {
                    long?lastMessageId = _messageCursorCollection.FindById("current")?.Value ?? _appSettings.BotSettings.LastMessageId;

                    var folowerIds    = User.GetFollowerIds("GiveawayXsg", 5000).ToList();
                    var friendIds     = User.GetFriendIds("GiveawayXsg", 5000).ToList();
                    var usersToFollow = folowerIds.Except(friendIds).ToList();
                    usersToFollow.ForEach(u => User.FollowUser(u));

                    var messages = Message.GetLatestMessages(new GetMessagesParameters
                    {
                        Count = 50
                    })?.Where(x => x.Id > lastMessageId.GetValueOrDefault(0)).ToList();

                    if (messages == null)
                    {
                        _logger.Information("Rate limit reached.");
                        CancellationTokenSource.Token.WaitHandle.WaitOne(_appSettings.ProcessingFrequency * 5);
                        continue;
                    }

                    if (messages.Count > 0)
                    {
                        var maxMessageId = messages.Max(x => x.Id);

                        _messageCursorCollection.Upsert("current", new MessageCursor
                        {
                            Id    = "current",
                            Value = maxMessageId
                        });

                        _logger.Information("Last message id: {lastMessageId}", maxMessageId);
                    }

                    foreach (var message in messages)
                    {
                        var url = message?.Entities?.Urls.Select(u => u.ExpandedURL).FirstOrDefault();

                        if (url == null)
                        {
                            continue;
                        }

                        var strTweetId = new Uri(url).Segments.LastOrDefault();
                        if (strTweetId != null)
                        {
                            if (long.TryParse(strTweetId, out var tweetId))
                            {
                                try
                                {
                                    var tweet = Tweet.GetTweet(tweetId);
                                    if (tweet == null)
                                    {
                                        continue;
                                    }

                                    if ((DateTime.UtcNow - tweet.CreatedBy.CreatedAt).Days < 10 || tweet.CreatedBy.DefaultProfileImage)  //|| !tweet.CreatedBy.Verified || tweet.CreatedBy.FollowersCount < 5)
                                    {
                                        _logger.Information("Ignoring tweet from user {@User} - probably a fake account.", tweet.CreatedBy);
                                        Message.PublishMessage($"Response to tweet ({tweet.Id}) - Are you using a fake account?", tweet.CreatedBy.Id);
                                        tweet.CreatedBy.BlockUser();
                                        continue;
                                    }

                                    var isProcessed = _userTweetMapCollection.FindById($"{tweet.CreatedBy.Id}@{tweet.Id}");
                                    if (isProcessed != null)
                                    {
                                        _logger.Information("Ignoring tweet from user {@User} - processed already.", tweet.CreatedBy);
                                        Message.PublishMessage($"Response to tweet ({tweet.Id}) - your tweet has been processed already.", tweet.CreatedBy.Id);
                                        continue;
                                    }

                                    _logger.Information("Received tweet ({Id}) '{Text}' from {Name} ", tweet.Id, tweet.FullText, tweet.CreatedBy.Name);

                                    // tweet can not be a reply
                                    if (!string.IsNullOrWhiteSpace(tweet.InReplyToScreenName))
                                    {
                                        _logger.Information("Ignoring tweet from user {@User} - replies are not supported.", tweet.CreatedBy);
                                        Message.PublishMessage($"Response to tweet ({tweet.Id}) - replies are not supported.", tweet.CreatedBy.Id);
                                        continue;
                                    }

                                    // tweet must contain hashtags
                                    var requiredHashTags = _appSettings.BotSettings.TrackKeywords;
                                    var tweetHashTags    = tweet.Hashtags.Select(x => x.Text).ToList();
                                    var hasValidHashTags = requiredHashTags.All(h => tweetHashTags.Contains(h));
                                    if (!hasValidHashTags)
                                    {
                                        _logger.Information("Ignoring tweet from user {@User} - tweet should contain the following hashtags", tweet.CreatedBy);
                                        Message.PublishMessage($"Response to tweet ({tweet.Id}) - Tweet should contain the following hashtags: {String.Join(" ", _appSettings.BotSettings.TrackKeywords)}", tweet.CreatedBy.Id);
                                        continue;
                                    }

                                    // tweet must contain valid xsg address
                                    var text          = Regex.Replace(tweet.FullText, @"\r\n?|\n|\(|\)", " ");
                                    var targetAddress = _messageParser.GetValidAddressAsync(text).GetAwaiter().GetResult();
                                    if (string.IsNullOrWhiteSpace(targetAddress))
                                    {
                                        _logger.Information("Ignoring tweet from user {@User} - Tweet should contain valid xsg transparent address", tweet.CreatedBy);
                                        Message.PublishMessage($"Response to tweet ({tweet.Id}) - Tweet should contain valid xsg transparent address", tweet.CreatedBy.Id);
                                        continue;
                                    }

                                    var addressToUserMap = _addressToUserMapCollection.FindById(targetAddress);
                                    if (addressToUserMap == null)
                                    {
                                        _addressToUserMapCollection.Insert(new AddressToUserMap
                                        {
                                            Id     = targetAddress,
                                            UserId = tweet.CreatedBy.Id
                                        });
                                    }
                                    else if (addressToUserMap.UserId != tweet.CreatedBy.Id)
                                    {
                                        _logger.Information("Ignoring tweet from user {@User} - probably a fake account - used same address", tweet.CreatedBy);
                                        Message.PublishMessage($"Response to tweet ({tweet.Id}) - Are you using a fake account?", tweet.CreatedBy.Id);
                                        tweet.CreatedBy.BlockUser();
                                    }


                                    // user can not be a scammer
                                    //var isUserLegit = ValidateUser(tweet.CreatedBy);
                                    //if (!isUserLegit)
                                    //{
//                                        _logger.Information("Ignoring tweet from user {@User}", tweet.CreatedBy);
//                                        Message.PublishMessage($"Response to tweet ({tweet.Id}) - Is your account a fake one? You you have to little followers.", tweet.CreatedBy.Id);
//                                        continue;
//                                    }

                                    // tweet can not be too short
                                    var isTweetTextValid = ValidateTweetText(tweet.Text);
                                    if (!isTweetTextValid)
                                    {
                                        _logger.Information("Ignoring tweet from user {@User} - Your tweet is too short", tweet.CreatedBy);
                                        Message.PublishMessage($"Response to tweet ({tweet.Id}) - Your tweet is too short", tweet.CreatedBy.Id);
                                        continue;
                                    }

                                    // --- processing payout
                                    var rewardType   = GetRewardType(tweet);
                                    var reward       = _rewardCollection.FindOne(x => x.Id == tweet.CreatedBy.Id);
                                    var replyMessage = reward != null
                                        ? HandleExistingUser(tweet, targetAddress, reward, rewardType)
                                        : HandleNewUser(tweet, targetAddress, rewardType);

                                    _userTweetMapCollection.Insert(new UserTweetMap
                                    {
                                        Id = $"{tweet.CreatedBy.Id}@{tweet.Id}"
                                    });

                                    Tweet.PublishTweet(replyMessage, new PublishTweetOptionalParameters
                                    {
                                        InReplyToTweet = tweet
                                    });

                                    Message.PublishMessage($"Response to tweet ({tweet.Id}) - {replyMessage}", tweet.CreatedBy.Id);

                                    _logger.Information("Replied with message '{ReplyMessage}'", replyMessage);
                                    _logger.Information("Faucet balance: {balance} XSG", _withdrawalService.GetBalanceAsync().GetAwaiter().GetResult());
                                }
                                catch (Exception exception)
                                {
                                    _logger.Error(exception, "Processing tweet messages failed");
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.Error(ex, "Failed to process tweets");
                    sleepMultiplier = 10;
                    SetUserCredentials();
                }
                finally
                {
                    CancellationTokenSource.Token.WaitHandle.WaitOne(_appSettings.ProcessingFrequency * sleepMultiplier);
                    sleepMultiplier = 1;
                }
            }
        }