Sample code for 30+ languages & platforms
PureBasic

Get Google API Access Token using JSON Private Key

See more Google APIs Examples

Demonstrates how to get a Google API access token using a JSON service account private key.

Chilkat PureBasic Downloads

PureBasic
IncludeFile "CkSocket.pb"
IncludeFile "CkAuthGoogle.pb"
IncludeFile "CkEmail.pb"
IncludeFile "CkFileAccess.pb"
IncludeFile "CkMailMan.pb"

Procedure ChilkatExample()

    success.i = 0

    ; 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.i = CkFileAccess::ckCreate()
    If fac.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    jsonKey.s = CkFileAccess::ckReadEntireTextFile(fac,"qa_data/googleApi/chilkat25-b4214220e565.json","utf-8")
    If CkFileAccess::ckLastMethodSuccess(fac) <> 1
        Debug CkFileAccess::ckLastErrorText(fac)
        CkFileAccess::ckDispose(fac)
        ProcedureReturn
    EndIf

    ; 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.i = CkAuthGoogle::ckCreate()
    If gAuth.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    CkAuthGoogle::setCkJsonKey(gAuth, jsonKey)

    ; Specify a scope.
    CkAuthGoogle::setCkScope(gAuth, "https://mail.google.com/")

    ; Request an access token that is valid for this many seconds.
    CkAuthGoogle::setCkExpireNumSeconds(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::setCkSubEmailAddress(gAuth, "info@chilkat.xyz")

    ; Connect to www.googleapis.com using TLS
    tlsSock.i = CkSocket::ckCreate()
    If tlsSock.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    success = CkSocket::ckConnect(tlsSock,"www.googleapis.com",443,1,5000)
    If success <> 1
        Debug CkSocket::ckLastErrorText(tlsSock)
        CkFileAccess::ckDispose(fac)
        CkAuthGoogle::ckDispose(gAuth)
        CkSocket::ckDispose(tlsSock)
        ProcedureReturn
    EndIf

    ; Send the request to obtain the access token.
    success = CkAuthGoogle::ckObtainAccessToken(gAuth,tlsSock)
    If success <> 1
        Debug CkAuthGoogle::ckLastErrorText(gAuth)
        CkFileAccess::ckDispose(fac)
        CkAuthGoogle::ckDispose(gAuth)
        CkSocket::ckDispose(tlsSock)
        ProcedureReturn
    EndIf

    ; Examine the access token:
    accessToken.s = CkAuthGoogle::ckAccessToken(gAuth)
    Debug "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.i = CkMailMan::ckCreate()
    If mailman.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    ; Set the properties for the GMail SMTP server:
    CkMailMan::setCkSmtpHost(mailman, "smtp.gmail.com")
    CkMailMan::setCkSmtpPort(mailman, 587)
    CkMailMan::setCkStartTLS(mailman, 1)

    CkMailMan::setCkSmtpUsername(mailman, "info@chilkat.xyz")
    CkMailMan::setCkOAuth2AccessToken(mailman, accessToken)

    ; Create a new email object
    email.i = CkEmail::ckCreate()
    If email.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    CkEmail::setCkSubject(email, "This is a test")
    CkEmail::setCkBody(email, "This is a test")
    CkEmail::setCkFrom(email, "Chilkat Test <info@chilkat.xyz>")
    success = CkEmail::ckAddTo(email,"Chilkat Software","info@chilkatsoft.com")
    ; To add more recipients, call AddTo, AddCC, or AddBcc once per recipient.

    success = CkMailMan::ckSendEmail(mailman,email)
    If success <> 1
        Debug CkMailMan::ckLastErrorText(mailman)
        CkFileAccess::ckDispose(fac)
        CkAuthGoogle::ckDispose(gAuth)
        CkSocket::ckDispose(tlsSock)
        CkMailMan::ckDispose(mailman)
        CkEmail::ckDispose(email)
        ProcedureReturn
    EndIf

    success = CkMailMan::ckCloseSmtpConnection(mailman)
    If success <> 1
        Debug "Connection to SMTP server not closed cleanly."
    EndIf

    Debug "Successfully sent email using Gmail with a service account key."


    CkFileAccess::ckDispose(fac)
    CkAuthGoogle::ckDispose(gAuth)
    CkSocket::ckDispose(tlsSock)
    CkMailMan::ckDispose(mailman)
    CkEmail::ckDispose(email)


    ProcedureReturn
EndProcedure