Send an email from an Azure c# Function app function, through exchange online using the Graph api

Peter Salmon 45 Reputation points
2024-12-06T15:39:50.57+00:00

I want to be able to send an email from an Azure functions app using our Exchange online account (the same account as the Azure account is registered with).

My reading has directed me to the MS Graph API to do this, involving the following steps:

  1. Register an app within our Azure Entra ID management console.
  2. Give the app credentials (a secret) and API permissions (Microsoft.Graph.Mail.Send) (I have also added myself as an "owner" of the app.)
  3. Add the MS Graph and Identity client Nuget libraries to our Functions app.
  4. Code the app with the tenant id, client id and client secret. (Code copied in below).

All this I have done. However, when I run the function it persistently fails to pass credentials authentication, with the following exception:

Microsoft.Graph.Models.ODataErrors.ODataError: Access is denied. Check credentials and try again.

Having tried to run it within the Visual studio dev environment, I have published the app to our online staging environment as well and tried it there, with exactly the same results.

Any ideas of what I am missing?

Thanks

This is my code:

[Function("EmailSend")]
public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req)
{
	_logger.LogInformation("C# HTTP trigger function processed a request.");
	var message = new Microsoft.Graph.Users.Item.SendMail.SendMailPostRequestBody
	{
		Message = new Message
		{
			Subject = "This is the subject line",
			Body = new ItemBody
			{
				ContentType = BodyType.Text,
				Content = "This is the body of the email message."
			},
			ToRecipients = new List<Recipient>
			{
				new Recipient
				{
					EmailAddress = new EmailAddress
					{
						Address = "******@them.com" // This is the recipient of the message
					}
				}
			}
		}
	};            
	var scopes = new[] { "https://graph.microsoft.com/.default" };
	var tenantId = "my tenantId taken from the Entra Id overview";
	var clientId = "the Application (client) ID taken from App registration overview";
	var clientSecret = "the value of the client secret taken from the app certificates and secrets page";
	var clientSecretCredential = new ClientSecretCredential(
		tenantId, clientId, clientSecret);
	try
	{
		var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
		Task t = graphClient.Users["******@us.onmicrosoft.com"].SendMail.PostAsync(message);
		t.Wait();
	}
	catch (Exception ex) 
	{ 
		_logger.LogError(ex.ToString());
		return new OkObjectResult(ex.ToString());
		// System.Console.WriteLine(ex.ToString());
	}
	return new OkObjectResult("Email sent successfully!");
}
}
Microsoft Exchange Online
Azure Functions
Azure Functions
An Azure service that provides an event-driven serverless compute platform.
5,587 questions
Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
13,330 questions
{count} votes

Accepted answer
  1. Alex Zhang-MSFT 6,625 Reputation points Microsoft External Staff
    2024-12-10T00:40:51.04+00:00

    Hello, @Peter Salmon,

    Great to know that the issue has already been resolved and thanks for sharing the solution so that others experiencing the same thing can easily reference this!

    Since the Microsoft Q&A community has a policy that "The question author cannot accept their own answer. They can only accept answers by others(https://docs.microsoft.com/en-us/answers/support/accepted-answers#why-only-one-accepted-answer)", I'll repost your solution in case you'd like to "Accept (https://learn.microsoft.com/en-us/answers/support/accept-answer#accepted-answer-in-a-question-thread)" the answer).     


    Issue Symptom:

    The author wanted to be able to enable an Exchange Online account (the same account that is registered with Azure Accounts) to send emails from the Azure Functions application. When running the MS Graph API to perform this, it persistently failed to authenticate with credentials and the following exception occurred:User's image

    Having tried to run it within the Visual studio dev environment, he has published the app to online staging environment as well and tried it there, with exactly the same results.

    Resolution:

    The issue was the Type of API permissions given to the app for Microsoft.Graph.Mail.Send. Anyone who wants to send an email from an Azure function app this must be an Application (not Delegated) permission.


    Hope you can consider accepting the answer as it could help other members of the Microsoft Q&A community who have similar questions and are looking for solutions.

    Thank you for helping to improve Microsoft Q&A!

    Best Wishes,

    Alex Zhang

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.