LumiSoft.Net
LumiSoft Forum
Source code
Examples
ImapXに比べてこなれていないObject Modelなのでとっつきにくいけれど、慣れればImapX以上の柔軟さがあるし、何よりOSSなので自分で問題解決できるのが良い。
コードはこんな感じ。
// すべてのメールを取得する try { using (var imap = new IMAP_Client()) { imap.Logger = new Logger(); imap.Logger.WriteLog += (s, e) => Console.WriteLine(e.LogEntry.Text); imap.Connect("imap.gmail.com", 993, true); imap.Login("username", "password"); imap.SelectFolder("INBOX"); var fetchHandler = new IMAP_Client_FetchHandler(); fetchHandler.NextMessage += (s, e) => { // 次のメッセージ Console.WriteLine(""); Console.WriteLine(""); Console.WriteLine("New message"); }; fetchHandler.Envelope += (s, e) => { // To, Fromとか Console.WriteLine("Envelope"); var envelope = e.Value; var from = ""; if (envelope.From != null) from = envelope.From.ToList().Select(x => x.ToString()).Aggregate((x, y) => string.Format("{0};{1}", x, y)); else from = "none"; Console.WriteLine(from); var subject = envelope.Subject ?? "none"; Console.WriteLine(subject); }; fetchHandler.Flags += (s, e) => { // フラグ(SEEN, UNSEENとか) e.Value.ToList().ForEach(f => Console.WriteLine(f)); }; fetchHandler.InternalDate += (s, e) => { // 日付 Console.WriteLine(e.Value.ToString()); }; fetchHandler.Rfc822Size += (s, e) => { // サイズ Console.WriteLine(((decimal)(e.Value / (decimal)1000)).ToString("f2") + " kb"); }; fetchHandler.UID += (s, e) => { // メールID Console.WriteLine(e.Value); }; var sequence = new IMAP_SequenceSet(); sequence.Parse("1:*"); // 取得する範囲を指定する // ※メールが15通あるとして // 2,4:7,9,12:*を指定すると // 2,4,5,6,7,9,12,13,14,15の順番のメールが取得できる // 詳細はIMAP_SequenceSetを参照のこと // 第一引数は指定のsequenceがUIDかどうかの判定用。UIDを指定する場合もIMAP_SequenceSetの記述は変わらない // 第三引数に指定したものがサーバーから取得され、値の解析後、fetchHandlerがコールバックされる imap.Fetch(false, sequence, new IMAP_Fetch_DataItem[] { new IMAP_Fetch_DataItem_Envelope(), new IMAP_Fetch_DataItem_Flags(), new IMAP_Fetch_DataItem_InternalDate(), new IMAP_Fetch_DataItem_Rfc822Size(), new IMAP_Fetch_DataItem_Uid() }, fetchHandler); } } catch (Exception x) { Console.WriteLine(string.Format("IMAP server returned : {0}", x.Message)); }
一見して分かる通りかなり癖があるのでとっつきにくい部分もあるが、慣れてしまえば細かいところまで制御できるので非常に有用だ。
もうひとつサンプルとして未読メッセージのみ取得する方法を紹介しておく。
try { using (var imap = new IMAP_Client()) { imap.Logger = new Logger(); imap.Logger.WriteLog += (s, e) => Console.WriteLine(e.LogEntry.Text); imap.Connect("imap.gmail.com", 993, true); imap.Login("username", "password"); imap.SelectFolder("INBOX"); // 未読のものだけ取得 var unseenMessages = imap.Search(false, "", "unseen"); unseenMessages.ToList().ForEach(uid => { var seqSet = new IMAP_SequenceSet(); seqSet.Parse(uid.ToString()); // Bodyのみハンドル var fetchHandler = new IMAP_Client_FetchHandler(); fetchHandler.Rfc822 += (s, e) => { var storeStream = new MemoryStream(); e.Stream = storeStream; e.StoringCompleted += (s2, e2) => { storeStream.Position = 0; var mime = Mail_Message.ParseFromStream(storeStream); Console.WriteLine("Attachment"); foreach (var entity in mime.Attachments) { if (entity.ContentDisposition != null && entity.ContentDisposition.Param_FileName != null) { // 添付ファイルの保存 var path = Path.Combine(@"C:\", entity.ContentDisposition.Param_FileName); File.WriteAllBytes(path,((MIME_b_SinglepartBase)entity.Body).Data); Console.WriteLine(string.Format("{0} saved", entity.ContentDisposition.Param_FileName)); } else { Console.WriteLine("untitled"); } } if (mime.BodyText != null) Console.WriteLine(mime.BodyText); // おまけ // テスト用に今回の処理で既読メールになったのを未読メールに戻す imap.StoreMessageFlags(true, seqSet, IMAP_Flags_SetType.Replace, IMAP_MessageFlags.Recent); }; }; imap.Fetch(true, seqSet, new IMAP_Fetch_DataItem[] { new IMAP_Fetch_DataItem_Rfc822() },fetchHandler); }); } } catch (Exception x) { Console.WriteLine(string.Format("IMAP server returned : {0}", x.Message)); }