M365: Microsoft Graph – Part 10 – Send Email using Graph API from Console Application (Background Job)

Hi All,

LIFE IS BEAUTIFUL 🙂 Today with MS Graph, my favorite feature of M365 🙂

In following previous articles we have discussed regarding Microsoft Graph. Today again long time back new article on MS GRAPH 🙂

In today’s article we will simple discuss steps to send an email from console application (background job) using Graph API.


M365 - Microsoft Graph - "Mail.Send" permission giving to Azure App
Fig1: M365 – Microsoft Graph – “Mail.Send” permission assigning to Azure App

Detailed Steps:

  • Once we have Azure App with respective permission, we are ready to consume the GraphServiceClient (Microsoft.Graph) class which requires instance of IAuthenticationProvider (Microsoft.Graph ) as
AuthProvider authProvider = new AuthProvider(); // AuthProvider is our custom class. Please have a look at below code snippet. 
GraphServiceClient _graphClient = new GraphServiceClient(authProvider);
  • We have our own AuthProvider class inherited from IAuthenticationProvider interface and implementing AuthenticateRequestAsync() method as
  • Here we are using X509Certificate2 certificate and AppId for authentication. We are not using Client Secret key.
namespace KnowledgeJunction.Azure
  public class AuthProvider : IAuthenticationProvider

    /// <summary>
    /// This method is called when actual request is made
    /// </summary>
    /// <param name="request">Request object, in header we add the access token</param>
    /// <returns></returns>
    public async Task AuthenticateRequestAsync(HttpRequestMessage request)
        string resource = "https://graph.microsoft.com";
        //reading tenant id from config file
        string authority = "https://login.windows.net/" +  ConfigurationManager.AppSettings["TenantId"];

    AuthenticationContext auth = new AuthenticationContext(authority, false);
    // Here we are using AppID and certificate for authentication. We are not 
   // using client secret key
   //Reading azure app id from config file
   // My certificate - X509Certificate2     
        var cac = new ClientAssertionCertificate(ConfigurationManager.AppSettings["AzureAppId"], X509Certificate2);

      var authResult = await auth.AcquireTokenAsync(resource, cac);

        var accessToken = authResult.AccessToken;
        request.Headers.Add("Authorization", "Bearer " + accessToken);
      catch (Exception ex)
         //ToDo : Proper exception handling
  • Create the Message (Microsoft.Graph.Message) object as
var message = new Microsoft.Graph.Message
          Subject = subj,
          Body = new ItemBody
            ContentType = Microsoft.Graph.BodyType.Html,
            Content = body
          ToRecipients = new List<Recipient>()
                        new Recipient

                            EmailAddress = new Microsoft.Graph.EmailAddress
                                Address = to
  • Call SendMail method of GraphServiceClient class as
await graphClient.Me
  • When above request is made, method “AuthenticateRequestAsync” of AuthProvider class is getting called.
  • If we don’t want to send email on be half of specific user, we could use shared email box as well.


Thanks a lot for reading 🙂 Enjoy the beautiful LIFE 🙂 HAVE A SAFE LIFE 🙂 TAKE CARE 🙂

Prasham Sabadra

LIFE IS VERY BEAUTIFUL :) ENJOY THE WHOLE JOURNEY :) Founder of Knowledge Junction and live-beautiful-life.com, Author, Learner, Passionate Techie, avid reader. Certified Professional Workshop Facilitator / Public Speaker. Scrum Foundation Professional certificated. Motivational, Behavioral , Technical speaker. Speaks in various events including SharePoint Saturdays, Boot camps, Collages / Schools, local chapter. Can reach me for Microsoft 365, Azure, DevOps, SharePoint, Teams, Power Platform, JavaScript.

You may also like...

9 Responses

  1. Pete says:

    You would be the first person I’ve seen posting use of GraphServiceClient using the Daemon app design utilizing a certificate instead of a client secret. The documentation in this area is quite sparse so its hard to find adequate examples so thanks for posting what you done here.

    I do have a question though. How do you go about caching the token using ConfidentialClientApplicationBuilder? MSAL provides in memory caching by default for ASP.Net, but for Daemon apps that are not blessed as a web service how do you enable app file based caching? Again, there are tons of examples for User Token caching, but the Daemon app cache is different in that there is no refresh token and again… documentation seems to have tanked in this realm. Microsoft doesn’t seem to have updated documentation and code examples for using ConfidentialClientApplicationBuilder with app cache, but there’s plenty of documentation and examples for using app cache with the deprecated ConfidentialClientApplication API version.

  2. Hi Pete,

    Thanks a lot 🙂

    Regarding answer to your question, I am sorry but I didnt require to use cache in my Jobs. MSAL refreshes the token automatically.

  3. Minal says:

    I tried your code to send emails in background service, but I got an error as below:

    Error :Code: BadRequest
    Message: Current authenticated context is not valid for this request. This occurs when a request is made to an endpoint that requires user sign-in. For example, /me requires a signed-in user. Acquire a token on behalf of a user to make requests to these endpoints. Use the OAuth 2.0 authorization code flow for mobile and native apps and the OAuth 2.0 implicit flow for single-page web apps.

    Inner error

    Can you tell me where I have been wrong?


  4. Hrishikesh Sawalkar says:

    Can you please share your code to sshrishi@gmail.com

  1. July 7, 2020

    […] favorite feature “Microsoft Graph”. This is sequel of my previous Graph Article – M365: Microsoft Graph – Part 10 – Send Email using Graph API from Console Application (Backgroun… […]

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: