Article Moderation/Abuse Management

The abuse plugin automates abuse detection to prevent SPAM and other abuse from entering the platform. Individual abuse detectors handle events applicable to their abuse detection logic and notify the abuse service when abuse is detected.

The IAbuseCheckingContentType interface defines the methods necessary to support the Abuse Service. Content types implementing this service can be marked as abusive, hidden if enough marks are added, and moderated using the abuse UI.

Why Should I Allow My Content to be Marked as Abusive?

To help promote clean and honest community members. Those who are responsible for questionable content are emailed that their content is being considered abusive and can appeal the finding in the email.

Creating an Abuse Plugin

In this sample we build upon the Application/Content sample. It is important to note that one or more Core Services can be implemented in the same IContentType class.

We took the IContentType implementation and further extended the IAbuseCheckingContentType interface.

using System;
using System.Collections.Generic;
using Telligent.Evolution.Extensibility.Content.Version1;
using Telligent.Evolution.Extensions.Lists.Data;
using IContent = Telligent.Evolution.Extensibility.Content.Version1.IContent;

namespace Telligent.Evolution.Extensions.Lists
{
    public interface ILinkItemContentType : IContentType, IAbuseCheckingContentType
    {
        IContentStateChanges _contentState = null;
        
        #region IPlugin
        
        //...
        
        #endregion
        
        #region IContentType

        //...

        #endregion
        
        #region IAbuseCheckingContentType
        
        //...
        
        #endregion
    }
}    

When a piece of content is first flagged as abusive the ContentSuspectedAbusive method is called. Here the intention is to temporarily disable the content. So we set the IsEnabled property of the LinkItem to false;

public void ContentSuspectedAbusive(Guid abuseId, Guid contentId)
{
    var content = LinksData.GetLink(contentId);
    if (content == null) return;

    content.IsEnabled = false;
}

After the user is notified that their content was flagged they are allowed to appeal the action. If a moderator accepts the repeal they can approve the content and reinstate it back into the platform. This is when the ContentFoundNotAbusive method is executed and the IsEnabled flag can be set back to true;

public void ContentFoundNotAbusive(Guid abuseId, Guid contentId)
{
    var content = LinksData.GetLink(contentId);
    if (content == null) return;

    content.IsEnabled = true;
}

On the other hand if the content is deemed inappropriate for the community. Then the ContentConfirmedAbusive method is called and the content should be permanently removed or deleted.

public void ContentConfirmedAbusive(Guid abuseId, Guid contentId)
{
    LinksData.DeleteLink(contentId);
}

In most cases when the content is marked as abusive you want to trim the result sets of the abusive content. In order for the platform to retrieve the disabled content a GetHiddenContent method is required. Here you want to make sure those mechanisms are disabled and the content can be returned.

public IContent GetHiddenContent(Guid contentId)
{
    return LinksData.GetLink(contentId);
}

Here is the full sample.

using System;
using System.Collections.Generic;
using Telligent.Evolution.Extensibility.Content.Version1;
using Telligent.Evolution.Extensions.Lists.Data;
using IContent = Telligent.Evolution.Extensibility.Content.Version1.IContent;

namespace Samples.Links
{
    public class LinkItemContentType : IAbuseCheckingContentType
    {
        IContentStateChanges _contentState = null;

        #region IPlugin Members

        public string Description
        {
            get { return "Items in a Links collection"; }
        }

        public void Initialize()
        {
        
        }

        public string Name
        {
            get { return "Link Items"; }
        }
        
        #endregion

        #region IContentType Members

        public Guid[] ApplicationTypes
        {
            get { return new Guid[] { ContentTypes.LinksApplicationId }; }
        }

        public void AttachChangeEvents(IContentStateChanges stateChanges)
        {
            _contentState = stateChanges;
        }

        public Guid ContentTypeId
        {
            get { return ContentTypes.LinksItemId; }
        }

        public string ContentTypeName
        {
            get { return "Links Item"; }
        }

        public IContent Get(Guid contentId)
        {
            return LinksData.GetLink(contentId);
        }

        #endregion

        #region IAbuseCheckingContentType

        public List<int> GetReviewBoardUsers(Guid contentId)
        {
            //Deprecated: The service now uses the group or site Manage Abuse permission
            return null;
        }

        public bool CanUserReviewAppeals(Guid contentId, int userId)
        {
            //Deprecated: The service now uses the group or site Manage Abuse permission
            return false;
        }

        public void ContentSuspectedAbusive(Guid abuseId, Guid contentId)
        {
            var content = LinksData.GetLink(contentId);
            if (content == null) return;

            content.IsEnabled = false;
        }

        public void ContentFoundNotAbusive(Guid abuseId, Guid contentId)
        {
            var content = LinksData.GetLink(contentId);
            if (content == null) return;

            content.IsEnabled = true;
        }

        public void ContentConfirmedAbusive(Guid abuseId, Guid contentId)
        {
            LinksData.DeleteLink(contentId);
        }

        public IContent GetHiddenContent(Guid contentId)
        {
            return LinksData.GetLink(contentId);
        }

        #endregion
    }
}