5

How can I retrieve a specific e-mail based on a certain text contained in the message ? For example how Gmail search works. If you search for a specific text, which is in the e-mail, then the Gmail will retrieve the message that is associated with the text. Preferably without any looping.

4

1 回答 1

6

你正在寻找SearchMailBox方法。这是一个简单的示例,期望您的 IMAP 客户端(在本例IMAPClient中为类型的变量TIdIMAP4)已经连接到 Gmail 服务器。对于那些寻找如何做到这一点的人,请看一下this post并将此代码放在and附近的try..finally块中。IMAPClient.ConnectIMAPClient.Disconnect

var
  // in this example is not shown how to connect to Gmail IMAP server but
  // it's expected that the IMAPClient object is already connected there
  IMAPClient: TIdIMAP4;

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  MsgObject: TIdMessage;
  SearchInfo: array of TIdIMAP4SearchRec;
begin
  // if the mailbox selection succeed, then...
  if IMAPClient.SelectMailBox('INBOX') then
  begin
    // set length of the search criteria to 1
    SetLength(SearchInfo, 1);
    // the SearchKey set to skBody means to search only in message body texts
    // for more options and explanation, see comments at the TIdIMAP4SearchKey
    // enumeration in the IdIMAP4.pas unit
    SearchInfo[0].SearchKey := skBody;
    // term you want to search
    SearchInfo[0].Text := 'Search term';

    // if the search in the selected mailbox succeed, then...
    if IMAPClient.SearchMailBox(SearchInfo) then
    begin
      // iterate the search results
      for I := 0 to High(IMAPClient.MailBox.SearchResult) do
      begin
        // make an instance of the message object
        MsgObject := TIdMessage.Create(nil);
        try
          // try to retrieve currently iterated message from search results
          // and if this succeed you can work with the MsgObject
          if IMAPClient.Retrieve(IMAPClient.MailBox.SearchResult[I], 
            MsgObject) then
          begin
            // here you have retrieved message in the MsgObject variable, so
            // let's do what what you need with the >> MsgObject <<
          end;
        finally
          MsgObject.Free;
        end;
      end;
    end;
  end;
end;

这是 UTF-8 字符集的 IMAP 搜索的快速实现。由于受保护的ParseSearchResult方法,它使用插入类:

type
  TBasicSearchKey = (bskBcc, bskBody, bskCc, bskFrom, bskHeader, bskKeyword,
    bskSubject, bskText, bskTo);
const
  IMAPSearchKeys: array [TBasicSearchKey] of string = ('BCC', 'BODY', 'CC',
    'FROM', 'HEADER', 'KEYWORD', 'SUBJECT', 'TEXT', 'TO');
type
  TIdIMAP4 = class(IdIMAP4.TIdIMAP4)
  public
    function SearchMailBoxUTF8(const ASearchText: string;
      ASearchKey: TBasicSearchKey): Boolean;
  end;

implementation

{ TIdIMAP4 }

function TIdIMAP4.SearchMailBoxUTF8(const ASearchText: string;
  ASearchKey: TBasicSearchKey): Boolean;
var
  SearchText: RawByteString;
begin
  Result := False;
  CheckConnectionState(csSelected);

  SearchText := UTF8Encode(ASearchText);
  SendCmd(Format('SEARCH CHARSET UTF-8 %s {%d}', [IMAPSearchKeys[ASearchKey],
    Length(SearchText)]), ['SEARCH']);
  if LastCmdResult.Code = IMAP_CONT then
    IOHandler.WriteLn(SearchText, TEncoding.UTF8);

  if GetInternalResponse(LastCmdCounter, ['SEARCH'], False) = IMAP_OK then
  begin
    ParseSearchResult(FMailBox, LastCmdResult.Text);
    Result := True;
  end;
end;

以及用法:

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  MsgObject: TIdMessage;
begin
  if IMAPClient.SelectMailBox('INBOX') and
    IMAPClient.SearchMailBoxUTF8('Search term', bskText) then
  begin
    for I := 0 to High(IMAPClient.MailBox.SearchResult) do
    begin
      MsgObject := TIdMessage.Create(nil);
      try
        if IMAPClient.Retrieve(IMAPClient.MailBox.SearchResult[I],
          MsgObject) then
        begin
          // here you have retrieved message in the MsgObject variable, so
          // let's do what what you need with the >> MsgObject <<
        end;
      finally
        MsgObject.Free;
      end;
    end;
  end;
end;
于 2012-11-28T20:07:17.693 回答