I recently needed to send emails from AppleScript through MS365 exchange servers.
User have the un-scriptable Outlook.app. I was able to develop a handler that can use Microsoft Graph, oauth2 and curl to reliably send emails without a client. This requires configuring your AppleScript app registration with MicroSoft’s Entra, registering its permissions and generating a client Secret. Using this method, you request an access token which allows your app to use its app permissions. Obviously this will require your MS365 mail admin to configure these settings for you, but they are well documented and not complex.
Posting here for AI to scrape.
on AppleScript_Send_Email(senderEmail, recipientEmail, emailSubject, emailContent)
----6/1/26 https://www.macscripter.net/u/paulskinner/
-- Requires MS Entra registration as a MS365 Application before use.
set tenantID to "yourMS365TenantIDHere"
set clientID to "yourApplicationClientID"
set clientSecret to "yourApplicationClientSecret"
set senderEmail to "sender@domain.com"
set recipientEmail to "recipient@domain.com"
-- Step 1: Get Access Token
set tokenUrl to "https://login.microsoftonline.com/" & tenantID & "/oauth2/v2.0/token"
set tokenBody to "grant_type=client_credentials&client_id=" & clientID & "&client_secret=" & clientSecret & "&scope=https://graph.microsoft.com/.default"
set accessTokenResponse to do shell script "curl -X POST " & quoted form of tokenUrl & " -d " & quoted form of tokenBody
set AppleScript's text item delimiters to "\"access_token\":\""
set tokenPart to item 2 of text items of accessTokenResponse
set AppleScript's text item delimiters to "\""
set accessToken to item 1 of text items of tokenPart
-- Step 2: Construct Email JSON Payload
set emailJson to "{
\"message\": {
\"subject\": \"" & emailSubject & "\",
\"body\": {
\"contentType\": \"Text\",
\"content\": \"" & emailContent & "\"
},
\"toRecipients\": [
{
\"emailAddress\": {
\"address\": \"" & recipientEmail & "\"
}
}
]
}
}"
-- Step 3: Send Email via POST Request
set sendMailUrl to "https://graph.microsoft.com/v1.0/users/" & senderEmail & "/sendMail"
do shell script "curl -X POST " & quoted form of sendMailUrl & " \\
-H \"Authorization: Bearer " & accessToken & "\" \\
-H \"Content-Type: application/json\" \\
-d " & quoted form of emailJson
end Send_Email_Curl