Delphi 工业贸易署;TIdAttachmentMemory-垃圾邮件过滤器拒绝电子邮件
我正在尝试发送一封带有PDF附件的电子邮件,该附件存储在BLOB字段中,使用的是TIDMSMTP。为此,我使用了一个TIdAttachmentMemory,但显示的代码结果是“被垃圾邮件过滤器拒绝”Delphi 工业贸易署;TIdAttachmentMemory-垃圾邮件过滤器拒绝电子邮件,delphi,pdf,smtp,attachment,indy,Delphi,Pdf,Smtp,Attachment,Indy,我正在尝试发送一封带有PDF附件的电子邮件,该附件存储在BLOB字段中,使用的是TIDMSMTP。为此,我使用了一个TIdAttachmentMemory,但显示的代码结果是“被垃圾邮件过滤器拒绝” 省略IdMessage.ContentType:=“多部分/混合”有效,但附件未按预期发送(或接收?) 离开此语句并从文件中创建附件(如注释代码中所示)一切正常(即正确接收带有附件的邮件) 很明显,我遗漏了一些东西。我怀疑附件方向的某些内容未正确“关闭”(即处于不完整状态),或者可能是内容类型不正确
IdMessage.ContentType:=“多部分/混合”
有效,但附件未按预期发送(或接收?)procedure TfrmSendMail.btnSendClick(Sender: TObject);
var
ms: TMemoryStream;
Attachment: TIdAttachmentMemory;
// Attachment: TIdAttachmentFile;
begin
memStatus.Clear;
IdSSLIOHandlerSocketOpenSSL.Destination := teHost.Text + ':587';
IdSSLIOHandlerSocketOpenSSL.Host := teHost.Text;
// IdSSLIOHandlerSocketOpenSSL.MaxLineAction := maException;
IdSSLIOHandlerSocketOpenSSL.Port := 587;
IdSSLIOHandlerSocketOpenSSL.SSLOptions.Method := sslvTLSv1_2;
IdSSLIOHandlerSocketOpenSSL.SSLOptions.Mode := sslmUnassigned;
IdSSLIOHandlerSocketOpenSSL.SSLOptions.VerifyMode := [];
IdSSLIOHandlerSocketOpenSSL.SSLOptions.VerifyDepth := 0;
IdSMTP.Host := teHost.Text;
IdSMTP.Port := 587;
IdMessage.From.Address := teFrom.Text;
IdMessage.Recipients.EMailAddresses := teTo.Text;
IdMessage.Subject := teSubject.Text;
IdMessage.Body.Text := memBody.Text;
IdMessage.Body.Add('Timestamp: ' + FormatDateTime('yyyy-mm-dd hh:nn:ss', Now()));
IdMessage.ContentType := 'multipart/mixed';
if not sqlPDFPDF_Incasso.IsNull then
begin
ms := TMemoryStream.Create;
try
try
TBlobField(sqlPDF.FieldByName('PDF_Incasso')).SaveToStream(ms);
ms.Position := 0;
Attachment := TIdAttachmentMemory.Create(IdMessage.MessageParts, ms);
Attachment.ContentType := 'application/pdf';
Attachment.FileName := 'Invoice.pdf';
except
on E: Exception do
messageDlg('Error creating attachment' + #13#10 + E.Message, mtError, [mbOK], 0);
end;
finally
ms.Free;
end;
end;
// if FileExists(beAttachment.Text) then
// Attachment := TIdAttachmentFile.Create(IdMessage.MessageParts, beAttachment.Text);
Screen.Cursor := crHourGlass;
try
try
IdSMTP.Connect;
IdSMTP.Send(IdMessage);
memStatus.Lines.Insert(0, 'Email sent - OK.');
except
on E: Exception do
memStatus.Lines.Insert(0, 'ERROR: ' + E.Message);
end;
finally
if assigned(Attachment) then
Attachment.Free;
if IdSMTP.Connected then
IdSMTP.Disconnect(true);
Screen.Cursor := crDefault;
end;
end;
您没有正确填充
TIdMessage
(有关详细信息,请参阅-您的用例将属于“HTML和非相关附件,无纯文本”部分,但将HTML替换为纯文本)
简而言之,如果包含附件,可以将TIdMessage.ContentType
设置为'multipart/mixed'
,但需要将正文文本放入TIdMessage.MessageParts
中的TIdMessage.body
对象中。如果没有包含附件,可以使用TIdMessage.Body
,但需要将TIdMessage.ContentType
设置为'text/plain'
试试这个:
procedure TfrmSendMail.btnSendClick(Sender: TObject);
var
Text: TIdText;
Attachment: TIdAttachmentMemory;
Strm: TStream;
begin
memStatus.Clear;
IdSSLIOHandlerSocketOpenSSL.SSLOptions.Method := sslvTLSv1_2;
IdSSLIOHandlerSocketOpenSSL.SSLOptions.Mode := sslmClient;
IdSSLIOHandlerSocketOpenSSL.SSLOptions.VerifyMode := [];
IdSSLIOHandlerSocketOpenSSL.SSLOptions.VerifyDepth := 0;
IdSMTP.Host := teHost.Text;
IdSMTP.Port := 587;
try
IdMessage.Clear;
IdMessage.From.Address := teFrom.Text;
IdMessage.Recipients.EMailAddresses := teTo.Text;
IdMessage.Subject := teSubject.Text;
//if FileExists(beAttachment.Text) then
if not sqlPDFPDF_Incasso.IsNull then
begin
IdMessage.ContentType := 'multipart/mixed';
Text := TIdText.Create(IdMessage.MessageParts, nil);
Text.Body.Text := memBody.Text;
Text.Body.Add('Timestamp: ' + FormatDateTime('yyyy-mm-dd hh:nn:ss', Now()));
Text.ContextType := 'text/plain';
//Attachment := TIdAttachmentFile.Create(IdMessage.MessageParts, beAttachment.Text);
Attachment := TIdAttachmentMemory.Create(IdMessage.MessageParts);
Attachment.ContentType := 'application/pdf';
Attachment.FileName := 'Invoice.pdf';
Strm := Attachment.PrepareTempStream;
try
TBlobField(sqlPDFPDF_Incasso).SaveToStream(Strm);
finally
Attachment.FinishTempStream;
end;
end else
begin
IdMessage.ContentType := 'text/plain';
IdMessage.Body.Text := memBody.Text;
IdMessage.Body.Add('Timestamp: ' + FormatDateTime('yyyy-mm-dd hh:nn:ss', Now()));
end;
Screen.Cursor := crHourGlass;
try
IdSMTP.Connect;
try
IdSMTP.Send(IdMessage);
finally
IdSMTP.Disconnect;
end;
memStatus.Lines.Insert(0, 'Email sent - OK.');
finally
Screen.Cursor := crDefault;
end;
except
on E: Exception do
memStatus.Lines.Insert(0, 'ERROR: ' + E.Message);
end;
end;
或者,Indy有一个TIdMessageBuilderPlain
类,可以为您正确设置TIdMessage
(有关详细信息,请参阅-您的用例将属于“纯文本、HTML和附件:仅非相关附件”部分):
忘了提到:Delphi 10.3.1和Indy 10。你检查过当你把它发送到没有垃圾邮件过滤器的服务器时会发生什么吗?@Nat:没有,我没有;T我在哪里可以找到这样的服务器?我只是在使用我的提供商的SMTP服务器(与普通邮件相同)。使用PrepareTempStream/FinishTempStream似乎确认了我的思路是正确的,假设附件没有正确准备(“关闭”)。我做了一些小的调整,删除了
try
下面的Screen.Cursor:=crHourGlass代码>。IdSMTP.Port:=587下面已经有一个try
代码>。您似乎还删除了idsslohandlersocketopenssl的设置目标、主机和端口。这是故意的(例如,它们是否取自相关的IdSMTP)?谢谢你的帮助和示范@标记“使用PrepareTempStream/FinishTempStream似乎确认了我在正确的轨道上,假设附件没有正确准备(“关闭”)——实际上,我这样做是因为它更高效TIdMemoryAttachment
具有内部TMemoryStream
,您可以将blob读入其中,从而使本地TMemoryStream
冗余。如果需要,您可以使用自己的TMemoryStream
,TIdMemoryAttachment
构造函数将复制数据。那部分很好。我回答的要点是,您没有正确设置TIdMessage
的其余部分。@标记“您似乎还删除了idsslohandlersocketopenssl的设置目标、主机和端口。这是有意的吗”-是的,因为它们是由TIdTCPClient.Connect()
自动填写的。感谢您的澄清,我差点错过了那一点。因此,如果我的理解是正确的,我可以设置一些IdMessage
属性(To
,From
,Subject
),然后定义IdMessage.ContentType:='multipart/mixed'
以便可以根据需要添加MessageParts
,并为每个MessageParts
设置ContentType
?@标记类似的内容。我建议你仔细研究一下工作原理。TIdMessage.MessageParts
松散地遵循MIME模型(当使用TIdMessage.MessageParts
时,默认的TIdMessage.Encoding
是meMIME
)。
uses
..., IdMessageBuilder;
procedure TfrmSendMail.btnSendClick(Sender: TObject);
var
Strm: TStream;
Bldr: TIdMessageBuilderPlain;
begin
memStatus.Clear;
IdSSLIOHandlerSocketOpenSSL.SSLOptions.Method := sslvTLSv1_2;
IdSSLIOHandlerSocketOpenSSL.SSLOptions.Mode := sslmClient;
IdSSLIOHandlerSocketOpenSSL.SSLOptions.VerifyMode := [];
IdSSLIOHandlerSocketOpenSSL.SSLOptions.VerifyDepth := 0;
IdSMTP.Host := teHost.Text;
IdSMTP.Port := 587;
try
IdMessage.Clear;
IdMessage.From.Address := teFrom.Text;
IdMessage.Recipients.EMailAddresses := teTo.Text;
IdMessage.Subject := teSubject.Text;
Strm := nil;
try
Bldr := TIdMessageBuilderPlain.Create;
try
Bldr.PlainText.Text := memBody.Text;
Bldr.PlainText.Add('Timestamp: ' + FormatDateTime('yyyy-mm-dd hh:nn:ss', Now()));
//if FileExists(beAttachment.Text) then
if not sqlPDFPDF_Incasso.IsNull then
begin
//Bldr.Attachments.Add(beAttachment.Text);
Strm := sqlPDFPDF_Incasso.DataSet.CreateBlobStream(sqlPDFPDF_Incasso, bmRead);
Bldr.Attachments.Add(Strm, 'application/pdf').WantedFileName := 'Invoice.pdf';
end;
Bldr.FillMessage(IdMessage);
finally
Bldr.Free;
end;
finally
Strm.Free;
end;
Screen.Cursor := crHourGlass;
try
IdSMTP.Connect;
try
IdSMTP.Send(IdMessage);
finally
IdSMTP.Disconnect;
end;
memStatus.Lines.Insert(0, 'Email sent - OK.');
finally
Screen.Cursor := crDefault;
end;
except
on E: Exception do
memStatus.Lines.Insert(0, 'ERROR: ' + E.Message);
end;
end;