質問したい事があったので書込みしました。
Delphiで簡易メール受信探知プログラム(?)を作りたいと思っています。
が、メール関連で手元に参考になる文献が全く無く、知識も乏しく困っています。
以下の事をするプログラムを作りたいと思ってます。
バックグラウンドで実行
↓
受信メールを探知
↓
開封せずに、タイトルとアドレス、受信日時だけを取得
(Windows純正メーラーからメールを開けるようにする為、受信メールには一切手を加えない)
↓
アドレスを検索して、指定した、複数の特定のアドレスのみを、
データベースにタイトル、アドレス、受信日時を記録、
チャイムを鳴らす
↓
待機、最初に戻る
というのを作りたいと思っています
以上をする為に、参考になる文献、HP、必要なコンポーネント名等、などがあったら教えて貰えないでしょうか?
また、技術的に初心者でも可能でしょうか?
また、取得した時点で他のメーラーからの取得が出来なくなってしまわないでしょうか?
また、上記にも増してインターネット関連に疎い為、全く解らず困っています。
教えていただけると助かります。
それではよろしくお願いしますm(__)m。
環境書き忘れました。
WinXP SP3 Delphi7PRO、又はTurboDelphi2006(無償版)です。
IndyのTIdPOP3 を使うのはいかがですか?
IdPOP3でメールチェックし送信者を知りたいがエラー
https://www.petitmonte.com/bbs/answers?question_id=6536
自宅にネット回線が無いので、
携帯から書いています。
igyさんありがとうございます、
まさにそれでした!
まだ作り始めですが、ある程度思い通りになりました。
indyて非常に便利なのですね。
タイトルと送信元の取得は成功したのですが、
送信日時の取得が解りません。
送信日時はメールの情報に含まれて無いのでしょうか?
明日は書き込めそうにないですが、進展があったら予定が終わり次第書き込みにきます。
>送信日時の取得が解りません。
TIdMessage の Date プロパティ はいかがでしょう?
# Dephi7 Proをお持ちであれば、Indy関連のヘルプも日本語で
# 記述されていますので、ヘルプを参照するのもよいかもしれません。
igyさんありがとうございます、
とても助かります^^。
早速組み込んでみました。
こちらの方でも、Msg.Headers.Strings[6]を使った取得方法が判りました。
こちらのは何故か、indyのヘルプは英文でした…
正確なバージョンは、Delphi 7 Studio Professionalでした^^;
同じDelphi7Proでも違うんですね…。
試しの試作段階ですが、以下まで出来上がりました。
後はデータベースを組んで、処理を作ってくだけです。
こんなに早くメイン部分が出来上がるとは思いませんでした^^;
それではありがとうございましたm(__)m。
procedure TForm1.Button1Click(Sender: TObject);
var
Msg : TIdMessage;
i : integer;
begin
memo1.Lines.Clear;
IdPOP31.Host := 'Pop3アドレス';
IdPOP31.Port := 110;
IdPOP31.Username := 'ユーザーネーム';
IdPOP31.Password := 'パスワード';
IdPOP31.Connect;
for i := 1 to IdPOP31.CheckMessages do begin
Msg := TIdMessage.Create(Self);
IdPOP31.Retrieve(i, Msg);
Memo1.Lines.Add(Msg.Subject{タイトル});
Memo1.Lines.Add(Msg.From.Text{送信者});
Memo1.Lines.Add(inttostr(IdPOP31.CheckMessages{未開封メール数}));
Memo1.Lines.Add(Msg.Headers.Strings[6]{送信日時});
Memo1.Lines.Add(datetostr(msg.Date{送信日}));
end;
IdPOP31.Disconnect;
end;
>こちらのは何故か、indyのヘルプは英文でした…
>正確なバージョンは、Delphi 7 Studio Professionalでした^^;
>同じDelphi7Proでも違うんですね…。
Delphi7リリース時はIndyのヘルプは英語のものでしたが、
その後、すぐアップデートが出てた気がします。
Delphi Registered User Downloads
http://cc.embarcadero.com/reg/delphi
には、ありませんが、
ダウンロードファイル - Delphi
http://support.codegear.com/jp/article/35932
から
Delphi 7 - Indy ヘルプファイル・アップデート
がダウンロードできるようです。
igyさんありがとうございます、
ヘルプをインストールしたところ、きちんと日本語表示なりました。
組んでみたところ、早速問題が出ました。
上記のプログラムだと、メール取得時にメールを開いてしまうようです。
メールを開かずに題名やアドレスを、あるいは、メールを取得した後で再びメールを未読に戻す方法は無いのでしょうか?
よろしくお願いしますm(__)m。
>上記のプログラムだと、メール取得時にメールを開いてしまうようです。
試していませんが、
Retrieve メソッドではなく、ReceiveHeader メソッド を使った場合は、どうなりますか?
訂正です。
×:ReceiveHeader メソッド
○:RetrieveHeader メソッド
igy毎回さんありがとうございますm(__)m、
RetrieveHeaderでメールを開かずに、
タイトルと時間、アドレスを取るのに成功しました。
後はこれで何とかなりそうです。
また何かあったらよろしくお願いしますm(__)m。
それではありがとうございました。
毎回ありがとうございます、
indyのメモリリークと思われるバグでつまづいたので、
先ほど、Indyを最新のIndy10に更新したのですが、
今度は以下のエラーメッセージが出るようになりました。
Delphiのバージョンは7PROです。
alreedy connected.
どのような意味のエラーなのでしょうか?
教えていただけると助かります。
それではよろしくお願いします。
接続済みなのにまた接続しようとしたとか?
これ以上は実際のソースを見られない者には答えようがない。
基本的にSMTPポートに同時にログインできるアカウントは
一つなので(出来るサーバーもあるかもしれませんけど)
「メインのメーラーの受信の邪魔をせずに」は難しいと
思いますよ。
メインのメーラーでメール受信している間はIndyだろうと
ログイン出来ないと思います。逆もしかり。
リトライして回避が基本です。
「TELNET SMTP」で検索して見ると良いかもしれません。
RFC2821も調べてみて下さい。
メーラーもIndyもやってる事は同じです。ただのテキスト
送受信です。
読んで字のごとしさん、多分無理かもさん、ありがとうございます。
メールやインターネットは殆ど判らず、思ったよりも苦戦しています。
メール受信を自動通知してくれるプロパティやメゾットがあると便利なのですが、
今は試しのプログラムですが、ほぼ上記のプログラムを無理矢理タイマーでループさせてます。
メールは、今は自分のヤフーメールで試しています。
作成したいソフトではプララのメールを予定してます。
まだプララの設定では試してないので判らないです。
以下が問題のプログラムです。
今度はFormShowでButton1を読み込んで、そこからタイマーで5秒間隔でButton2を連続実行しています。
何回か連続実行された後「invoild passwad」という、パスワードが無効ですといった感じのエラーが出ます。
やはり下のコードは無理があるのでしょうか?
procedure TForm1.Button1Click(Sender: TObject);
var
Msg : TIdMessage;
i : integer;
begin
memo1.Lines.Clear;
IdPOP31.Host := 'pop3アドレス';
IdPOP31.Port := 110;
IdPOP31.Username := 'ユーザーネーム';
IdPOP31.Password := 'パスワード';
IdPOP31.Connect;
for i := 1 to IdPOP31.CheckMessages do begin
Msg := TIdMessage.Create(Self);
IdPOP31.RetrieveHeader(i, Msg);
//数件の未開封があった場合、変数Sの値は毎回変化する
//これでは一件しか記録できない
//受信データ取得
s1 := Msg.Subject{タイトル};
s2 := Msg.From.Text{送信者};
s3 := inttostr(IdPOP31.CheckMessages{未開封メール数});
s4 := Msg.Headers.Strings[6]{送信日時};
s5 := datetostr(msg.Date{送信日});
memo1.Lines.Add(s1);
memo1.Lines.Add(s2);
memo1.Lines.Add(s3);
memo1.Lines.Add(s4);
memo1.Lines.Add(s5);
end;
IdPOP31.Disconnect;
timer1.Enabled := true;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
Msg : TIdMessage;
i : integer;
begin
memo1.Lines.Clear;
IdPOP31.Connect;
for i := 1 to IdPOP31.CheckMessages do begin
Msg := TIdMessage.Create(Self);
IdPOP31.RetrieveHeader(i, Msg);
//受信データ取得
s1 := Msg.Subject{タイトル};
s2 := Msg.From.Text{送信者};
s3 := inttostr(IdPOP31.CheckMessages{未開封メール数});
s4 := Msg.Headers.Strings[6]{送信日時};
s5 := datetostr(msg.Date{送信日});
memo1.Lines.Add(s1);
memo1.Lines.Add(s2);
memo1.Lines.Add(s3);
memo1.Lines.Add(s4);
memo1.Lines.Add(s5);
end;
IdPOP31.Disconnect;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
Button1Click(Sender);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Button2Click(Sender);
end;
メールのチェック中にタイマーイベントが発生してしまうと言う事はありませんか?
(つまり、メールのチェックに5秒以上かかってしまう)
念のためタイマーイベントを
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
try
Button2Click(Sender);
finally
Timer1.Enabled := True;
end
end;
としてみてはどうでしょう。(ハズレの可能性が高いですが)
Questさんありがとうございます、
早速試してみました。
何分間か実行して放置してみたのですが、無事動作しているみたいです。
何とかなりました、ありがとうございますm(__)m。
Questさんのご指摘した通りだったみたいです。
Try文はExceptしか使った事がなかったのですが、
Fainaryはこういう風に使うのですね^^。
勉強になりました^^。
データベース登録部分は殆ど完成しているので、
あとはこれを組み込むだけです。
また何かエラーがでたら(多分出ると思いますが^^;)、よろしくお願いします。
それではありがとうございましたm(__)m。
皆さんありがとうございます、
先程完成しました。
今の所正常動作しています。
殆どが教えて貰った事で、
自分の実力以上のものが作れました^^。
大変助かりました。
今回もありがとうございましたm(__)m。
以下が完成したコードです。
procedure TForm1.FormShow(Sender: TObject);
var
s:string;
begin
//変数初期化
s1 := ''; s2 := ''; s3 := ''; s4 := ''; s5 := ''; s6 := '';
//データベースアドレス設定
table1.DatabaseName := ExtractFileDir( Paramstr(0) );
Query1.DatabaseName := ExtractFileDir( Paramstr(0) );
try
table1.Open;
except
table1.CreateTable;
table1.Open;
end;
Button1Click(Sender);
caption := 'メール受信を監視しています';
s := '';
while 1 > 0 do begin
if s = table1.fieldbyname('送信日時詳細').AsString then
exit;
ListBox1.Items.Add(table1.fieldbyname('タイトル').asstring+ ' ' +
table1.fieldbyname('送信者').asstring + ' ' +
table1.fieldbyname('送信日時詳細').AsString);
s := table1.fieldbyname('送信日時詳細').AsString;
table1.Next;
end;
table1.Close;
table1.open;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Msg : TIdMessage;
i : integer;
begin
application.Title := 'メールチェッカー';
listbox1.Clear;
IdPOP31.Host := 'POP3アドレス';
IdPOP31.Port := 110;
IdPOP31.Username := 'ユーザー名';
IdPOP31.Password := 'パスワード';
IdPOP31.Connect;
//if 0 = idpop31.CheckMessages then
//exit;
for i := 1 to IdPOP31.CheckMessages do begin
Msg := TIdMessage.Create(Self);
IdPOP31.RetrieveHeader(i, Msg);
//受信データ取得
s1 := Msg.Subject{タイトル};
s2 := Msg.From.Text{送信者};
s3 := inttostr(IdPOP31.CheckMessages{未開封メール数});
s4 := Msg.Headers.Strings[6]{送信日時};
s5 := datetostr(msg.Date{送信日});
if s2 = 'メールアドレス1' then
sw1 := true;
if s2 = 'メールアドレス2' then
sw1 := true;
if SW1 then begin
//データ検索
Query1.SQL.Text := 'SELECT COUNT(*) FROM メールお知らせ WHERE 送信日時詳細 = "'
+ S4 + '";';
Query1.Open;
if 0 = Query1.fieldbyname('COUNT(*)').AsInteger then begin
//データベース登録}
application.Title := '受信しました';
with table1 do begin
Insert;
Edit;
FieldByName('タイトル').AsString := s1;
FieldByName('From').AsString := s2;
FieldByName('送信日時詳細').AsString := s4;
FieldByName('送信日').AsString := s5;
if s2 = 'メールアドレス1' then
FieldByName('送信者').AsString := '1さん';
if s2 = 'メールアドレス2' then
FieldByName('送信者').AsString := '2さん';
post;
sw1 := false;
timer2.Enabled := true;//チャイムを鳴らす
end;
end;
end;
end;
IdPOP31.Disconnect;
ListBox1.Items.Add(table1.fieldbyname('タイトル').asstring+ ' ' +
table1.fieldbyname('送信者').asstring + ' ' +
table1.fieldbyname('送信日時詳細').AsString);
timer1.Enabled := true;
form1.WindowState := wsMinimized;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
Msg : TIdMessage;
i : integer;
begin
IdPOP31.Connect;
for i := 1 to IdPOP31.CheckMessages do begin
Msg := TIdMessage.Create(Self);
IdPOP31.RetrieveHeader(i, Msg);
//受信データ取得
s1 := Msg.Subject{タイトル};
s2 := Msg.From.Text{送信者};
s3 := inttostr(IdPOP31.CheckMessages{未開封メール数});
s4 := Msg.Headers.Strings[6]{送信日時};
s5 := datetostr(msg.Date{送信日});
if s2 = 'メールアドレス1' then
sw1 := true;
if s2 = 'メールアドレス2' then
sw1 := true;
if sw1 then
begin
edit1.Text := s1;
//データ検索
Query1.SQL.Text := 'SELECT COUNT(*) FROM メールお知らせ WHERE 送信日時詳細 = "'
+ S4 + '";';
Query1.Open;
if 0 = Query1.fieldbyname('COUNT(*)').AsInteger then begin
//データベース登録}
application.Title := '受信しました';
with table1 do begin
ListBox1.Items.Add(table1.fieldbyname('タイトル').asstring+ ' ' +
table1.fieldbyname('送信者').asstring + ' ' +
table1.fieldbyname('送信日時詳細').AsString);
Insert;
Edit;
FieldByName('タイトル').AsString := s1;
FieldByName('From').AsString := s2;
FieldByName('送信日時詳細').AsString := s4;
FieldByName('送信日').AsString := s5;
if s2 = 'メールアドレス1' then
FieldByName('送信者').AsString := '1さん';
if s2 = 'メールアドレス2' then
FieldByName('送信者').AsString := '2さん';
post;
sw1 := false;
timer2.Enabled := true;//チャイムを鳴らす
end;
end;
end;
end;
IdPOP31.Disconnect;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
timer1.Enabled := false;
try
Button2Click(Sender);
finally
timer1.Enabled := true;
end;
i := i +1;
caption := inttostr(i);
end;
procedure TForm1.Timer2Timer(Sender: TObject);
begin
messagebeep(mb_ok);
if count1 = 5 then begin
timer2.Enabled := false;
count1 := 0;
end;
count1 := count1 + 1;
end;
ツイート | ![]() |