I am using this simple code to send emails it works for most SMTP servers but for the Servers which using SMTP AUTH extension as defined in RFC 2554. it shows this error:
ERROR: valid RCPT command must precede DATA
here is the code :
SMTP.Host := 'host.com';
SMTP.Port := 25;
SMTP.Username:= 'user#host.com';
SMTP.Password:= 'pass';
MailMessages.From.Address:='address#address.com';
MailMessages.From.Name:= 'Ehsan';
MailMessages.Subject := 'Test';
MailMessages.Body.Text := 'the body is going to test';
MailMessages.ReceiptRecipient.Address := 'ehsan.hesam13#gmail.com';
try
try
SMTP.Connect;
SMTP.Authenticate;
SMTP.Send(MailMessages);
except on E:Exception do
StatusMemo.Lines.Insert(0, 'ERROR: ' + E.Message);
end;
finally
if SMTP.Connected then SMTP.Disconnect;
end;
end;
how can i solve this problem in XE2?
thankx
Make sure you are filling in the TIdMessage.Recipients, TIdMessage.CCList, or TIdMessage.BCCList properties. Those are the properties where TIdSMTP gets the addresses for its SMTP RCPT TO commands. You cannot send an email without specify the recipient(s) for it. You are only filling in the TIdMessage.ReceiptRecipient property, which is only meant for specifying the return address that recipients send read receipts to, if recipients support read recipients.
Also, you do not need to call Authenticate() manually. Send() calls it internally for you when needed.
Thank you all , I have filled the Recipients.EMailAddresses and it worked :D
here is the correct code :
SMTP.Host := 'host.com';
SMTP.Port := 25;
SMTP.Username:= 'user#host.com';
SMTP.Password:= 'pass';
MailMessages.From.Address:='address#address.com';
MailMessages.From.Name:= 'Ehsan';
MailMessages.Subject := 'Test';
MailMessages.Body.Text := 'the body is going to test';
MailMessages.Recipients.EMailAddresses:='ehsan.hesam13#gmail.com';
try
try
SMTP.Connect;
SMTP.Authenticate;
SMTP.Send(MailMessages);
except on E:Exception do
StatusMemo.Lines.Insert(0, 'ERROR: ' + E.Message);
end;
finally
if SMTP.Connected then SMTP.Disconnect;
end;
end;
Thank you again.
Related
I tried with Indy component to send email in XE2, and it works fine on my laptop that I compiled my project on.
But if I take my exe project to another PC, it shows an error message
Connection closed gracefully
or, sometimes I get
SSL Negotiation failed
Actually I tried many times to solve my problem, but I can't.
This is my code - where is my mistake? I need a practical solution.
procedure Gmail(username, password, totarget, subject, body :string);
var
DATA : TIdMessage;
SMTP : TIdSMTP;
SSL : TIdSSLIOHandlerSocketOpenSSL;
result:Boolean;
begin
try
SMTP := TIdSMTP.Create(nil);
DATA := TIdMessage.Create(nil);
SSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
SSL.Destination := 'smtp.gmail.com:587';
SSL.Host := 'smtp.gmail.com';
// SSL.MaxLineAction.maException;
SSL.Port:= 587;
SSL.SSLOptions.Method := sslvTLSv1;
SSL.SSLOptions.Mode := sslmUnassigned;
SSL.SSLOptions.VerifyMode := [];
SSL.SSLOptions.VerifyDepth := 0;
DATA.From.Address := username;
DATA.Recipients.EMailAddresses := totarget;
DATA.Subject := subject;
DATA.Body.Text := body;
if FileExists('D:\Test1.txt') then
TIdAttachmentFile.Create(DATA.MessageParts, 'D:\Test1.txt');
SMTP.IOHandler := SSL;
SMTP.Host := 'smtp.live.com';
SMTP.Port := 587 ;
SMTP.Username := username;
SMTP.Password := password;
// SMTP.SASLMechanisms;
SMTP.UseTLS := utUseExplicitTLS;
try
try
SMTP.Connect;
SMTP.Send(DATA);
Result := True;
except
on E:Exception do
begin
ShowMessage('Cannot send E-Mail: ' + E.Message);
Result := False;
end;
end;
finally
if SMTP.Connected then SMTP.Disconnect;
end;
except
on E : Exception do
begin
ShowMessage('Error in the function SendEmailDelphi: ' + E.Message);
Result := False;
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Timer1.Enabled:= True;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
mail_username := 'email#gmail.com';
mail_password := 'pass';
mail_to := 'email#gmail.com';
mail_subject := 'Text email from Delphi project';
mail_body := 'this is a test email sent from Delphi project, do not reply';
try
begin
Gmail(mail_username, mail_password, mail_to , mail_subject, mail_body);
end;
finally
end;
end;
DO NOT set the SSL.Destination, SSL.Host, or SSL.Port properties manually! TIdTCPClient.Connect() handles that for you. Besides, don't you think it's odd that you are setting SSL.Destination/Host to smtp.gmail.com but are setting SMTP.Host to smtp.live.com instead? Gmail and Live are not the same service provider.
Also, SSL.SSLOptions.Mode should be set to sslmClient instead of sslmUnassigned. Not too important, TIdSSLIOHandlerSocketOpenSSL will simply flip it when it configures the connection. But you should do it anyway, since you know your code is acting as a client.
And lastly, try setting SMTP.UseTLS before setting SMTP.Port, as setting UseTLS may change the Port, so you want to make sure you are really connecting to the correct port you are expecting.
With that said, the SSL Negotiation failed error means the TLS handshake was started but failed part-way through the negotiation. Try assigning handlers to TIdSSLIOHandlerSocketOpenSSL's OnStatusInfo/Ex events to see how far the handshake is actually getting. And if you are using a relatively modern version of Indy 10, try looking at the raised exception's InnerException property, it might give you a clue as to what went wrong before the EIdTLSClientTLSHandShakeFailed exception was raised afterwards.
I have successfully sent email using GMail's SMTP server with the code below. I'm using Delphi 2006 and the latest version of Indy (10.6.2) and latest fulgan ssl libraries. The problem is that I had to turn down the GMail security settings as explained in the Google link. With the default high settings I get a cryptic error something like this: "https://accounts.google.com/ContinueSignIn?[...] Please log in via your web browser and then try again. Learn more at https://support.google.com/mail/bin/answer.py?answer=78754 [...] - gsmtp". How can I adjust the code below to use GMail's high security settings?
IdSMTP1.host:='smtp.gmail.com';
IdSMTP1.username:='[deleted]#gmail.com';
IdSMTP1.Password:='[deleted]';
IdSMTP1.port:=587;
IdSMTP1.UseTLS:=utUseExplicitTLS;
IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Mode := sslmClient;
IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method:= sslvTLSv1;
IdSSLIOHandlerSocketOpenSSL1.SSLOptions.VerifyDepth := 2;
IdSSLIOHandlerSocketOpenSSL1.SSLOptions.VerifyMode := [];
IdSSLIOHandlerSocketOpenSSL1.Host := IdSMTP1.Host;
IdSSLIOHandlerSocketOpenSSL1.Port := IdSMTP1.Port;
IdMessage1.From.address := '[deleted]#gmail.com';
IdMessage1.CClist.EMailAddresses:= edit1.Text;
IdMessage1.Subject:= 'Subject is here';
IdMessage1.Body.Clear;
Idmessage1.Body.Add('Body is here');
IdSMTP1.Connect;
try
try
idSMTP1.Send(IdMessage1);
except on E:Exception do
Memo1.Lines.Insert(0, 'ERROR: ' + E.Message);
end;
finally
if idSMTP1.Connected then idSMTP1.Disconnect;
end;
My question is: why gmail gives me that error:
Username and Password not accepted. Learn more at
http://support.google.com/mail/bin/answer.py?answer=14257 lp8sm18275694wic.17 - gsmtp
I tried everything, whole bunch of options: SSL, TSL, SASL and still nothing. Somewhere I found that google demands some OAUTH2 SASL method wchich is to be done in Indy.
Of course on Delphi 6 and Indy 9 with proper eay dlls on port 465 with ssl works fine.
Anyone has some idea what to do with that?
O course I installed http://slproweb.com/products/Win32OpenSSL.html i anyone asked...
here is the code:
procedure send(Recipientemail, AccountName, Pass, EmailSMTP,EmailPortNo :string);
var
lTextPart: TIdText;
lImagePart: TIdAttachmentfile;
IdSMTP1: TIdSMTP;
IdMsg: TIdMessage;
SSLHandler:TIdSSLIOHandlerSocketOpenSSL;
IdUserPassProv1: TIdUserPassProvider;
IdSASLLogin1: TIdSASLLogin;
IdSASLCRAMMD5: TIdSASLCRAMMD5;
IdSASLCRAMSHA1: TIdSASLCRAMSHA1;
IdSASLPlain: TIdSASLPlain;
IdSASLLogin: TIdSASLLogin;
IdSASLSKey: TIdSASLSKey;
IdSASLOTP: TIdSASLOTP;
IdSASLAnonymous: TIdSASLAnonymous;
IdSASLExternal: TIdSASLExternal;
begin
IdSMTP1:=TIdSMTP.Create(nil);
IdMsg:=TIdMessage.Create(nil);
IdSMTP1.Host:=EmailSMTP;
IdSMTP1.Port:=EmailPortNo;
//IdSMTP1.Username:=trim(AccountName);//tried with or without
//IdSMTP1.Password:=trim(Pass);//tried with or without
TIdSSLContext.Create.Free;
SSLHandler:=TIdSSLIOHandlerSocketOpenSSL.Create(IdSMTP1);
SSLHandler.SSLOptions.Method := sslvSSLv3;
SSLHandler.SSLOptions.Mode := sslmClient;
IdSMTP1.IOHandler := SSLHandler;
if (IdSMTP1.port = 465) then
IdSMTP1.UseTLS := utUseImplicitTLS
else
IdSMTP1.UseTLS := utUseExplicitTLS;
IdSASLLogin1:=TIdSASLLogin.Create(IdSMTP1);
IdUserPassProv1:=TIdUserPassProvider.Create(IdSMTP1);
IdUserPassProv1.Password:=trim(EmailHasloKonta);
IdUserPassProv1.Username:=trim(EmailNazwaKonta);
IdSMTP1.AuthType:=satSASL;
IdSASLCRAMSHA1 := TIdSASLCRAMSHA1.Create(idSMTP1);
IdSASLCRAMSHA1.UserPassProvider := IdUserPassProv1;
IdSASLCRAMMD5 := TIdSASLCRAMMD5.Create(idSMTP1);
IdSASLCRAMMD5.UserPassProvider := IdUserPassProv1;
IdSASLSKey := TIdSASLSKey.Create(idSMTP1);
IdSASLSKey.UserPassProvider := IdUserPassProv1;
IdSASLOTP := TIdSASLOTP.Create(idSMTP1);
IdSASLOTP.UserPassProvider := IdUserPassProv1;
IdSASLAnonymous := TIdSASLAnonymous.Create(idSMTP1);
IdSASLExternal := TIdSASLExternal.Create(idSMTP1);
IdSASLLogin := TIdSASLLogin.Create(idSMTP1);
IdSASLLogin1.UserPassProvider:=IdUserPassProv1;
IdSASLPlain := TIdSASLPlain.Create(idSMTP1);
IdSASLPlain.UserPassProvider := IdUserPassProv1;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLCRAMSHA1;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLCRAMMD5;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLSKey;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLOTP;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLAnonymous;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLExternal;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLLogin1;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLPlain;
IdMsg.CharSet:=CmbEncod.Text;
IdMsg.From.Address:=EmailAdresNadawcy;
IdMsg.From.Name:=ToISO_8859_2(true, EmailNadawca);
IdMsg.Recipients.Add.Address:=email;
if EmailDoWiad<>'' then IdMsg.BccList.Add.Address:=EmailDoWiad;
IdMsg.ContentType:='multipart/relative';//; charset='+CmbEncod.Text;
IdMsg.Subject:=ifthen(TytulEmaila='',translate('Potwierdzenie rezerwacji'),TytulEmaila);
IdMsg.Body.Clear;
IdMsg.Body.Text:='';
lTextPart := TIdText.Create(IdMsg.MessageParts);
lTextPart.Body.text:='Some body text';
lTextPart.ContentType := 'text/plain';
try
IdSMTP1.Connect;
//IdSMTP1.Authenticate; //tried with or without
try
try
IdSMTP1.Send(IdMsg);
except
on e: exception do
MessageDlg('Sending error:'#13+
e.message,
mtinformation,[mbok],0);
end;
finally
IdSMTP1.Disconnect;
end;
finally
IdSMTP1.Disconnect;
IdUserPassProv1.free;
IdSASLLogin1.free;
IdSASLCRAMMD5.free;
IdSASLCRAMSHA1.free;
IdSASLPlain.free;
IdSASLLogin.free;
IdSASLSKey.free;
IdSASLOTP.free;
IdSASLAnonymous.free;
IdSASLExternal.free;
lTextPart.Free;
lImagePart.Free;
SSLHandler.free;
IdSMTP1.Free;
IdMsg.Free;
SSLHandler.Free;
end;
end;
Using the latest Indy version (10.6.1), I can successfully connect and authenticate TIdSMTP to Gmail using Indy's SASL components with both SSL (UseTLS=utUseImplicitTLS on port 465) and TLS (UseTLS=utUseExplicitTLS on port 587) using similar code to what you have shown. Despite popular belief, OAUTH2 is not required yet.
The fact that you are getting a human-readable authentication error means the SSL/TLS portion is working fine, so this is strictly a SASL issue.
If your Gmail account is using 2-step verification, make sure you have created an Application Password in your Gmail account settings, you cannot use your primary Gmail password. Read Gmail's documentation for more details:
Application-specific password required
Sign in using App Passwords
With that said, the only changes I would suggest you make to the code you have showed are:
setting the UseTLS property may change the Port property value, so you should set UseTLS first and then set the Port to the desired value afterwards:
if (EmailPortNo = 465) then
IdSMTP1.UseTLS := utUseImplicitTLS
else
IdSMTP1.UseTLS := utUseExplicitTLS;
IdSMTP1.Port := EmailPortNo;
you do not need to create and destroy a TIdSSLContext object, so get rid of that. The only reason to create a TIdSSLContext manually is so it can call the IdSSLOpenSSL.LoadOpenSSLLibrary() function, which is public so you can call it directly if needed (which you don't really need to in this situation).
multipart/relative is not a valid ContentType. Did you mean multipart/related instead? Your TIdMessage does not contain multiple parts so you should not be using multipart ContentType to begin with.
Most of your calls to Free() are redundant since you assigned the TIdSMTP as the Owner for everything except the TIdMessage. You don't need to free the SASL components manually, you can let TIdSMTP do that for you.
you are calling IdSMTP1.Disconnect() twice. You don't need that.
Here is the solution:
After all tries is seems to I have had the wrong version of two dlls libeay.dll and ssleay.dll.
Hello I'm trying to send a message from delphi (indy) to a gmail address. When I go to Gmail I found my message in spam folder. If I try to send the same message with PHPMailer from web it works correctly. This is the code.
Thanks
//setup SMTP
SMTP.Port := 25;
SMTP.ConnectTimeout := 1000;
SMTP.Host := 'smtp.xxxxxx.it';
SMTP.Username := 'info#xxxxxx.it';
SMTP.Password := 'xxxxxx';
SMTP.Connect();
if SMTP.Authenticate then
begin
//setup mail message
MailMessage.From.Name := 'xxxxxx';
MailMessage.From.Address := 'info#xxxxxx.it';
MailMessage.Recipients.EMailAddresses := 'xxxxxx#gmail.com';
MailMessage.Subject := ledSubject.Text;
MailMessage.ContentType := 'multipart/mixed';
htmpart := TIdText.Create(MailMessage.MessageParts, nil);
htmpart.Body := Body.Lines;
htmpart.ContentType := 'text/html';
//send mail
try
try
SMTP.Send(MailMessage);
except on E:Exception do
StatusMemo.Lines.Insert(0, 'ERROR: ' + E.Message);
end;
finally
if SMTP.Connected then SMTP.Disconnect;
end;
end;
Probably I've found the problem. I look the message in 'original mode' I found in the header that google says 'MISSING ID' and I try to add this code:
MailMessage.MsgId := '1234567890#drinkmessage.it';
MailMessage.ExtraHeaders.Values['Message-Id'] := MailMessage.MsgId;
Now it seems to work fine.
thanks
Have you tried changing HeloName and MailAgent of IdSMTP? If you use the same domain with PHPMailer, my guess is GMail considers emails coming from your application as spam because it doesn't detect/like the application which is sending them.
Here is my Issue. I'm using Delphi 5 and Indy 9. I have no option to upgrade either at the moment. I am trying to send an email via gmail, and i hard code the string as 'smtp.google.com' it works just fine. however, if smtp.host is getting the host name from a variable it fails with error 11001, and i havent been able to figure out why. I'm new using indy so i'm probably missing something silly, but i don't understand why it could accept a string as the host, but not a variable holding the string. (It's got to be a variable because i need to pass the procedure different SMTP hosts based on the user signed in. Here is the code:
procedure TFormEmail.SendSimpleMail(ToEmail, MyAttachment: string);
var
Msg: TIdMessage;
DestAddr: TIdEmailAddressItem;
SMTP: TIdSMTP;
SSLHandler : TidSSLIOHandlerSocket;
Attachment: TIdAttachment;
SMTPHost1 :string;
begin
Msg := idMessage1;
Msg.From.Text := EmailName(My_User);
Msg.From.Address := EmailAddress(My_User);
msg.Subject := 'Test';//email subject
DestAddr := Msg.Recipients.Add;
DestAddr.Text := '';//receiver's name (optional)
DestAddr.Address := ToEmail;//where its going
Msg.Body.Add(edtEmailBody.text); //email body
SMTP := IdSMTP1;
SMTP.IOHandler := idSSLIOHandlerSocket1;
SMTPhost1 := SMTPHost(My_User);
SMTPhost1 := 'smtp.google.com';
//SMTP.Host := SMTPhost1; //<--FAILS
SMTP.Host := 'smtp.google.com'; //<--SUCCEEDS
SMTP.Port := SMTPPort(My_User);
SMTP.AuthenticationType := atLogin; //error here (2 error)
SMTP.Username := EmailAddress(My_User);
SMTP.Password := SMTPPassword(My_User);
If not empty(MyAttachment) then
Attachment := TIdAttachment.Create(Msg.MessageParts, MyAttachment);//loads Att
Try
SMTP.Connect;
except
SMTP.Connect;//refire if exception (issue with INDY)
end;
if useSSL(My_User) then
SMTP.SendCmd('STARTTLS');//load TLS
SMTP.Authenticate;
SMTP.Send(Msg);
SMTP.Disconnect;//disconnect from server
end;
I marked the one that fails and the one that succeeds, but i don't understand what i'm doing wrong. Any help would be appreciated
Seems you have more issues in one question, I can only help you with one.
I had the same issue with Connect, I simply called the Load method from IdSSLOpenSSLHeaders.
Try the following:
SMTP := IdSMTP1;
IdSSLOpenSSLHeaders.Load;
SMTP.IOHandler := idSSLIOHandlerSocket1;