メールをテキストファイルとして保存する
ではYahoo!メールを受信してテキストファイルやCSVファイルとして保存するアプリを作成しました。今回は他のメールも受信できるようにします。
Gmailに対応させる
まずはGmailに挑戦。まずはメールアカウントにログインしてPOPを有効にする必要があります。そのためには
あとはGetMails()メソッドを書き換えて実行すればうまくいきそうです。
メソッドの内容は以下のページの内容とほとんど同じです。string server = “pop.gmail.com”; の部分だけ変えています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
public partial class Form1 : Form { List<Data> GetMails() { List<Data> datas = new List<Data>(); // 接続情報 GMail ここを変えただけ -------- string server = "pop.gmail.com"; int port = 995; // -------- string userid = textBoxId.Text; string pass = textBoxPass.Text; System.Net.IPAddress address = System.Net.Dns.GetHostEntry(server).AddressList[0]; TKMP.Net.IPopLogon logon = new TKMP.Net.BasicPopLogon(userid, pass); TKMP.Net.PopClient pop = new TKMP.Net.PopClient(logon, address, port); pop.AuthenticationProtocol = TKMP.Net.AuthenticationProtocols.SSL; pop.CertificateValidation += new TKMP.Net.CertificateValidationHandler(pop_CertificateValidation); if(!pop.Connect()) { MessageBox.Show("接続失敗"); return datas; } int mailcount = pop.MailDatas.Length; if(mailcount == 0) { MessageBox.Show("着信メールはありません"); return datas; } for(int i = 0; i < mailcount; i++) { TKMP.Net.MailData Mail = pop.MailDatas[i]; if(!Mail.ReadBody()) { MessageBox.Show("データ受信に失敗しました"); continue; } TKMP.Reader.MailReader reader = new TKMP.Reader.MailReader(Mail.DataStream, false); string subject = reader.HeaderCollection["Subject"]; string date = reader.HeaderCollection["Date"]; string mainText = reader.MainText + "\n"; datas.Add(new Data(subject, date, mainText)); } pop.Close(); MessageBox.Show("取得完了!"); return datas; } } |
ところがカンタンにできると思っていたらそうはいきませんでした。
失敗するのでなぜだろうと調べていたら「アクセスをブロックした」というメールが送られてきたのです。
安全性の低いアプリ(自作だからそうなるよね)はそのままだとブロックの対象になるのです。
上記の設定を変更すればアクセスは可能になります。
さくらインターネットの場合
上記コードの以下の部分だけ修正すれば対応できます。
1 2 |
string server = "XXXXXX.sakura.ne.jp"; int port = 995; |
エックスサーバーの場合
メールソフトの設定 | レンタルサーバー【エックスサーバー】
1 2 |
string server = "svXXXX.xserver.jp"; int port = 995; |
ということでGmailは設定を変更する必要がありましたが、それ以外はPOP/IMAPサーバー名を変更すればメールの受信が可能になります。
GUIを少し変更します。
メールサーバーもテキストボックスから設定できるようにします。アカウント名とパスワードは●で表示して他人から見られないようにします。
[メールを取得]をクリックするとメールボックスにあるメールを取得し、リストボックスにその一覧を表示させます。リストボックスのアイテムをクリックするとメールの件名、本文、受信日時が表示されるようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
public partial class Form1 : Form { private void buttonGetMails_Click(object sender, EventArgs e) { Datas = GetMails(); foreach(Data data in Datas) { listBox1.Items.Add(data.Subject); } } List<Data> GetMails() { List<Data> datas = new List<Data>(); string server = textBoxMailServer.Text; int port = int.Parse(textBoxPort.Text); string userid = textBoxId.Text; string pass = textBoxPass.Text; System.Net.IPAddress address = System.Net.Dns.GetHostEntry(server).AddressList[0]; TKMP.Net.IPopLogon logon = new TKMP.Net.BasicPopLogon(userid, pass); TKMP.Net.PopClient pop = new TKMP.Net.PopClient(logon, address, port); pop.AuthenticationProtocol = TKMP.Net.AuthenticationProtocols.SSL; pop.CertificateValidation += new TKMP.Net.CertificateValidationHandler(pop_CertificateValidation); if(!pop.Connect()) { MessageBox.Show("接続失敗"); return datas; } int mailcount = pop.MailDatas.Length; if(mailcount == 0) { MessageBox.Show("着信メールはありません"); return datas; } for(int i = 0; i < mailcount; i++) { TKMP.Net.MailData Mail = pop.MailDatas[i]; if(!Mail.ReadBody()) { MessageBox.Show("データ受信に失敗しました"); continue; } TKMP.Reader.MailReader reader = new TKMP.Reader.MailReader(Mail.DataStream, false); string subject = reader.HeaderCollection["Subject"]; string date = reader.HeaderCollection["Date"]; string mainText = reader.MainText + "\n"; datas.Add(new Data(subject, date, mainText)); } pop.Close(); MessageBox.Show("取得完了!"); return datas; } private void listBox1_SelectedIndexChanged(object sender, EventArgs e) { int index = listBox1.SelectedIndex; if(index == -1) return; Data data = Datas[index]; textBoxSubject.Text = data.Subject; textBoxDate.Text = data.DateText; richTextBox1.Text = data.MainText; } private void buttonMailsClear_Click(object sender, EventArgs e) { listBox1.Items.Clear(); Datas.Clear(); } } |
それから設定と取得したメールの内容も保存したり読み出しができるようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
public partial class Form1 : Form { private void buttonSaveXml_Click(object sender, EventArgs e) { SaveFileDialog dlg = new SaveFileDialog(); dlg.Filter = "メールデータ(*.xml)|*.xml"; dlg.DefaultExt = "xml"; if(dlg.ShowDialog() == DialogResult.OK) { Doc doc = new Doc(Datas, textBoxMailServer.Text, textBoxPort.Text, textBoxId.Text, textBoxPass.Text); System.Xml.Serialization.XmlSerializer xml = new System.Xml.Serialization.XmlSerializer(typeof(Doc)); System.IO.StreamWriter sw = new System.IO.StreamWriter(dlg.FileName); xml.Serialize(sw, doc); sw.Close(); } dlg.Dispose(); MessageBox.Show("保存完了"); } private void buttonLoadXml_Click(object sender, EventArgs e) { OpenFileDialog dlg = new OpenFileDialog(); if(dlg.ShowDialog() == DialogResult.OK) { System.Xml.Serialization.XmlSerializer xml = new System.Xml.Serialization.XmlSerializer(typeof(Doc)); System.IO.StreamReader sr = new System.IO.StreamReader(dlg.FileName); Doc doc =(Doc)xml.Deserialize(sr); sr.Close(); Datas = doc.Datas; textBoxMailServer.Text = doc.MailServer; textBoxPort.Text = doc.Port; textBoxId.Text = doc.Id; textBoxPass.Text = doc.Password; // 新しいメールを上側に表示させる Datas = Datas.OrderByDescending(x => x.DateText).ToList(); listBox1.Items.Clear(); foreach(Data data in Datas) { listBox1.Items.Add(data.Subject); } } dlg.Dispose(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class Doc { public Doc() { } public Doc(List<Data> datas, string mailServer, string port, string id, string password) { Datas = datas; MailServer = mailServer; Port = port; Id = id; Password = password; } public List<Data> Datas = null; // そのまま保存していいのか? public string MailServer = ""; public string Port = ""; public string Id = ""; public string Password = ""; } |
ところで毎回毎回、ログインのために必要な情報を入力するのは面倒です。この設定を保存しておきたいのですが、パスワードをそのままファイルに保存するのはよくありません。