public void GetUserTimelineQuery_ReturnsExpectedQuery() { // Arrange var queryGenerator = CreateTimelineQueryGenerator(); var parameters = new GetUserTimelineParameters("linvi") { IncludeEntities = true, TrimUser = true, IncludeContributorDetails = true, IncludeRetweets = true, ExcludeReplies = true, MaxId = 42, SinceId = 43, PageSize = 44, CustomQueryParameters = { new Tuple <string, string>("hello", "world") } }; // Act var result = queryGenerator.GetUserTimelineQuery(parameters, ComputedTweetMode.Extended); // Assert Assert.Equal(result, $"https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=linvi&count=44&since_id=43&max_id=42" + $"&include_entities=true&trim_user=true&tweet_mode=extended&exclude_replies=true&include_rts=true&hello=world"); }
private async Task <IEnumerable <ITweet> > RetrieveTweets(string username, DateTime earliest, DateTime latest) { var tweets = new List <ITweet>(); IEnumerable <ITweet> fetched; var timelineParams = new GetUserTimelineParameters(username) { IncludeEntities = true, IncludeRetweets = true, PageSize = 200 }; var finish = false; do { fetched = await client.Timelines.GetUserTimelineAsync(timelineParams); Log("Fetched page with: " + fetched.Count() + " tweets."); var fetchedInRange = fetched.Where(t => t.CreatedAt >= earliest && t.CreatedAt < latest); Log("➡ Found " + fetchedInRange.Count() + " tweets in range."); tweets.AddRange(fetchedInRange); if (fetched.Count() > 0) { timelineParams.MaxId = fetched.Min(t => t.Id) - 1; Log("➡ New max id: " + timelineParams.MaxId); } finish = fetched.Count() == 0 || fetched.All(t => t.CreatedAt < earliest) || tweets.Count() >= API_LIMIT_MAX_TWEETS; } while (!finish); return(tweets); }
public ITwitterPageIterator <ITwitterResult <ITweetDTO[]>, long?> GetUserTimelineIterator(IGetUserTimelineParameters parameters, ITwitterRequest request) { return(_pageCursorIteratorFactories.Create(parameters, cursor => { var cursoredParameters = new GetUserTimelineParameters(parameters) { MaxId = cursor }; return _timelineQueryExecutor.GetUserTimeline(cursoredParameters, new TwitterRequest(request)); })); }
public async Task <IEnumerable <Update> > GetUpdatesAsync(string userId) { var parameters = new GetUserTimelineParameters(userId) { PageSize = 10, TweetMode = TweetMode.Extended }; ITweet[] tweets = await _twitterClient.Timelines.GetUserTimelineAsync(parameters); return(tweets .Select(ToUpdate(userId))); }
public void GetUserTimelineIterator_ReturnsFromPageCursorIteratorFactories() { // arrange var parameters = new GetUserTimelineParameters("linvi") { PageSize = 2 }; var request = A.Fake <ITwitterRequest>(); var expectedResult = A.Fake <ITwitterPageIterator <ITwitterResult <ITweetDTO[]>, long?> >(); A.CallTo(() => _fakePageCursorIteratorFactories.Create(parameters, It.IsAny <Func <long?, Task <ITwitterResult <ITweetDTO[]> > > >())) .Returns(expectedResult); var controller = CreateTimelineController(); var iterator = controller.GetUserTimelineIterator(parameters, request); // assert Assert.Equal(iterator, expectedResult); }
public async Task GetUserTimelineQuery_ReturnsTweetsAsync() { // Arrange var queryExecutor = CreateTimelineQueryExecutor(); var expectedQuery = TestHelper.GenerateString(); var parameters = new GetUserTimelineParameters("linvi"); var request = A.Fake <ITwitterRequest>(); var expectedResult = A.Fake <ITwitterResult <ITweetDTO[]> >(); A.CallTo(() => _fakeTimelineQueryGenerator.GetUserTimelineQuery(parameters, It.IsAny <TweetMode?>())).Returns(expectedQuery); A.CallTo(() => _fakeTwitterAccessor.ExecuteRequestAsync <ITweetDTO[]>(request)).Returns(expectedResult); // Act var result = await queryExecutor.GetUserTimelineAsync(parameters, request); // Assert Assert.Equal(result, expectedResult); Assert.Equal(request.Query.Url, expectedQuery); Assert.Equal(HttpMethod.GET, request.Query.HttpMethod); }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { try { var lastTweetIdTask = _twitterLogService.GetLastTweetId(); var user = await _twitterClient.Users.GetUserAsync(_twitterBotSettings.BotUsername); long sinceTweetId = await lastTweetIdTask; var tweets = new List <ITweet>(); await foreach (var followerId in GetFollowersIds(user)) { var getTimeLineParameters = new GetUserTimelineParameters(followerId); if (sinceTweetId == 0) { getTimeLineParameters.PageSize = _twitterBotSettings.TimelineFirstLoadPageSize; } else { getTimeLineParameters.SinceId = sinceTweetId; } var timeLine = await _twitterClient.Timelines.GetUserTimelineAsync(getTimeLineParameters); if (timeLine.Length == 0) { continue; } // Avoid Retweets. tweets.AddRange(timeLine.Where(v => !v.Text.StartsWith("RT"))); } foreach (var tweet in tweets) { var tweetText = StringUtils.RemoveHashtags(StringUtils.RemoveMentions(tweet.Text)); var correctionsResult = await _grammarService.GetCorrections(tweetText); if (correctionsResult.HasCorrections) { var messageBuilder = new StringBuilder(); var mentionedUsers = tweet.UserMentions.Select(v => v.ToString()).Join(" "); // Other users mentioned in the tweet messageBuilder.Append($"@{tweet.CreatedBy.ScreenName} {mentionedUsers}"); foreach (var correction in correctionsResult.Corrections) { // Only suggest the first possible replacement for now messageBuilder.AppendLine($"*{correction.PossibleReplacements.First()} [{correction.Message}]"); } var correctionString = messageBuilder.ToString(); _logger.LogInformation($"Sending reply to: {tweet.CreatedBy.ScreenName}"); var publishTweetParameters = new PublishTweetParameters(correctionString) { InReplyToTweetId = tweet.Id, }; var replyTweet = await _twitterClient.Tweets.PublishTweetAsync(publishTweetParameters); if (replyTweet != null) { _logger.LogInformation("Reply sent successfuly"); await _twitterLogService.LogReply(tweet.Id, replyTweet.Id); } await Task.Delay(_twitterBotSettings.PublishTweetDelayMilliseconds); } } if (tweets.Any()) { var lastTweet = tweets.OrderByDescending(v => v.Id).First(); // Save last Tweet Id await _twitterLogService.LogTweet(lastTweet.Id); } } catch (Exception ex) { _logger.LogError(ex, ex.Message); } await Task.Delay(_twitterBotSettings.HostedServiceIntervalMilliseconds); } }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { try { var lastTweetIdTask = TwitterLogService.GetLastTweetId(); var followers = await TwitterClient.Users.GetFollowersAsync(TwitterBotSettings.BotUsername); var friendIds = await TwitterClient.Users.GetFriendIdsAsync(TwitterBotSettings.BotUsername); long sinceTweetId = await lastTweetIdTask; var tweets = new List <ITweet>(); foreach (var follower in followers) { if (follower.Protected && !friendIds.Contains(follower.Id)) { continue; } var getTimeLineParameters = new GetUserTimelineParameters(follower); if (sinceTweetId == 0) { getTimeLineParameters.PageSize = TwitterBotSettings.TimelineFirstLoadPageSize; } else { getTimeLineParameters.SinceId = sinceTweetId; } var timeLine = await TwitterClient.Timelines.GetUserTimelineAsync(getTimeLineParameters); if (timeLine.Length == 0) { continue; } // Avoid Retweets. tweets.AddRange(timeLine.Where(v => !v.Text.StartsWith("RT"))); } foreach (var tweet in tweets) { var tweetText = StringUtils.RemoveHashtags(StringUtils.RemoveMentions(StringUtils.RemoveEmojis(tweet.Text))); var correctionsResult = await _grammarService.GetCorrections(tweetText); if (!correctionsResult.HasCorrections) { continue; } var messageBuilder = new StringBuilder(); var mentionedUsers = tweet.UserMentions.Select(v => v.ToString()).Join(" "); // Other users mentioned in the tweet messageBuilder.Append($"@{tweet.CreatedBy.ScreenName} {mentionedUsers} "); foreach (var correction in correctionsResult.Corrections) { // Only suggest the first possible replacement messageBuilder.AppendLine($"*{correction.PossibleReplacements.First()} [{correction.Message}]"); } var correctionString = messageBuilder.ToString(); Logger.LogInformation($"Sending reply to: {tweet.CreatedBy.ScreenName}"); if (correctionString.Length >= Defaults.TwitterTextMaxLength) { var replyTweets = correctionString.SplitInParts(Defaults.TwitterTextMaxLength); foreach (var(reply, index) in replyTweets.WithIndex()) { var correctionStringSplitted = index == 0 ? reply : $"@{tweet.CreatedBy.ScreenName} {mentionedUsers} {reply}"; await PublishReplyTweet(correctionStringSplitted, tweet.Id); await Task.Delay(TwitterBotSettings.PublishTweetDelayMilliseconds, stoppingToken); } continue; } await PublishReplyTweet(correctionString, tweet.Id); await Task.Delay(TwitterBotSettings.PublishTweetDelayMilliseconds, stoppingToken); } if (tweets.Any()) { var lastTweet = tweets.OrderByDescending(v => v.Id).First(); // Save last Tweet Id await TwitterLogService.LogTweet(lastTweet.Id); } await FollowBackUsers(followers, friendIds); await PublishScheduledTweets(); await LikeRepliesToBot(tweets); } catch (Exception ex) { var message = ex is TwitterException tEx ? tEx.TwitterDescription : ex.Message; Logger.LogError(ex, message); // fire and forget _ = _githubService.CreateBugIssue($"Application Exception: {message}", ex, GithubIssueLabels.Twitter); } await Task.Delay(TwitterBotSettings.HostedServiceIntervalMilliseconds); } }