public static async Task RespondToMPUrls(Dictionary <Subreddit, List <Comment> > subredditsAndRecentComments) //Respond to comments that have a mountainproject url { foreach (Subreddit subreddit in subredditsAndRecentComments.Keys.ToList()) { List <Comment> filteredComments = subredditsAndRecentComments[subreddit].Where(c => c.Body.Contains("mountainproject.com")).ToList(); filteredComments = BotUtilities.RemoveAlreadyRepliedTo(filteredComments); filteredComments.RemoveAll(c => c.IsArchived); filteredComments = BotUtilities.RemoveBlacklisted(filteredComments, new[] { BlacklistLevel.OnlyKeywordReplies, BlacklistLevel.Total }); //Remove comments from users who don't want the bot to automatically reply to them filteredComments = await BotUtilities.RemoveCommentsOnSelfPosts(subreddit, filteredComments); //Don't reply to self posts (aka text posts) subredditsAndRecentComments[subreddit] = filteredComments; } foreach (Comment comment in subredditsAndRecentComments.SelectMany(p => p.Value)) { try { Console.WriteLine($"\tGetting reply for comment: {comment.Id}"); string reply = BotReply.GetReplyForMPLinks(comment); if (string.IsNullOrEmpty(reply)) { BotUtilities.LogCommentBeenRepliedTo(comment); //Don't check this comment again continue; } if (!DryRun) { Comment botReplyComment = await RedditHelper.ReplyToComment(comment, reply); ConsoleHelper.Write($"\tReplied to comment {comment.Id}", ConsoleColor.Green); monitoredComments.Add(new CommentMonitor() { Parent = comment, BotResponseComment = botReplyComment }); } BotUtilities.LogCommentBeenRepliedTo(comment); } catch (RateLimitException) { Console.WriteLine("\tRate limit hit. Postponing reply until next iteration"); } catch (Exception e) { Console.WriteLine($"\tException occurred with comment {RedditHelper.GetFullLink(comment.Permalink)}"); Console.WriteLine($"\t{e.Message}\n{e.StackTrace}"); } } }
public static async Task RespondToRequests(List <Comment> recentComments) //Respond to comments that specifically called the bot (!MountainProject) { List <Comment> botRequestComments = recentComments.Where(c => Regex.IsMatch(c.Body, BOTKEYWORDREGEX)).ToList(); botRequestComments = BotUtilities.RemoveAlreadyRepliedTo(botRequestComments); botRequestComments.RemoveAll(c => c.IsArchived); botRequestComments = BotUtilities.RemoveBlacklisted(botRequestComments, new[] { BlacklistLevel.Total }); //Don't reply to bots foreach (Comment comment in botRequestComments) { try { Console.WriteLine($"\tGetting reply for comment: {comment.Id}"); string reply = BotReply.GetReplyForRequest(comment); if (!DryRun) { Comment botReplyComment = await RedditHelper.ReplyToComment(comment, reply); ConsoleHelper.Write($"\tReplied to comment {comment.Id}", ConsoleColor.Green); monitoredComments.Add(new CommentMonitor() { Parent = comment, BotResponseComment = botReplyComment }); } BotUtilities.LogCommentBeenRepliedTo(comment); } catch (RateLimitException) { Console.WriteLine("\tRate limit hit. Postponing reply until next iteration"); } catch (Exception e) { Console.WriteLine($"\tException occurred with comment {RedditHelper.GetFullLink(comment.Permalink)}"); Console.WriteLine($"\t{e.Message}\n{e.StackTrace}"); } } }
public static async Task CheckPostsForAutoReply(List <Subreddit> subreddits) { List <Post> recentPosts = new List <Post>(); foreach (Subreddit subreddit in subreddits) { List <Post> subredditPosts = await RedditHelper.GetPosts(subreddit, 10); subredditPosts = BotUtilities.RemoveAlreadySeenPosts(subredditPosts); subredditPosts = BotUtilities.RemoveBlacklisted(subredditPosts, new[] { BlacklistLevel.NoPostReplies, BlacklistLevel.OnlyKeywordReplies, BlacklistLevel.Total }); //Remove posts from users who don't want the bot to automatically reply to them foreach (Post post in subredditPosts.ToList()) { if (post.IsSelfPost) { subredditPosts.Remove(post); ConsoleHelper.Write($"\tSkipping {post.Id} (self-post)", ConsoleColor.Red); BotUtilities.LogPostBeenSeen(post, "self-post"); } double ageInMin = (DateTime.UtcNow - post.CreatedUTC).TotalMinutes; if (ageInMin > 30) { subredditPosts.Remove(post); ConsoleHelper.Write($"\tSkipping {post.Id} (too old: {Math.Round(ageInMin, 2)} min)", ConsoleColor.Red); BotUtilities.LogPostBeenSeen(post, $"too old ({Math.Round(ageInMin, 2)} min)"); } } recentPosts.AddRange(subredditPosts); } foreach (Post post in recentPosts) { try { string postTitle = WebUtility.HtmlDecode(post.Title); Console.WriteLine($"\tTrying to get an automatic reply for post (/r/{post.SubredditName}): {postTitle}"); SearchResult searchResult = MountainProjectDataSearch.ParseRouteFromString(postTitle); if (!searchResult.IsEmpty()) { ApprovalRequest approvalRequest = new ApprovalRequest { RedditPost = post, SearchResult = searchResult }; PostsPendingApproval.TryAdd(post.Id, approvalRequest); BotUtilities.LogPostBeenSeen(post, searchResult.Confidence == 1 ? "auto-replying" : "pending approval"); if (!DryRun) { if (searchResult.Confidence == 1) { string reply = BotReply.GetFormattedString(searchResult); reply += Markdown.HRule; reply += BotReply.GetBotLinks(post); Comment botReplyComment = await RedditHelper.CommentOnPost(post, reply); monitoredComments.Add(new CommentMonitor() { Parent = post, BotResponseComment = botReplyComment }); ConsoleHelper.Write($"\n\tAuto-replied to post {post.Id}", ConsoleColor.Green); } else { //Until we are more confident with automatic results, we're going to request for approval for confidence values greater than 1 (less than 100%) ConsoleHelper.Write($"\tRequesting approval for post {post.Id}", ConsoleColor.Yellow); BotUtilities.RequestApproval(approvalRequest); } BotUtilities.LogOrUpdateSpreadsheet(approvalRequest); } } else { Console.WriteLine("\tNothing found"); BotUtilities.LogPostBeenSeen(post, "nothing found"); } } catch (RateLimitException) { Console.WriteLine("\tRate limit hit. Postponing reply until next iteration"); } catch (Exception e) { Console.WriteLine($"\tException occurred with post {RedditHelper.GetFullLink(post.Permalink)}"); Console.WriteLine($"\t{e.Message}\n{e.StackTrace}"); } } }