Click here to Skip to main content
15,880,392 members
Articles / Programming Languages / C#

How to Create a Spam Filter or Automatic Category Sort Algorithm with Your Mail Application

Rate me:
Please Sign up or sign in to vote.
5.00/5 (9 votes)
29 Jul 2012MIT3 min read 40K   1.2K   19  
This article describes automatic category filters in mail applications.
In this article, you will learn how to create a spam filter on your mail application. You will also see how to filter your mail based on whether the mail tells about a particular topic or not.
using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using HigLabo.Net.Mail;

namespace HigLabo.Net.Smtp
{
    /// Represent smtp message.
    /// <summary>
    /// Represent smtp message.
    /// </summary>
    public class SmtpMessage : InternetTextMessage
    {
        private List<SmtpContent> _Contents;
        private List<String> _EncodeHeaderKeys = new List<String>();
        private List<MailAddress> _To = new List<MailAddress>();
        private List<MailAddress> _Cc = new List<MailAddress>();
        private List<MailAddress> _Bcc = new List<MailAddress>();
        private MailPriority _MailPriority = MailPriority.Normal;
        private String _BodyText = "";
        private Encoding _HeaderEncoding = Encoding.ASCII;
        private TransferEncoding _HeaderTransferEncoding = TransferEncoding.SevenBit;
        /// 宛先のメールアドレスのリストを取得します。
        /// <summary>
        /// 宛先のメールアドレスのリストを取得します。
        /// </summary>
        public List<MailAddress> To
        {
            get { return this._To; }
        }
        /// CCのメールアドレスのリストを取得します。
        /// <summary>
        /// CCのメールアドレスのリストを取得します。
        /// </summary>
        public List<MailAddress> Cc
        {
            get { return this._Cc; }
        }
        /// BCCのメールアドレスのリストを取得します。
        /// <summary>
        /// BCCのメールアドレスのリストを取得します。
        /// </summary>
        public List<MailAddress> Bcc
        {
            get { return this._Bcc; }
        }
        /// <summary>
        /// 
        /// </summary>
        public MailPriority Priority
        {
            get { return _MailPriority; }
            set { _MailPriority = value; }
        }
        /// HeaderのEncodingを取得または設定します。
        /// <summary>
        /// HeaderのEncodingを取得または設定します。
        /// </summary>
        public Encoding HeaderEncoding
        {
            get { return this._HeaderEncoding; }
            set { this._HeaderEncoding = value; }
        }
        /// HeaderのTransferEncodingを取得または設定します。
        /// <summary>
        /// HeaderのTransferEncodingを取得または設定します。
        /// </summary>
        public TransferEncoding HeaderTransferEncoding
        {
            get { return this._HeaderTransferEncoding; }
            set { this._HeaderTransferEncoding = value; }
        }
        /// ボディ部分のテキスト文字列を取得または設定します。
        /// <summary>
        /// ボディ部分のテキスト文字列を取得または設定します。
        /// </summary>
        public String BodyText
        {
            get { return this._BodyText; }
            set { this._BodyText = value; }
        }
        /// HTML形式のメールかどうかを示す値を取得または設定します。
        /// <summary>
        /// HTML形式のメールかどうかを示す値を取得または設定します。
        /// </summary>
        public new Boolean IsHtml
        {
            get { return base.IsHtml; }
            set { this.ContentType.Value = "text/html"; }
        }
        /// SmtpContentのコレクションを取得します。
        /// <summary>
        /// SmtpContentのコレクションを取得します。
        /// </summary>
        public List<SmtpContent> Contents
        {
            get { return this._Contents; }
        }
		/// <summary>
		/// 
		/// </summary>
        public SmtpMessage()
        {
            this.Initialize();
        }
		/// <summary>
		/// 
		/// </summary>
		/// <param name="mailFrom"></param>
		/// <param name="to"></param>
		/// <param name="cc"></param>
		/// <param name="subject"></param>
		/// <param name="bodyText"></param>
        public SmtpMessage(String mailFrom, String to, String cc, String subject, String bodyText)
        {
            this.Initialize();
            this.From = mailFrom;
            if (String.IsNullOrEmpty(to) == false)
            {
                this.To.Add(new MailAddress(to));
            }
            if (String.IsNullOrEmpty(cc) == false)
            {
                this.Cc.Add(new MailAddress(cc));
            }
            this.Subject = subject;
            this.BodyText = bodyText;
        }
        /// 初期化処理を行います。
        /// <summary>
        /// 初期化処理を行います。
        /// </summary>
        private void Initialize()
        {
            this._Contents = new List<SmtpContent>();

            this["MIME-Version"] = "1.0";
            
            if (CultureInfo.CurrentCulture.Name.StartsWith("ja") == true)
            {
                this.HeaderEncoding = Encoding.GetEncoding("iso-2022-jp");
                this.HeaderTransferEncoding = TransferEncoding.Base64;
                this.ContentEncoding = Encoding.GetEncoding("iso-2022-jp");
                this.ContentTransferEncoding = TransferEncoding.Base64;
            }
            this._EncodeHeaderKeys.Add("subject");
        }
        /// 実際に送信される文字列のデータを取得します。
        /// <summary>
        /// 実際に送信される文字列のデータを取得します。
        /// </summary>
        /// <returns></returns>
        public String GetDataText()
        {
            StringBuilder sb = new StringBuilder(1024);
            CultureInfo ci = CultureInfo.CurrentCulture;
            Field f = null;
            SmtpContent ct = null;
            String line = "";
            String bodyText = "";

            //ContentTransferEncoding
            f = InternetTextMessage.Field.FindField(this.Header, "Content-Transfer-Encoding");
            if (f == null)
            {
                f = new Field("Content-Transfer-Encoding", MailParser.ToTransferEncoding(this.ContentTransferEncoding));
                this.Header.Add(f);
            }
            else
            {
                f.Value = MailParser.ToTransferEncoding(this.ContentTransferEncoding);
            }

            for (int i = 0; i < this.Header.Count; i++)
            {
                f = this.Header[i];
                if (this._EncodeHeaderKeys.Contains(f.Key.ToLower()) == true)
                {
                    sb.AppendFormat("{0}: {1}{2}", f.Key
                        , MailParser.EncodeToMailHeaderLine(f.Value, this.HeaderTransferEncoding, this.HeaderEncoding
                        , MailParser.MaxCharCountPerRow - f.Key.Length - 2), MailParser.NewLine);
                }
                else if(f.Key.ToLower() != "content-type")
                {
                    sb.AppendFormat("{0}: {1}{2}", f.Key, f.Value, MailParser.NewLine);
                }
            }
            //Headerに設定されていない場合のみセットする
            //Priority
            f = Field.FindField(this.Header, "X-Priority");
            if (f == null)
            {
                sb.AppendFormat("X-Priority: {0}{1}", ((byte)this.Priority).ToString(), MailParser.NewLine);
            }
            //TO
            f = Field.FindField(this.Header, "To");
            if (f == null)
            {
                line = this.CreateMailAddressListText(this._To);
                if (String.IsNullOrEmpty(line) == false)
                {
                    sb.Append("To: ");
                    sb.Append(line);
                }
            }
            //CC
            f = Field.FindField(this.Header, "Cc");
            if (f == null)
            {
                line = this.CreateMailAddressListText(this._Cc);
                if (String.IsNullOrEmpty(line) == false)
                {
                    sb.Append("Cc: ");
                    sb.Append(line);
                }
            }

            if (this.Contents.Count > 0)
            {
                if (String.IsNullOrEmpty(this.MultiPartBoundary) == true)
                {
                    this.MultiPartBoundary = MailParser.GenerateBoundary();
                }
                //Multipartboundary
                sb.AppendFormat("Content-Type: multipart/mixed; boundary=\"{0}\"", this.MultiPartBoundary);
                sb.Append(MailParser.NewLine);
                sb.Append(MailParser.NewLine);

                //This is multi-part message in MIME format.
                sb.Append(MailParser.ThisIsMultiPartMessageInMimeFormat);
                sb.Append(MailParser.NewLine);
                //Add BodyText Content
                if (String.IsNullOrEmpty(this.BodyText) == false)
                {
                    ct = new SmtpContent();
                    if (this.IsHtml == true)
                    {
                        ct.LoadHtml(this.BodyText);
                    }
                    else
                    {
                        ct.LoadText(this.BodyText);
                    }
                    ct.ContentEncoding = this.ContentEncoding;
                    ct.ContentTransferEncoding = this.ContentTransferEncoding;
                    if (this.Contents.Exists(delegate(SmtpContent c) { return c.IsBody; }) == false)
                    {
                        sb.Append("--");
                        sb.Append(this.MultiPartBoundary);
                        sb.Append(MailParser.NewLine);
                        sb.Append(ct.Data);
                        sb.Append(MailParser.NewLine);
                    }
                }
                for (int i = 0; i < this._Contents.Count; i++)
                {
                    //Skip empty SmtpContent instance
                    if (String.IsNullOrEmpty(this._Contents[i].Data) == true) { continue; }
                    sb.Append("--");
                    sb.Append(this.MultiPartBoundary);
                    sb.Append(MailParser.NewLine);
                    sb.Append(this.Contents[i].Data);
                    sb.Append(MailParser.NewLine);
                }
                sb.Append(MailParser.NewLine);
                sb.AppendFormat("--{0}--", this.MultiPartBoundary);
            }
            else
            {
                sb.AppendFormat("Content-Type: {0}; charset=\"{1}\"", this.ContentType.Value, this.ContentEncoding.WebName);
                sb.Append(MailParser.NewLine);
                sb.Append(MailParser.NewLine);
                bodyText = MailParser.EncodeToMailBody(this.BodyText, this.ContentTransferEncoding, this.ContentEncoding);
				if (this.ContentTransferEncoding == TransferEncoding.SevenBit)
				{
                    sb.Append(bodyText);
				}
				else
				{
                    for (int i = 0; i < bodyText.Length; i++)
					{
						if (i > 0 && i % 76 == 0)
						{
							sb.Append(MailParser.NewLine);
						}
                        //Is current index is first char of line
                        if (i == 0 || (i > 2 && bodyText[i - 2] == '\r' && bodyText[i - 1] == '\n'))
                        {
                            if (bodyText[i] == '.')
                            {
                                sb.Append(".");
                            }
                        }
                        sb.Append(bodyText[i]);
					}
				}
            }
            sb.Append(MailParser.NewLine);
            sb.Append(MailParser.NewLine);
            sb.Append(".");
            sb.Append(MailParser.NewLine);

            return sb.ToString();
        }
        /// ユーザー名とメールアドレスをFromにセットします。
        /// <summary>
        /// ユーザー名とメールアドレスをFromにセットします。
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="mailAddress"></param>
        public void SetFromMailAddress(String userName, String mailAddress)
        {
            this.From = SmtpMessage.CreateFromMailAddress(userName, mailAddress); ;
        }
        /// ユーザー名とメールアドレスを示す文字列を生成します。
        /// <summary>
        /// ユーザー名とメールアドレスを示す文字列を生成します。
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="mailAddress"></param>
        public static String CreateFromMailAddress(String userName, String mailAddress)
        {
            return String.Format("\"{0}\" <{1}>", userName, mailAddress);
        }
        /// メールアドレスの一覧データからメールアドレスの文字列を生成します。
        /// <summary>
        /// メールアドレスの一覧データからメールアドレスの文字列を生成します。
        /// </summary>
        /// <param name="mailAddressList"></param>
        /// <returns></returns>
        private String CreateMailAddressListText(List<MailAddress> mailAddressList)
        {
            StringBuilder sb = new StringBuilder();
            List<MailAddress> l = mailAddressList;
            String s = "";

            for (int i = 0; i < l.Count; i++)
            {
                sb.AppendFormat("{0}{1}", s, l[i].ToEncodeString().Trim());
                sb.Append(MailParser.NewLine);

                s = "\t, ";
            }
            return sb.ToString();
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
CEO TinyBetter, Inc
Japan Japan
I'm a CEO of TinyBetter, Inc in Japan.

Comments and Discussions