DataFlex
DataFlex
Auto-Refresh O365 Access Token when Sending Email
See more Office365 Examples
Demonstrates how to automatically recover from an expired access token when sending email from smtp.office365.com using OAuth2 authentication. If the server responds with an error indicating that the access token is expired, then we refresh the access token and retry.Chilkat DataFlex Downloads
Use ChilkatAx-win32.pkg
Procedure Test
Boolean iSuccess
Handle hoJsonToken
Handle hoMailman
Variant vEmail
Handle hoEmail
Handle hoOauth2
Variant vSbJson
Handle hoSbJson
String sTemp1
Integer iTemp1
Move False To iSuccess
// This example requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
// An Office365 OAuth2 access token must first be obtained prior
// to running this code.
// First get our previously obtained OAuth2 access token.
Get Create (RefClass(cComChilkatJsonObject)) To hoJsonToken
If (Not(IsComObjectCreated(hoJsonToken))) Begin
Send CreateComObject of hoJsonToken
End
Get ComLoadFile Of hoJsonToken "qa_data/tokens/office365.json" To iSuccess
Get Create (RefClass(cComChilkatMailMan)) To hoMailman
If (Not(IsComObjectCreated(hoMailman))) Begin
Send CreateComObject of hoMailman
End
Set ComSmtpHost Of hoMailman To "smtp.office365.com"
Set ComSmtpPort Of hoMailman To 587
Set ComStartTLS Of hoMailman To True
// Use your Office365 email address for the SmtpUsername.
Set ComSmtpUsername Of hoMailman To "OFFICE365_EMAIL_ADDRESS"
Get ComStringOf Of hoJsonToken "access_token" To sTemp1
Set ComOAuth2AccessToken Of hoMailman To sTemp1
// Create a new email object
Get Create (RefClass(cComChilkatEmail)) To hoEmail
If (Not(IsComObjectCreated(hoEmail))) Begin
Send CreateComObject of hoEmail
End
Set ComSubject Of hoEmail To "This is a test"
Set ComBody Of hoEmail To "This is a test"
Set ComFrom Of hoEmail To "MY_NAME <OFFICE365_EMAIL_ADDRESS>"
Get ComAddTo Of hoEmail "John Doe" "somebody@example.com" To iSuccess
// Call SendEmail to connect to the SMTP server and send.
// The connection (i.e. session) to the SMTP server remains
// open so that subsequent SendEmail calls may use the
// same connection.
Get pvComObject of hoEmail to vEmail
Get ComSendEmail Of hoMailman vEmail To iSuccess
If (iSuccess = True) Begin
Showln "Mail Sent!"
Procedure_Return
End
// If we fall through to here, it means something failed.
// If we failed because of an invalid or expired access token, we should get this SMTP status code and error message:
// response: 535 5.7.3 Authentication unsuccessful [CH2PR19CA0023.namprd19.prod.outlook.com]
// status code: 535
Get ComLastSmtpStatus Of hoMailman To iTemp1
If (iTemp1 <> 535) Begin
Get ComLastErrorText Of hoMailman To sTemp1
Showln sTemp1
Procedure_Return
End
// If we get here, it means the SMTP status code equaled 535, which is an authentication failure.
// Let's refresh the access token, and then retry..
Get Create (RefClass(cComChilkatOAuth2)) To hoOauth2
If (Not(IsComObjectCreated(hoOauth2))) Begin
Send CreateComObject of hoOauth2
End
// Update to use your token endpoint.
// In the Azure Portal, in "App registrations", go to "Endpoints" (located to the right of the "+ New registration" link.)
// Find your endpoint for the "OAuth 2.0 token endpoint (v2)"
// See Office365 OAuth2 Endpoints
Set ComTokenEndpoint Of hoOauth2 To "https://login.microsoftonline.com/xxxxxxxxxx-71bf-4ebe-a866-738364321bf2/oauth2/v2.0/token"
// Replace these with actual values.
Set ComClientId Of hoOauth2 To "CLIENT_ID"
Set ComClientSecret Of hoOauth2 To "CLIENT_SECRET"
// Get the "refresh_token"
Get ComStringOf Of hoJsonToken "refresh_token" To sTemp1
Set ComRefreshToken Of hoOauth2 To sTemp1
// Send the HTTP POST to refresh the access token..
Get ComRefreshAccessToken Of hoOauth2 To iSuccess
If (iSuccess <> True) Begin
Get ComLastErrorText Of hoOauth2 To sTemp1
Showln sTemp1
Procedure_Return
End
Get ComAccessToken Of hoOauth2 To sTemp1
Showln "New access token: " sTemp1
Get ComRefreshToken Of hoOauth2 To sTemp1
Showln "New refresh token: " sTemp1
// Update the JSON with the new tokens.
Get ComAccessToken Of hoOauth2 To sTemp1
Get ComUpdateString Of hoJsonToken "access_token" sTemp1 To iSuccess
Get ComRefreshToken Of hoOauth2 To sTemp1
Get ComUpdateString Of hoJsonToken "refresh_token" sTemp1 To iSuccess
// Save the new JSON access token response to a file.
Get Create (RefClass(cComChilkatStringBuilder)) To hoSbJson
If (Not(IsComObjectCreated(hoSbJson))) Begin
Send CreateComObject of hoSbJson
End
Set ComEmitCompact Of hoJsonToken To False
Get pvComObject of hoSbJson to vSbJson
Get ComEmitSb Of hoJsonToken vSbJson To iSuccess
Get ComWriteFile Of hoSbJson "qa_data/tokens/office365.json" "utf-8" False To iSuccess
Showln "OAuth2 authorization granted!"
Get ComAccessToken Of hoOauth2 To sTemp1
Showln "New Access Token = " sTemp1
// -------------------------------------------------
// Retry the SMTP send using the refreshed access token.
Showln "Retrying the send using the refreshed access token."
Get ComAccessToken Of hoOauth2 To sTemp1
Set ComOAuth2AccessToken Of hoMailman To sTemp1
Get pvComObject of hoEmail to vEmail
Get ComSendEmail Of hoMailman vEmail To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoMailman To sTemp1
Showln sTemp1
Procedure_Return
End
Get ComCloseSmtpConnection Of hoMailman To iSuccess
If (iSuccess <> True) Begin
Showln "Connection to SMTP server not closed cleanly."
End
Showln "Email sent!"
End_Procedure