How to Write a Spam Rule for Community Server 2008.5

Obviously you have wondered why I write frequent posts about writing spam rules for Community Server and you’re right. Part of this is related to my interest in Community Server while another part is related to having an enterprise online spam filter service like Waegis that primarily targets .NET sites including Community Server sites.  Moreover, Telligent has been applying major changes in the product especially in the field of spam blocking and these changes have affected my older posts about writing spam rules for Community Server.

But most likely you have heard about the recent release of Community Server 2008.5 Beta 1 as a milestone in 2008 lifecycle with major changes and new features but you wouldn’t know that behind the scenes this release replaces the fundamental of spam blocker mechanism in Community Server. A few days after announcing Community Server 2008.5, some Waegis clients asked me about a spam rule that works with this new version because my spam rule for Community Server 2008 was broken. After some initial evaluation on the spam rule, I believed that there is a problem that stops my spam rule from loading to the system and there was no ostensible reason to use as a start point, so like the past I contacted Wyatt Preul and he responded with some details about the changes.

He told me that the fundamental of spam rule development has changed in Community Server 2008.5 and I need to apply some updates in my code in order to make it compatible with the most recent build of the product. Here I’m going to update my prior posts about developing spam rules for Community Server hoping it can help others who are going to deal with the same stuff. For this post I return to my traditional minimum length spam rule that I developed for my prior examples and rewrite it again based on the new API.

ConfigurableContentScorerBase

ConfigurableContentScorerBase Strcuture In Community Server 2008.5 a spam rule is a class derived from ConfigurableContentScorerBase class available in CommunityServer.Spam namespace. This is an abstract base class with some properties and methods that must be overridden in your spam rules. Actually this class is a replacement for SpamRule base class and its derivations such as BlogSpamRule or ForumSpamRule in older versions.

While Telligent has tried to keep consistency between the structure of properties and methods in the new class with previous classes, there are still some changes that were not evadable and you need to deal with them.

Here is a brief description about properties that must be overridden:

And here is a short discussion about the methods that you need to override:

ScoreableContent

ScoreableContent Structure The other addition to the spam blocker system is the introduction of ScoreableContent class that replaces the use of Post class and its derivations in the blocker.

This class has some properties and methods that let you have a quick access to some properties that you need when working with spam rules. Beside some obvious properties, it has two properties named SourceObject and SourceType that respectively allow you to have access to the original post object and post type, so you can always cast these objects and use them in your code.

Example

Having this background, let me rewrite my minimum length spam rule again. I derive from ConfigurableContentScorerBase and override the required properties and methods.

using System;

using System.Collections.Generic;

using System.Text;

using CommunityServer.Spam;

using Telligent.DynamicConfiguration.Components;

using CommunityServer.Blogs.Components;

using CommunityServer.MediaGalleries.Components;

using CommunityServer.Components;

 

namespace MinLengthRule

{

    public class LengthRule : ConfigurableContentScorerBase

    {

        public static readonly Guid ruleID =

            new Guid("66A4BD1B-46FD-4cab-A17B-CC4E2F843740");

        public static readonly int defaultMinLength = 15;

        public static readonly int defaultPoints = 10;

 

        public override Guid ContentScorerId

        {

            get { return ruleID; }

        }

 

        public override string ScorerDescription

        {

            get { return "A spam rule to test the length of the content."; }

        }

 

        public override string ScorerName

        {

            get { return "LengthRule"; }

        }

 

        public override bool TryGetScore(ScoreableContent scoreableContent,

            out int score)

        {

            score = 0;

 

            try

            {

 

                int minLength = GetIntValue("length", defaultMinLength);

                int points = GetIntValue("points", defaultPoints);

 

                if (scoreableContent.SourceType == typeof(WeblogPost))

                {

                    WeblogPost post = scoreableContent.SourceObject as WeblogPost;

 

                    if (post.Body.Length < minLength)

                        score = (minLength - post.Body.Length) * points;

                }

            }

            catch (Exception ex)

            {

                EventLogs.Warn(ex.Message + ex.StackTrace,

                    "Spam Rules", 8001);

                return false;

            }

 

            return true;

        }

 

        public override PropertyGroup[] GetPropertyGroups()

        {

            PropertyGroup[] propertyGroups = new PropertyGroup[] {

                new PropertyGroup("lengthSettings", "Spam Settings", 1) };

 

            propertyGroups[0].Properties.Add(new Property

                ("length", "Minimum Length", PropertyType.Int,

                0, defaultMinLength.ToString()));

            propertyGroups[0].Properties.Add(new Property

                ("points", "Points", PropertyType.Int,

                1, defaultPoints.ToString()));

 

            return propertyGroups;

        }

    }

}

The fundamental of working with identifying properties and dynamic configuration is constant, so I don’t talk about them and refer you back to my post about building spam rules for Community Server 2008. The only point is about TryGetScore function where I cast my ScoreableContent to WeblogPost and set the score value, so this spam rule works with blog comment and trackbacks only.

Download

As always, you can grab the sample code for this post!

By the way, Waegis spam rule for Community Server 2008.5 is written and being tested privately, so you can keep an eye on Waegis blog for the public release to get your hands on it.

[advertisement] Axosoft OnTime 2008 is four developer tools in one: bug tracking, project wiki, feature management, and help desk. It manages your development process so developers can focus on coding. Installed or Hosted – Free Single-user license -- Free 30-day team trial.

No Comments : 09.17.08

Feedbacks

There are no comments yet...Kick things off by filling out the form below.

Leave a Comment