.net 獲取郵箱郵件列表和內容

sands發表於2018-04-10

需求:

       最近專案裡遇到了個問題,對方沒有提供直接獲取資料來源的api介面,而是通過郵件發資料的。這就需要接收郵件後解析郵件內容獲得資料。

 

分析:

     想在程式碼裡實時獲取郵件,可以通過郵件的幾個協議來實現,常用的幾個協議有POP3協議,SMTP協議,IAMP協議。

1. pop3:(Post Office Protocal 3),3是版本,是目前使用的主流版本。POP3是客戶-伺服器協議,其中電子郵件的接收需要一個收件伺服器,郵件下載到本地計算機上所有一次,從而使離線閱讀更輕鬆,可以指定是否保留副本的郵件在伺服器上。 

2. SMTP(Simple Mail Transfer Protocal):簡單Mail傳輸協議,是個請求/響應協議,它監聽25號埠,用於接收使用者的Mail請求,並與遠端Mail伺服器建立SMTP連線。 獨立於特定的傳輸子系統,它可以是電子郵件從客戶機傳輸到伺服器;也可以是從某一個伺服器傳輸到另一個伺服器;且只需要可靠有序的資料流通道支援。SMTP 重要特性之一是其能跨越網路傳輸郵件,即SMTP 郵件中繼。通常,一個網路可以由公用網際網路上 TCP 可相互訪問的主機、防火牆分隔的 TCP/IP 網路上 TCP 可相互訪問的主機,及其它 LAN/WAN 中的主機利用非 TCP 傳輸層協議組成。使用 SMTP,可實現相同網路上處理機之間的郵件傳輸,也可通過中繼器或閘道器實現某處理機與其它網路之間的郵件傳輸。

3. IMAP ( Internet訊息訪問協議)是一種標準協議,用於訪問電子郵件從您的本地伺服器。的IMAP (最新版本的IMAP第4版)是一個客戶機/伺服器協議在電子郵件收到併為您舉行的由您的因特網伺服器。您(或您的電子郵件客戶端)可以檢視剛才的標題和發件人的信件,然後決定是否下載該郵件。您還可以建立和操縱多個資料夾或郵箱的伺服器上,刪除郵件,或尋找某些地區或整個說明。

 imap協議可以實現獲取郵件狀態,並且操作伺服器上的郵件,而POP3不能,

 

 程式設計思路是:

     1 從郵件伺服器上獲取未讀郵件,

     2 進行解析操作,

     3 標記郵件為已讀。

     4 將郵件資料推送到訊息佇列中

     5 部署多個訊息佇列的消費者元件,對郵件內容進行二次處理,進行業務邏輯處理。

     郵件接收的元件其實在前三步就已經結束了。 業務處理的服務可以部署多個,但是接收郵件的元件相當於一個客戶端,只作為郵件的接收和轉發資料,這裡部署了一個,屬於單點的,鑑於服務暫時沒多少壓力,先只做了異常報警通知,沒有去部署多個。

實現:

       .net下有現成的開源元件LumiSoft.Net.IMAP

       開源元件下載地址 http://www.lumisoft.ee/lswww/download/downloads/

       整理後的主要程式碼        public void imapdemo()

        {
            var mailServer = "imap.exmail.qq.com";//也可以使用其他郵箱伺服器
            var username = "登入賬號";
            var password = "登入密碼";

            using (IMAP_Client client = new IMAP_Client())
            {
                client.Connect(mailServer, 993, true);
                client.Login(username, password);
                client.SelectFolder("INBOX");//開啟收件箱
                int[] unseen_ids = client.Search(false, Encoding.UTF8, new IMAP_Search_Key_Unseen());
                if (unseen_ids.Count() == 0)
                {
                    return;
                }
                IMAP_t_SeqSet sequence = IMAP_t_SeqSet.Parse(string.Join(",", unseen_ids));
                var items = new IMAP_t_Fetch_i[] { new IMAP_t_Fetch_i_Envelope(), new IMAP_t_Fetch_i_Uid(), new IMAP_t_Fetch_i_Flags(), new IMAP_t_Fetch_i_Flags(), new IMAP_t_Fetch_i_InternalDate(), new IMAP_t_Fetch_i_Rfc822(), new IMAP_t_Fetch_i_BodyStructure() };

                client.Fetch(false, sequence, items, (s, e) =>
                {
                    try
                    {
                        var email = e.Value as IMAP_r_u_Fetch;

                        if (email.Rfc822 != null)
                        {
                            email.Rfc822.Stream.Position = 0;
                            var mine = Mail_Message.ParseFromStream(email.Rfc822.Stream);
                            email.Rfc822.Stream.Close();

                            var files = mine.Attachments;
                            var fileurls = new List<KeyValuePair<string, string>>();
                            foreach (var item in files)
                            {
                                var name = item.ContentType.Param_Name;
                                using (MemoryStream stream = new MemoryStream(item.DataToByte()))
                                {
                                    //附件可以上傳到阿里雲上或者其他地方
                                    var key = "";// AliOss.Upload(stream);
                                    fileurls.Add(new KeyValuePair<string, string>(name, key));//檔名,地址
                                }
                            }

//處理自定義業務邏輯 var Title = email.Envelope.Subject; var CreateTime = email.InternalDate.Date; var BodyText = mine.BodyText; var BodyHtmlText = mine.BodyHtmlText; var File = string.Join(",", fileurls.Select(x => x.Value));

//處理完的郵件標記為已讀 var sequenceSet = new IMAP_SequenceSet(); sequenceSet.Parse(string.Join(",", email.SeqNo)); client.StoreMessageFlags(false, sequenceSet, IMAP_Flags_SetType.Add, IMAP_MessageFlags.Seen);

                //-------郵件內容入訊息佇列------------ } }
catch (Exception ex) { throw ex; } }); } }

 

相關文章