Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Delphi 10.3 - Enable application to send emails without email client
#1
Hi,

I want to make an application send different emails using tidSMTP.
The tests I am doing using Yahoo or Gmail to send the email it not working but I don't know why.
I don't get an error, but the test email does not work.
The message that pops up is Connection close graciously.
I am new to this and I haven't found any documentation on how to approach this.

Thanks in advance,

Here's the code:

With IdSSLIOHandlerSocketOpenSSL1 do
  begin
    Destination := dbeSMTPServer.Text + ':' + dbeSMTPPort.Text;
    Host := dbeSMTPServer.Text;
    MaxLineAction := maException;
    Port := StrToInt(dbeSMTPPort.Text);
    SSLOptions.Method := sslvTLSv1;
    SSLOptions.Mode := sslmUnassigned;
    SSLOptions.VerifyMode := [];
    SSLOptions.VerifyDepth := 0;
  end;
//SETTING SMTP COMPONENT DATA //
  IdSMTP.Host := dbeSMTPServer.Text;
  IdSMTP.Port := StrToInt(dbeSMTPPort.Text);
  IdSMTP.Username := dbeSMTPUser.Text;
  IdSMTP.Password := dbeSMTPPassword.Text;
  IdSMTP.IOHandler := IdSSLIOHandlerSocketOpenSSL1;
  IdSMTP.AuthType := satDefault;
  //IdSMTP.UseTLS := utUseExplicitTLS;
// SETTING email MESSAGE DATA //
  IdMessage.Clear;
// add recipient list //
  with IdMessage.Recipients.Add do
  begin
    Name := dbeFullName.Text;
    Address := dbeEmail.Text;
  end;
  IdMessage.From.Address :=  dbeEmail.Text;
  IdMessage.Subject := 'Email Test From Sales Manager';
  IdMessage.Body.Add('Hi ' + dbeFullName.Text + ',' + chr(13) + chr(13) +
                    'If you received this email, the configuration of the email for the user ' + dbeUsername.Text +
                    ' is correct!');
  IdMessage.Priority := mpHigh;
  try
    IdSMTP.Connect();
    IdSMTP.Send(IdMessage);
    ShowMessage('Email sent');
    IdSMTP.Disconnect();
  except on e:Exception do
    begin
      ShowMessage(e.Message);
      IdSMTP.Disconnect();
    end;
  end;
Reply
#2
(04-08-2020, 06:22 PM)joceravolo Wrote: I don't get an error, but the test email does not work.
The message that pops up is Connection close graciously.

That would be an error condition. The server is closing the connection on its end. Basically, it is kicking you out. Usually because you didn't authenticate properly, or the TLS handshake failed.

(04-08-2020, 06:22 PM)joceravolo Wrote: With IdSSLIOHandlerSocketOpenSSL1 do
  begin
    Destination := dbeSMTPServer.Text + ':' + dbeSMTPPort.Text;
    Host := dbeSMTPServer.Text;
    MaxLineAction := maException;
    Port := StrToInt(dbeSMTPPort.Text);

FYI, you don't need to set any of those properties manually, they are set by Connect() for you (well, except for MaxLineAction, but you shouldn't be setting that manually anyway, especially since maException is the default).

(04-08-2020, 06:22 PM)joceravolo Wrote:   IdSMTP.Host := dbeSMTPServer.Text;
  IdSMTP.Port := StrToInt(dbeSMTPPort.Text);

You did not indicate what Host/Port values you are using exactly. It makes a difference, especially in how you have to set the UseTLS property (which you have commented out).

(04-08-2020, 06:22 PM)joceravolo Wrote:   IdSMTP.AuthType := satDefault;

Note that not all SMTP servers will support that setting. satDefault uses an AUTH LOGIN command, which is unsecure without a TLS connection to encrypt it. And even if a given SMTP server does support AUTH LOGIN, not all SMTP servers advertise support for it. You MAY have to set the TIdSMTP.ValidateAuthLoginCapability property to False to get satDefault to actually send its AUTH LOGIN command.

(04-08-2020, 06:22 PM)joceravolo Wrote:   IdMessage.Body.Add('Hi ' + dbeFullName.Text + ',' + chr(13) + chr(13) +
                    'If you received this email, the configuration of the email for the user ' + dbeUsername.Text +
                    ' is correct!');

Rather than using chr(13) (or just #13), you should use the Body.Add() method for each individual line:

Code:
IdMessage.Body.Add('Hi ' + dbeFullName.Text + ',');
IdMessage.Body.Add('');
IdMessage.Body.Add('');
IdMessage.Body.Add('If you received this email, the configuration of the email for the user ' + dbeUsername.Text + ' is correct!');

Or, use the Body.Text property:

Code:
IdMessage.Body.Text := 'Hi ' + dbeFullName.Text + ',' + sLineBreak + sLineBreak + 'If you received this email, the configuration of the email for the user ' + dbeUsername.Text + ' is correct!');

Reply
#3
Thanks for the reply.
I want this to work for different email providers.
Such as GMail, Yahoo, etc.
I have different emails to test it with. They all require SSL, but I there's no mention of TLS.
On Yahoo I set it up to be able to use an app to send emais.
Is there a way to query the server requirements?

So, with the SSL configuration (Ports 995 and 465) in mind.
On that case, what do I have to config?

Thanks again and I am sorry for all the questions. I can't find anything detailing these...
Reply
#4
(04-10-2020, 04:49 PM)joceravolo Wrote: I have different emails to test it with. They all require SSL, but I there's no mention of TLS.

You need to understand the difference.

When a server wants "SSL", it usually wants an "implicit" SSL/TLS session, meaning that the client must negotiate an SSL/TLS session immediately upon connecting to the server's port, before then reading the server's (now-encrypted) greeting or sending any (encrypted) commands. This is handled in Indy by setting the UseTLS property to utUseImplicitTLS.

When a server wants "TLS", it usually wants an "explicit" SSL/TLS session, meaning that the client must not negotiate an SSL/TLS session immediately upon connecting to the server's port. It must read the server's (unencrypted) greeting first, and then later it can send an appropriate STARTTLS command (if the server advertises support for it) to ask for permission to then negotiate an SSL/TLS session before sending any further (encrypted) commands. This is handled in Indy by setting the UseTLS property to utUseExplicitTLS.

(04-10-2020, 04:49 PM)joceravolo Wrote: On Yahoo I set it up to be able to use an app to send emais.
Is there a way to query the server requirements?

So, with the SSL configuration (Ports 995 and 465) in mind.
On that case, what do I have to config?

POP3:
Port 110 uses explicit-tls.
Port 995 uses implicit-ssl.

SMTP:
Port 25 is usually unencrypted, may support explicit-tls (check server capabilities).
Port 465 uses implicit-ssl.
Port 587 uses explicit-tls.

IMAP
Port 143 uses explicit-tls.
Port 993 uses implicit-ssl.

Reply
#5
I tried both utUseExplicitTLS and utUseImplicitTLS. Now I get this message:
Need SASL mechanisms to login with it!!


I am testing using smtp.mail.yahoo.com at port 465.
Reply
#6
(04-10-2020, 09:18 PM)joceravolo Wrote: Now I get this message:
Need SASL mechanisms to login with it!!

That error message means that you set the TIdSMTP.AuthType property to satSASL, but you did not assign any TIdSASL-derived components (TIdSASLCRAMMD5, TIdSASLCRAMSHA1, TIdSASLDigest, TIdSASLLogin, etc) to the TIdSMTP.SASLMechanisms property, so TIdSMTP has not way to authenticate with the server.

Indy currently implements 2 SASLs that Yahoo and Gmail both support (last time I checked): LOGIN (handled by TIdSASLLogin, also handled by TIdSMTP.AuthType=satDefault) and PLAIN (TIdSASLPlain). Both of those SASLs are not secure unless SSL/TLS is used. Yahoo and Gmail also support various OAUTH SASLs, which are not currently implemented in Indy (but some experimental code has been written for them - contact me privately if you would like a copy). And Yahoo also supports another SASL named XYMCOOKIE, which I have never heard of before, and is proprietary to Yahoo (and thus not implemented by Indy).

Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)