2

I maintain and develop a program that (amongst other things) sends emails via GMail.

Until now, there have been no problems with sending emails, but a few days ago this functionality ceased to work with a message 'Bad credentials'. I looked through the help of GMail and found this explanation/warning/what-have-you:

To help keep your account secure, from May 30, 2022, ​​Google no longer supports the use of third-party apps or devices which ask you to sign in to your Google Account using only your username and password.

The solution is to use the 'app specific' password.

I looked at this question that states:

My most recent try was to create an 'app specific' password on Gmail

But the attached code doesn't actually show how the password is sent.

Reading the question and its answers, I made some changes to my program:

Port := 995
UseTLS := utUseImplicitTLS
SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2]

After these changes, in an attempt to send a test mail (still no app specific password), I get the response

Reply code is not valid: +OK

which might mean that my program fails, as it doesn't send the app specific password.

What I want to know is: how to send that password?

Below is my code that executes as a thread, hence all components are defined in code:

 email:= TIdMessage.Create (nil);
 try
  email.LoadFromFile (FFileName);
  email.OnInitializeISO:= DoInitializeISO;
  //  DeleteFile (FFileName);

  smtp:= TIdSMTP.Create (nil);
  try
   smtp.OnFailedRecipient:= FailedRecipient;
   ssl:= TIdSSLIOHandlerSocketOpenSSL.Create (smtp);
   ssl.SSLOptions.SSLVersions:= [sslvTLSv1];

   smtp.OnStatus := DoStatus;
   smtp.IOHandler:= ssl;
   smtp.Host:= FHost;
   smtp.Password:= FPassword;   // now app passord
   smtp.Username:= FUsername;
   smtp.UseTLS:= utUseExplicitTLS;
   smtp.Port:= 587;

   smtp.Connect;
   try
    smtp.Send (email);
   finally
    smtp.Disconnect;
   end;
  finally
   ssl.free;
   smtp.Free;
  end;
 finally
  email.Free;
 end;
No'am Newman
  • 6,395
  • 5
  • 38
  • 50
  • Please edit your question and include your code. We need to see how you are making the call including applying the users password. – Linda Lawton - DaImTo Jun 10 '22 at 06:11
  • Does this answer your question? [Delphi 11 Indy GMail SMTP error "Username and Password not accepted"](https://stackoverflow.com/questions/72609133/delphi-11-indy-gmail-smtp-error-username-and-password-not-accepted) – Mark Rotteveel Jun 28 '22 at 11:29
  • @MarkRotteveel: That question is basically the same as mine, except for the fact that my question was asked first! – No'am Newman Jun 28 '22 at 12:50
  • Yes, but it has an, in my opinion, better answer. Age is not the primary motivator for direction of closing. – Mark Rotteveel Jun 28 '22 at 17:10

2 Answers2

2

An application-specific password is simply a password that Gmail generates for you, and then you use it instead of your normal password (ie, in the TIdSMTP.Password property). This is explained in Gmail's documentation:

Sign in with App Passwords

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
2

You can just replace the password with the apps password. Assuming your code id similar to that below. Just remember you need to have 2fa enabled in order to create an apps password.

   smtp.OnStatus := DoStatus;
   smtp.IOHandler:= ssl;
   smtp.Host:= FHost;
   smtp.Password:= AppsPassword;   // Password from Apps Password
   smtp.Username:= FUsername;
   smtp.UseTLS:= utUseExplicitTLS;
   smtp.Port:= 587;

Another option would be to use Xoauth2.

Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
  • You don't need to set the `Destination`, `Host`, `Port` or `DefaultPort` on the `IOHandler`, `Connect()` handles that internally for you. – Remy Lebeau Jun 09 '22 at 15:15
  • Although the first sentence "you can just replace the password with the apps password" is technically correct, the rest of the answer is problematic as it gives instructions for *downloading* mail, not *sending* mail. This was an unintended mistake on my part; the accepted answer refers to TIdSMTP which is the correct component. The error message that I received was a hint that I was using the wrong port. – No'am Newman Jun 10 '22 at 03:38
  • Remy, you might want to let Marco Cantu know that. His online example implies that those properties need to be set. – Todd Grigsby Feb 08 '23 at 00:45