【发布时间】:2013-01-29 06:05:20
【问题描述】:
如何根据邮件中包含的特定文本检索特定的电子邮件?例如 Gmail 搜索的工作原理。如果您搜索电子邮件中的特定文本,则 Gmail 将检索与该文本关联的消息。最好没有任何循环。
【问题讨论】:
标签: delphi delphi-xe2 imap
如何根据邮件中包含的特定文本检索特定的电子邮件?例如 Gmail 搜索的工作原理。如果您搜索电子邮件中的特定文本,则 Gmail 将检索与该文本关联的消息。最好没有任何循环。
【问题讨论】:
标签: delphi delphi-xe2 imap
您正在寻找SearchMailBox 方法。这是一个简单的示例,期望您的 IMAP 客户端(在本例中为 TIdIMAP4 类型的 IMAPClient 变量)已连接到 Gmail 服务器。对于那些寻找如何做到这一点的人,请查看 this post 和 put 将此代码放在 try..finally 块中,靠近 IMAPClient.Connect 和 IMAPClient.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;
【讨论】:
SEARCH 命令的目标 IMAP 服务器实现,但不幸的是在这种情况下它不会搜索文本消息部分。值得一提。
SearchMailBox 时,您只需将命令发送到服务器,例如SEARCH BODY "Search term",它是由服务器决定的,它是如何接受的以及返回给您的。如果可以单独配置,我会感到惊讶。他们的搜索可能会有所不同,他们可以在眨眼间循环所有消息,因为他们在现场,所以可能不会使用SEARCH 命令。