使用INDY SMTP服务器

4
以下代码是我修改过的样例代码(以便在10.5.8系统下工作),用于使用Indy Mail server中描述的SMTP客户端独立发送电子邮件。
以下来自INDY SMTP服务器示例。
procedure TForm1.btnServerOnClick(Sender: TObject);
 begin

 IdSMTPServer1.active := true;
end;

procedure TForm1.btnServerOffClick(Sender: TObject);
begin

 IdSMTPServer1.active := false;
end;

procedure TForm1.IdSMTPServer1MailFrom(ASender: TIdSMTPServerContext;
  const AAddress: string; AParams: TStrings; var VAction: TIdMailFromReply);
begin
// Here we are testing the MAIL FROM line sent to the server.
 // MAIL FROM address comes in via AAddress. VAction sets the return action to the server.

 // The following actions can be returned to the server:
 { mAccept, mReject }

 // For now, we will just always allow the mail from address.
 VAction := mAccept;
end;

procedure TForm1.IdSMTPServer1MsgReceive(ASender: TIdSMTPServerContext;
  AMsg: TStream; var LAction: TIdDataReply);
var
 LMsg : TIdMessage;
 LStream : TFileStream;
begin
// When a message is received by the server, this event fires.
// The message data is made available in the AMsg : TStream.
// In this example, we will save it to a temporary file, and the load it using
// IdMessage and parse some header elements.

LStream := TFileStream.Create(ExtractFilePath(Application.exename) + 'test.eml', fmCreate);
Try
 LStream.CopyFrom(AMsg, 0);
Finally
 FreeAndNil(LStream);
End;

LMsg := TIdMessage.Create;
Try
 LMsg.LoadFromFile(ExtractFilePath(Application.exename) + 'test.eml', False);
 ToLabel.Caption := LMsg.Recipients.EMailAddresses;
 FromLabel.Caption := LMsg.From.Text;
 SubjectLabel.Caption := LMsg.Subject;
 Memo1.Lines := LMsg.Body;
Finally
 FreeAndNil(LMsg);
End;

end;


procedure TForm1.IdSMTPServer1UserLogin(ASender: TIdSMTPServerContext;
  const AUsername, APassword: String; var VAuthenticated: Boolean);
begin
 // This event is fired if a user attempts to login to the server
 // Normally used to grant relay access to specific users etc.
 VAuthenticated := True;
end;



procedure TForm1.IdSMTPServer1RcptTo(ASender: TIdSMTPServerContext;
  const AAddress: string; AParams: TStrings; var VAction: TIdRCPToReply;
  var VForward: string);
begin
   VAction := rAddressOk;    
end;

procedure TForm1.IdSMTPServer1Received(ASender: TIdSMTPServerContext;
  var AReceived: string);
begin
//
end;

我需要将这个项目添加什么才能作为电子邮件发送服务器。

我对原始示例进行了很少的更改(只是为了兼容性),因为我无法理解电子邮件如何发送和接收背后的大部分概念。请告诉我如何使此代码将电子邮件发送到此问题中提供的目标地址(例如:someone@gmail.com)Indy Mail server (smtpclient)。


我不太明白你具体在询问什么。请说明你的问题。 - Remy Lebeau
谢谢,我已经更新了,请看最后一段;你在之前的帖子中说,“如果那个交付不起作用,那么你没有正确地存储/转发数据,请展示存储和检索数据的代码”,就是这样。 - VibeeshanRC
之前的帖子 = http://stackoverflow.com/questions/8489820/indy-mail-server - VibeeshanRC
1个回答

5

要将电子邮件传递给另一个系统(在本例中为Gmail),请使用TIdSMTPRelay组件,例如:

procedure TForm1.IdSMTPServer1RcptTo(ASender: TIdSMTPServerContext;                
  const AAddress: string; AParams: TStrings; var VAction: TIdRCPToReply;                
  var VForward: string);                
begin                
  if (AAddress represents a user in your network) then
    VAction := rAddressOk
  else if (AAddress is outside of your network) then
    VAction := rWillForward;                    
end;

procedure TForm1.IdSMTPServer1MsgReceive(ASender: TIdSMTPServerContext; AMsg: TStream; var LAction: TIdDataReply); 
var 
  LMsg : TIdMessage; 
  LMsgClient: TIdMessageClient;
  LStream : TFileStream; 
  LRelayRecipients: TIdEMailAddressList;
  LRelay: TIdSMTPRelay;
  I: Integer;
begin 
  // When a message is received by the server, this event fires. 
  // The message data is made available in the AMsg : TStream. 
  // In this example, we will save it to a temporary file, and load it using 
  // IdMessage to parse some header elements. 

  LStream := TFileStream.Create(ExtractFilePath(Application.exename) + 'test.eml', fmCreate); 
  Try 
    LStream.CopyFrom(AMsg, 0); 
  Finally 
    LStream.Free; 
  End; 
  AMsg.Position := 0;

  LMsg := TIdMessage.Create; 
  Try 
    //LMsg.LoadFromFile(ExtractFilePath(Application.exename) + 'test.eml', False); 

    // Do not use the TIdMessage.LoadFrom...() methods here! The email
    // data contained in the AMsg stream does not escape leading periods
    // on lines of text. That escaping is only used when the email was
    // transmitted over the socket, as a period character has special
    // meaning to the SMTP protocol.  TIdSMTPServer removes the escaping
    // from the data before firing this event. However, the LoadFrom...()
    // methods (which uses TIdMessageClient internally) require the
    // data to be escaped!  This is a known limitation in Indy's core
    // architecture and will be addressed in Indy 11.  Until then,
    // use TIdMessageClient manually so the necessary escaping can be
    // re-introduced into the data while it is being parsed...

    LMsgClient := TIdMessageClient.Create(nil);
    try
      LMsgClient.IOHandler := TIdIOHandlerStreamMsg.Create(LMsgClient, AMsg);
      with TIdIOHandlerStreamMsg(LMsgClient.IOHandler) do
      begin
        FreeStreams := False;
        EscapeLines := True;
      end;
      LMsgClient.IOHandler.Open;
      LMsgClient.ProcessMessage(LMsg, False);
    finally
      LMsgClient.Free;
    end;

    // process LMsg as needed...

    // save the email for local users and forward it to other SMTP servers as needed...

    LRelayRecipients := nil;
    try
      for I := 0 to ASender.RCPTList.Count-1 do
      begin
        if (ASender.RCPTList[I] represents a user in your network) then
        begin
          // save AMsg in the user's mailbox somewhere on the local
          // machine/network where an POP3/IMAP4 client can retreive
          // it from later...
        end else
        begin
          if not Assigned(LRelayRecipients) then LRelayRecipients := TIdEMailAddressList.Create(nil);
          LRelayRecipients.Add.Assign(ASender.RCPTList[I]);
        end;
      end;

      if Assigned(LRelayRecipients) then
      begin
        LRelay := TIdSMTPRelay.Create(nil);
        try
          // you must supply the IP/Host of a DNS server that
          // will be used for determining the SMTP server of
          // each recipient domain...
          LRelay.DNSServer := ...;

          LRelay.Send(LMsg, LRelayRecipients);
        finally
          LRelay.Free;
        end;
      end;
    finally
      LRelayRecipients.Free;
    end;

  Finally 
    LMsg.Free; 
  End; 
end; 

1
@waza123:关于这个问题呢?你还没有对它做出任何更改。你最初展示的内容是不完整的。我上面的例子为你填补了一些缺失的部分,现在你需要根据你特定的业务需求完成剩下的部分。 - Remy Lebeau
http://chat.stackoverflow.com/rooms/5854/discussion-between-waza123-and-remy-lebeau-teamb - jmp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接