Sample code for 30+ languages & platforms
Delphi DLL

OAuth2 for a GMail using a JSON Service Account Key

See more GMail SMTP/IMAP/POP Examples

This example shows how to obtain an OAuth2 access token for Gmail using a Google Service Account and a JSON private key. Once acquired, the access token can be used to send emails. Remember, upon token expiration, this process needs to be repeated to obtain a new token. Note: This procedure is specific to OAuth2 with Google Service Account keys.

Chilkat Delphi DLL Downloads

Delphi DLL
uses
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, MailMan, FileAccess, AuthGoogle, Email, Socket;

...

procedure TForm1.Button1Click(Sender: TObject);
var
success: Boolean;
fac: HCkFileAccess;
jsonKey: PWideChar;
gAuth: HCkAuthGoogle;
tlsSock: HCkSocket;
accessToken: PWideChar;
mailman: HCkMailMan;
email: HCkEmail;

begin
success := False;

// This example requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.

// --------------------------------------------------------------------------------
// For a step-by-step guide for setting up your Google Workspace service account,
// see Setup Google Workspace Account for Sending SMTP GMail from a Service Account
// --------------------------------------------------------------------------------

// First load the JSON key into a string.
fac := CkFileAccess_Create();
jsonKey := CkFileAccess__readEntireTextFile(fac,'qa_data/googleApi/chilkat25-b4214220e565.json','utf-8');
if (CkFileAccess_getLastMethodSuccess(fac) <> True) then
  begin
    Memo1.Lines.Add(CkFileAccess__lastErrorText(fac));
    Exit;
  end;

// A Google service account JSON private key looks like this:

// {
//   "type": "service_account",
//   "project_id": "chilkat25",
//   "private_key_id": "b4214220f565881e19eeb97c2699bf5a0d1e3e0b",
//   "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQ...NXcM=\n-----END PRIVATE KEY-----\n",
//   "client_email": "chilkatsvc@chilkat25.iam.gserviceaccount.com",
//   "client_id": "109122032928932715958",
//   "auth_uri": "https://accounts.google.com/o/oauth2/auth",
//   "token_uri": "https://oauth2.googleapis.com/token",
//   "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
//   "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/chilkatsvc%40chilkat25.iam.gserviceaccount.com",
//   "universe_domain": "googleapis.com"
// }

gAuth := CkAuthGoogle_Create();
CkAuthGoogle_putJsonKey(gAuth,jsonKey);

// Specify a scope.
CkAuthGoogle_putScope(gAuth,'https://mail.google.com/');

// Request an access token that is valid for this many seconds.
CkAuthGoogle_putExpireNumSeconds(gAuth,3600);

// When using a Google Workspace account with Gmail APIs, a service account can impersonate a user 
// via a process called domain-wide delegation � and the "sub" claim in the JWT is what enables this.
// Domain-wide delegation allows a Google Workspace administrator to authorize a service account to 
// act on behalf of any user in the domain, without user interaction.

// This is required for server-to-server access to user data � such as reading/sending Gmail from a background service.
// This is your company email address.
CkAuthGoogle_putSubEmailAddress(gAuth,'info@chilkat.xyz');

// Connect to www.googleapis.com using TLS
tlsSock := CkSocket_Create();
success := CkSocket_Connect(tlsSock,'www.googleapis.com',443,True,5000);
if (success <> True) then
  begin
    Memo1.Lines.Add(CkSocket__lastErrorText(tlsSock));
    Exit;
  end;

// Send the request to obtain the access token.
success := CkAuthGoogle_ObtainAccessToken(gAuth,tlsSock);
if (success <> True) then
  begin
    Memo1.Lines.Add(CkAuthGoogle__lastErrorText(gAuth));
    Exit;
  end;

// Examine the access token:
accessToken := CkAuthGoogle__accessToken(gAuth);
Memo1.Lines.Add('Access Token: ' + accessToken);

// Sample output:
// ya29.a0AW4XtxjGTD67Z8 .... IRw0218

// The access token allows us to send unlimited emails while it's valid. Once it expires, we must obtain and use a new one.

// -----------------------------------------------------------------------
mailman := CkMailMan_Create();

// Set the properties for the GMail SMTP server:
CkMailMan_putSmtpHost(mailman,'smtp.gmail.com');
CkMailMan_putSmtpPort(mailman,587);
CkMailMan_putStartTLS(mailman,True);

CkMailMan_putSmtpUsername(mailman,'info@chilkat.xyz');
CkMailMan_putOAuth2AccessToken(mailman,accessToken);

// Create a new email object
email := CkEmail_Create();

CkEmail_putSubject(email,'This is a test');
CkEmail_putBody(email,'This is a test');
CkEmail_putFrom(email,'Chilkat Test <info@chilkat.xyz>');
success := CkEmail_AddTo(email,'Chilkat Software','info@chilkatsoft.com');
// To add more recipients, call AddTo, AddCC, or AddBcc once per recipient.

success := CkMailMan_SendEmail(mailman,email);
if (success <> True) then
  begin
    Memo1.Lines.Add(CkMailMan__lastErrorText(mailman));
    Exit;
  end;

success := CkMailMan_CloseSmtpConnection(mailman);
if (success <> True) then
  begin
    Memo1.Lines.Add('Connection to SMTP server not closed cleanly.');
  end;

Memo1.Lines.Add('Successfully sent email using Gmail with a service account key.');

CkFileAccess_Dispose(fac);
CkAuthGoogle_Dispose(gAuth);
CkSocket_Dispose(tlsSock);
CkMailMan_Dispose(mailman);
CkEmail_Dispose(email);

end;