Delphi の IdImap4 で IDLE

Delphi の Indy IMAP4クライアント(TIdImap4) で IDLE (メール受信を監視するコード)
ChatGPT や Gemini で間違ったコードばかり教えてくれるので、修正
procedure TForm1.Button1Click(Sender: TObject);
var
    Response: string;
begin
    if IdIMAP41.Connect() then begin
        try
            if IdIMAP41.SelectMailBox('INBOX') then begin
                IdIMAP41.IOHandler.WriteLn('TAG001 IDLE');

                Response := IdIMAP41.IOHandler.ReadLn;
                Memo1.Lines.Add('Server: ' + Response);
                if Pos('+', Response) <> 1 then begin
                    raise Exception.Create('IDLE not accepted: ' + Response);
                end;

                Memo1.Lines.Add('IDLE started... waiting for updates');
                try
                    while IdIMAP41.Connected do begin
                        Response := IdIMAP41.IOHandler.ReadLn;
                        Memo1.Lines.Add('Server: ' + Response);

                        if Pos('EXISTS', Response) > 0 then begin
                            Memo1.Lines.Add('New mail detected!');
                            Break;
                        end;
                    end;
                finally
                    IdIMAP41.IOHandler.WriteLn('DONE');
                    Memo1.Lines.Add('IDLE stopped');
                end;
            end;
        finally
            IdIMAP41.Disconnect;
        end;
    end;
end;
  • WriteLn で直接コマンドを送る場合、コマンドの前にタグが必要(DONE以外)です(タグは、どのコマンドに対するレスポンスかを判断するための任意の文字列です)
  • 実際に利用する場合はスレッドなどへ入れましょう
  • 上記コードでIDLE状態に置いて、メール受信すると下記(* 8 EXISTS の行)のようにレスポンスが返ってきます

IDLEを標準実装していない理由?
https://github.com/IndySockets/Indy/issues/147

レスポンスバッファに溜まった応答を全て取得するには
    while (not IdIMAP41.IOHandler.InputBufferIsEmpty) do begin
        Response := IdIMAP41.IOHandler.ReadLn;
    end;

コメント