Home General

GMail OAuth2 - directly sending mail

RcsRcs
edited July 2022 in General
A few questions regarding GMail with OAuth2 via TppEmail to send a stand-alone mail

After authorizing my application to send emails using my GMail account, instead of sending the mail, the GMail web interface is opened with a draft of the mail I want to send. What is missing in my setup to directly send the mail instead of showing the draft?

For consecutive mails, the authorization process is repeated every single time. What needs to be done to retain the authorization code so that won't be necessary any more until the code expires?

Upon opening the GMail web interface an access violation on the worker thread occurs after a certain period of time. Details below. Is this a known problem?

Project MailTestOAuth2.exe raised exception class EAccessViolation with message 'Access violation at address 00CB1F0E. Read of address 00000014'.
---------------------------
[&Filter ...] [Ignore &All this Session] [Break] [Additional &Info] [Continue]
---------------------------
ThreadId=21096
ProcessId=18
ThreadName="Worker Thread - TThreadPool.TQueueWorkerThread #4 ThreadPool - 049AC1D8"
ExceptionMessage="Access violation at address 00CB1F0E. Read of address 00000014"
ExceptionName="EAccessViolation"
ExceptionDisplayName="$C0000005"
ExceptionAddress=00CB1F0E
FileName="D:\RBPro_21.04\RBuilder\Source\ppHttpLoopback.pas"
LineNumber=370
---------------------------
My code: 
procedure TForm1.btn1Click(Sender: TObject);
var
  lEmail: TppEmail;
begin
  lEmail := TppEmail.Create;
  try
    TppSMTPPlugin.RegisterClass(TppRESTMailGmail);
    lEmail.EmailSettings.ConnectionSettings.UseTLS := True;
    lEmail.EmailSettings.ConnectionSettings.WebMail.GmailSettings.OAuth2.RedirectURI := 'http://localhost';
    lEmail.EmailSettings.ConnectionSettings.WebMail.GmailSettings.OAuth2.ClientID := '****';
    lEmail.EmailSettings.ConnectionSettings.WebMail.GmailSettings.OAuth2.ClientSecret := '****';
    lEmail.EmailSettings.Recipients.Add('john@doe.com');
    lEmail.EmailSettings.Body.Add('Body text');
    lEmail.EmailSettings.Subject := 'Subject text';
    lEmail.SendEmail;
  finally
    lEmail.Free;
  end;
end;

Comments

  • Hi Reinier,

    1. To send emails without displaying email client, set

    EmailSettings.PreviewInEmailClient := False

    2. See Example code below. Create and use a single Email instance to send all emails. Authorization occurs for first email only.

    3. We recently created a patch for RB 21.04 to resolve a Rest Email issue that appeared due to changes in Delphi 11.1. I'm emailing you the patch.

    Example code:


    procedure TForm1.FormCreate(Sender: TObject);
    begin
    FEmail := TppEmail.Create;

    InitializeGmailSettings(FEmail.EmailSettings);

    end;

    procedure TForm1.FormDestroy(Sender: TObject);
    begin
    FEmail.Free;
    end;

    procedure TForm1.Button2Click(Sender: TObject);
    begin

    BuildEmailMessage('myself@mycompany.com', 'Test RB Email', 'Hello from RB Rest Gmail');

    FEmail.SendEmail;

    end;

    procedure TForm1.BuildEmailMessage(const aRecipient, aSubject, aMessageBody: string);
    begin
    FEmail.EmailSettings.PreviewInEmailClient := False;

    FEmail.EmailSettings.FromAddress := cFromAddress; // constant
    FEmail.EmailSettings.Recipients.Text := aRecipient;
    FEmail.EmailSettings.Subject := aSubject;
    FEmail.EmailSettings.Body.Text := aMessageBody;


    end;


    procedure TForm1.InitializeGmailSettings(aEmailSettings: TppEmailSettings);
    begin
    aEmailSettings.Enabled := True;

    aEmailSettings.ConnectionSettings.MailService := 'Gmail';
    aEmailSettings.ConnectionSettings.WebMail.GmailSettings.OAuth2.ClientID := cGmailClientID; // constant
    aEmailSettings.ConnectionSettings.WebMail.GmailSettings.OAuth2.ClientSecret := cGmailClientSecret; // constant
    aEmailSettings.ConnectionSettings.WebMail.GmailSettings.OAuth2.RedirectURI := 'http://localhost';

    end;



    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
  • This helped, thank you Nard!
  • The example helped to send mail through the google API, but the AV is still an issue. Now only upon closing the application after the loopback-server was used. Using the example you gave above, it seems like everything is cleaned up but one or more threads stay alive and raise an exception after a certain timeout.
    image
    I'm running Delphi27/10.4 by the way, not 28/11.1 (which most of the patch changes were for) so I'm guessing the patch wasn't for that specific problem?

    Also, are there any plans for implementing the use of refresh tokens?
  • Hi Reinier,

    I created a simple test using the latest version of RB (with patches) and Delphi 10.4.2 but was unable to get the AV you are getting. If possible, please send me the exact code you are using (without any login credentials) and I will try to run it here and see if I can recreate the issue.

    Refresh tokens are on our list of possible enhancement for a future release.
    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • Hi Nico, sent you the project and some additional info
Sign In or Register to comment.