Skip to content

Instantly share code, notes, and snippets.

@gscales
Last active August 22, 2021 23:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gscales/02b32a66dfb0b11792b8a2d852188086 to your computer and use it in GitHub Desktop.
Save gscales/02b32a66dfb0b11792b8a2d852188086 to your computer and use it in GitHub Desktop.
Send Mail via Microsoft Graph using MIMEKit, Graph SDK and MSAL
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;
using Microsoft.Identity.Client;
using Newtonsoft.Json;
using Microsoft.Graph;
using System.IO;
using MimeKit;
using MimeKit.Utils;
namespace GraphMimeKitMSAL
{
class Program
{
static void Main(string[] args)
{
string mailboxName = "user@domain.com";
String recipient = "target@domain.com";
string scope = "https://graph.microsoft.com/.default";
string redirectUri = "http://localhost";
string clientId = "5471030d-f311-4c5d-91ef-74ca885463a7";
string inlineImagePath = @"C:\temp\test.jpg";
// Code attribution
// The following MIMEkit code is a modified version of the sample included on
// http://www.mimekit.net/docs/html/Working-With-Messages.htm
var message = new MimeMessage();
message.From.Add(MailboxAddress.Parse(mailboxName));
message.To.Add(MailboxAddress.Parse(recipient));
message.Subject = "How you doin?";
// create our message text, just like before (except don't set it as the message.Body)
var builder = new BodyBuilder();
// Set the plain-text version of the message text
builder.TextBody = @"Hey Alice,
What are you up to this weekend? Monica is throwing one of her parties on
Saturday and I was hoping you could make it.
Will you be my +1?
-- Joey
";
// In order to reference inline image from the html text, we'll need to add it
// to builder.LinkedResources and then use its Content-Id value in the img src.
var image = builder.LinkedResources.Add(inlineImagePath);
image.ContentId = MimeUtils.GenerateMessageId();
// Set the html version of the message text
builder.HtmlBody = string.Format(@"<p>Hey Alice,<br>
<p>What are you up to this weekend? Monica is throwing one of her parties on
Saturday and I was hoping you could make it.<br>
<p>Will you be my +1?<br>
<p>-- Joey<br>
<center><img src=""cid:{0}""></center>", image.ContentId);
// Now we just need to set the message body and we're done
message.Body = builder.ToMessageBody();
//End MimeKit Sample
var stream = new MemoryStream();
message.WriteTo(stream);
stream.Position = 0;
StringContent MessagePost = new StringContent(Convert.ToBase64String(stream.ToArray()),Encoding.UTF8, "text/plain");
GraphServiceClient graphServiceClient = new GraphServiceClient(new AuthHelp(redirectUri, scope, mailboxName, clientId));
var Message = new Message { };
var sendMailRequest = graphServiceClient.Me.SendMail(Message, null).Request().GetHttpRequestMessage();
sendMailRequest.Content = MessagePost;
sendMailRequest.Method = HttpMethod.Post;
var sendResult = graphServiceClient.HttpProvider.SendAsync(sendMailRequest).Result;
Console.WriteLine(sendResult.StatusCode);
}
}
class AuthHelp : IAuthenticationProvider
{
internal Microsoft.Identity.Client.PublicClientApplication PublicClientApplication { get; set; }
private string Scope { get; set; }
public AuthHelp(String redirectUri,string scope,string mailboxName,string clientId)
{
Scope = scope;
HttpClient httpclient = new HttpClient();
var TenantId = ((dynamic)JsonConvert.DeserializeObject(httpclient.GetAsync("https://login.microsoftonline.com/" + mailboxName.Split('@')[1] + "/v2.0/.well-known/openid-configuration")
.Result.Content.ReadAsStringAsync().Result))
.authorization_endpoint.ToString().Split('/')[3];
PublicClientApplicationBuilder pcaConfig = PublicClientApplicationBuilder.Create(clientId)
.WithTenantId(TenantId);
pcaConfig.WithRedirectUri(redirectUri);
PublicClientApplication = (Microsoft.Identity.Client.PublicClientApplication)pcaConfig.Build();
var tokenResult = PublicClientApplication.AcquireTokenInteractive(new[] { scope })
.WithPrompt(Microsoft.Identity.Client.Prompt.SelectAccount)
.WithLoginHint(mailboxName).ExecuteAsync().Result;
}
public Task AuthenticateRequestAsync(HttpRequestMessage request)
{
var accounts = PublicClientApplication.GetAccountsAsync().Result;
IAccount account = accounts.FirstOrDefault();
AuthenticationResult authResult = PublicClientApplication.AcquireTokenSilent(new[] { Scope }, account).ExecuteAsync().Result;
request.Headers.Authorization = new AuthenticationHeaderValue("bearer", authResult.AccessToken);
return System.Threading.Tasks.Task.CompletedTask;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment