Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A way for CP members to reduce RSI during spam wave events

4.68/5 (6 votes)
20 May 2022CPOL2 min read 6.1K   10  
Unless you have sufficient permissions (i.e. you are a protector) you can't see the moderation queue, so this is useless to you. Sorry!Spam waves: A flood of spammers filling the moderation queue with new users all advertising the same thing.

Download BotReport.zip

Introduction

Protectors can access the Forum post and Q&A pending message queues, and either approve it for publication, or reject it as spam / abuse. We then raise the member in the "Spam & Abuse" forum, so members can vote to close the offenders account.

This is important, because the process absolutely needs human input - it's too easy for the automated system to assume it's spam when it really isn't. And the need for multiple members to vote to close an account is also important as it's far to easy to hit the wrong button, and we do need a "double check" before closing an account.

Background

But... during a spam wave you get lots of users in the queue, and the manual process to report them is both intensive and RSI inducing. So, I assembled this quick and dirty bit of code to make the process simpler.

Using the code

The first thing to note is that this doesn't automate the reporting process - all it does is assemble a list of links to users from the HTML of the report page. This is deliberate.

To automate it would require fetching the report page from the CP server (doable) once the HTMLAgilityPack had been told to log in as you (probably doable), parsing the HTML and extracting the links (trivial), formatting them for a S&A message (trivial), and reporting each of the users (probably doable).

But ... that has problems:

  1. Fetching the report page and automatically processing it could add "false positives" because the automated system could have added messages to it since you looked.
  2. Logging in as you would require me storing your email and password in a safe and secure manner appropriate for GDPR.
  3. You might have logged in using Facebook or Google and I really don't want to see how deep that rabbit hole goes ...

To use the code, just approve all the "non-spam" messages, then use your browser to inspect the page source, copy it to the clipboard, then run the code. Open a report in S&A, and paste the clipboard "as is".

Reject all the messages.

This is pretty easy: for Chrome CTRL+U, CTRL+A, CTRL+C, CTRL+F4 will copy the HTML source and close the view.

Please, not too many comments on the code quality - this is a quick and dirty, brute force and ignorance approach in C#:

C#
        private void DoClipboardToClipboard()
            {
            Clipboard.SetText(ExtractAndDisplay(Clipboard.GetText()));
            }
        private string ExtractAndDisplay(string rawPageHtml)
            {
            rawHTML.Text = rawPageHtml;
            string processedData = MakeReportableLinks(rawPageHtml);
            links.Text = processedData;
            return processedData;
            }
        private static string MakeReportableLinks(string rawPageHtml)
            {
            string userLink = "<a href=\"https://www.codeproject.com/script/Membership/View.aspx?mid=%ID%\">Member %ID% - Professional Profile</a>[<a href=\"https://www.codeproject.com/script/Membership/View.aspx?mid=%ID%\" target=\"_blank\" title=\"New Window\">^</a>]";
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(rawPageHtml);
            HtmlNodeCollection nodes = doc.DocumentNode.SelectNodes("//a[contains(@id,'ctl00_MC_PendingQA_ct')]");
            if (nodes == null) return "** No links found **";
            StringBuilder sb = new StringBuilder(nodes.Count);
            int rows = 0;
            foreach (HtmlNode node in nodes)
                {
                if (node.Id.EndsWith("_memberLink"))
                    {
                    if (rows == 5)
                        {
                        sb.AppendLine();
                        rows = 0;
                        }
                    string url = node.Attributes["href"].Value;
                    string mid = url.Substring(url.IndexOf("?mid=") + 5);
                    sb.AppendLine(userLink.Replace("%ID%", mid));
                    rows++;
                    }
                }
            return sb.ToString();
            }

History

2022-05-20 First Version

2022-05-20 Typos, and updated code (the version from my standalone app)

2022-05-20 BotReport Winforms app project source code (no Solution files) added.

2022-12-30 GenerateTimeStampFile.exe added to BIN folder of download.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)