2
votes

I am trying to send an email using the Outlook/Office 365 REST API, and I am trying to send it as an address that I have as a "Connected Account". Attempting to send the message returns a `` error. However, the API will let me create a draft with this address.

Additionally, I can send the API-created draft just fine, and I can also create and send messages as this account from the web interface.

Is there a way to authorize the API to be able to send a message as an address for a connected account?

2

2 Answers

1
votes

No, the API doesn't support this today. It has to do with the scope of the permissions that you consent to. "Allow this app to send mail as you" covers sending from your account, but not from another account, even if you have been granted access.

0
votes

Another thing you can think about is to leverage App-only authentication. You can configure a Azure AD App to have App-only authentication. After that, all the request will behalf of that app id and you should be able to delegate that app id to send email to anyone on behalf of the user you want. The following is the steps:

  • Create a Azure AD application.
  • Configure your Azure AD Application to allow App-only token by following Build service and daemon apps in Office 365. You also need a certificate for app-only token request.
  • Go to your Azure AD Application->Configuration, Click "Add application" to add "Office 365 Exchange Online". Select "Send email as any user" under "Application permission" dropdown box. It allows your Azure AD App to have permission to send email on behalf of someone.
  • Once you have Azure AD application configured, you can refer the following code for sending email on behalf of a specific user.

    string tenantId = "yourtenant.onmicrosoft.com";
    string clientId = "your client id";
    string resourceId = "https://outlook.office.com/";
    string resourceUrl = "https://outlook.office.com/api/v2.0/users/[email protected]/sendmail"; //this is your on behalf user's UPN
    string authority = String.Format("https://login.windows.net/{1}", AUTHORITYURL, tenantId);
    string certificatPath = @"c:\test.pfx"; //this is your certficate location.
    string certificatePassword = "xxxx"; // this is your certificate password
    var itemPayload = new
    {
        Message = new
        {
            Subject = "Test email",
            Body = new { ContentType = "Text", Content = "this is test email." },
            ToRecipients = new[] { new { EmailAddress = new { Address = "[email protected]" } } }
        }
    };
    
    //if you need to load from certficate store, use different constructors. 
    X509Certificate2 certificate = new X509Certificate2(certficatePath, certificatePassword, X509KeyStorageFlags.MachineKeySet);
    AuthenticationContext authenticationContext = new AuthenticationContext(authority, false);
    
    ClientAssertionCertificate cac = new ClientAssertionCertificate(clientId, certificate);
    
    //get the access token to Outlook using the ClientAssertionCertificate
    var authenticationResult = await authenticationContext.AcquireTokenAsync(resourceId, cac);
    string token = authenticationResult.AccessToken;
    
    //initialize HttpClient for REST call
    HttpClient client = new HttpClient();
    client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
    client.DefaultRequestHeaders.Add("Accept", "application/json"); 
    
    //setup the client post
    HttpContent content = new StringContent(JsonConvert.SerializeObject(itemPayload));
    //Specify the content type. 
    content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json;odata=verbose");
    HttpResponseMessage result = await client.PostAsync(url, content);
    if(result.IsSuccessStatusCode)
    {
        //email send successfully.
    }else
    {
        //email send failed. check the result for detail information from REST api.
    }
    

For a complete explanation, please reference to my blog Send email on behalf of a service account using Office Graph API

I hope it helps and let me know if you have questions.