Keyvan Nayyeri

God breathing through me

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:

  • ContentScorerId: A unique identifier for the content scorer that is actually a GUID and is similar to the identifier that you were assigning to configurable add-ons in first version Community Server 2008.
  • ScorerDescription: String description of the spam rule (content scorer).
  • ScorerName: String name of the spam rule (content scorer).

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

  • TryGetScore: In structure this method is very similar to TryParse method for built-in value types in the .NET Framework and gets two parameters: the first one is an instance of the ScoreableContent that can be used to extract data for incoming content and the other parameter is a return integer parameter that carries the spam score assigned to the content. This method returns a Boolean value that specifies if the method has been successfully run or not.
  • GetPropertyGroups: This is just similar to GetAvailablePropertyGroups function in prior version and returns an array of PropertyGroup objects to be used for dynamic configuration.

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.

0 Comments

Leave a Comment





Ads Powered by Lake Quincy Media Network