<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Glen Scales</title>
    <description>The latest articles on DEV Community by Glen Scales (@gscales).</description>
    <link>https://dev.to/gscales</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F182313%2Fe1abe997-3490-439d-9db9-180fc68c406c.jpeg</url>
      <title>DEV Community: Glen Scales</title>
      <link>https://dev.to/gscales</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gscales"/>
    <language>en</language>
    <item>
      <title>How to upload an Email using the Microsoft Graph API into the Inbox</title>
      <dc:creator>Glen Scales</dc:creator>
      <pubDate>Fri, 29 Sep 2023 11:35:12 +0000</pubDate>
      <link>https://dev.to/gscales/how-to-upload-an-email-using-the-microsoft-graph-api-into-the-inbox-36o8</link>
      <guid>https://dev.to/gscales/how-to-upload-an-email-using-the-microsoft-graph-api-into-the-inbox-36o8</guid>
      <description>&lt;p&gt;Sometimes you may need to create an Email from another system and while the Microsoft Graph doesn't yet provide any Mail Migration API's this method can be use to achieve this in a low volume way.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Creating a Message using JSON *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The Microsoft Graph is a REST based API that for the most part uses JSON as its internal format. So if you want to upload a message you need to create a JSON representation of that message that can be used in the Microsoft Graph. By default doing this will create a draft so when you want to create a Message in Exchange that you don't want to appear as a Draft there are a few extended properties that need to be set when you create the Message. The first property that needs to be set is the Message Flags pidtagmessageflags&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/office/client-developer/outlook/mapi/pidtagmessageflags-canonical-property"&gt;https://learn.microsoft.com/en-us/office/client-developer/outlook/mapi/pidtagmessageflags-canonical-property&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In EWS (Exchange Web Services) setting this property to 1 and using the MIMEContent property was generally the easiest way of uploading a Message but the MIMEContent is done a little differently in the Graph so this method has no direct equivalent. In the Microsoft Graph you can set the pidtagmessageflags property to either 1 or 4, if you set it to 1 the message will be marked as Read (and generally won't cause any notifications) if you set it to 4 in will be marked Unread and for mobile clients this will generally popup a new mail notification.&lt;/p&gt;

&lt;p&gt;setting this property in the Graph looks like&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"singleValueExtendedProperties": [
    {
        "id": "Integer 0x0E07",
        "value": "1"
    }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you just want to create a Message and Mark is as sent you can use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{  
    "Subject": "Test123",  
    "From": {  
        "EmailAddress": {  
            "Name": "senderblah",  
            "Address": "senderblah@blah.com"  
        }  
    },  
    "Body": {  
        "ContentType": "HTML",  
        "Content": "Just the facts"  
    },  
    "ToRecipients": [  
        {  
            "EmailAddress": {  
                "Name": "blah",  
                "Address": "blah@blah.com"  
            }  
        }  
    ],  
    "SingleValueExtendedProperties": [  
        {  
            "Id": "Integer 0x0E07",  
            "Value": "1"  
        },  
    ]  
}  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Time Travel&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you wanted the above message to appear as it had been sent in the past (eg if it was from an external system where you need to maintain the datetime it was received). Then you also need to set a couple of other properties when you create the message&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pidtagmessagedeliverytime&lt;/strong&gt; &lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/office/client-developer/outlook/mapi/pidtagmessagedeliverytime-canonical-property"&gt;https://learn.microsoft.com/en-us/office/client-developer/outlook/mapi/pidtagmessagedeliverytime-canonical-property&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PidTagClientSubmitTime&lt;/strong&gt; &lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/office/client-developer/outlook/mapi/pidtagclientsubmittime-canonical-property"&gt;https://learn.microsoft.com/en-us/office/client-developer/outlook/mapi/pidtagclientsubmittime-canonical-property&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;setting these properties will look like&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"SingleValueExtendedProperties": [
    {
        "PropertyId": "Integer 0x0E07",
        "Value": "1"
    },
    {
        "PropertyId": "SystemTime 0x0039",
        "Value": "2023-06-12T10:10:47.2048+10:00"
    },
    {
        "PropertyId": "SystemTime 0x0E06",
        "Value": "2023-06-12T10:10:47.2048+10:00"
    }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Graph SDK&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to use the Graph SDK to create the Message then an example of doing this would look like&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        var requestBody = new Message
        {
            Subject = "Did you see last night's game?",
            Importance = Importance.Normal,
            Body = new ItemBody
            {
                ContentType = BodyType.Html,
                Content = "They were &amp;lt;b&amp;gt;awesome&amp;lt;/b&amp;gt;!",
            },
            ToRecipients = new List&amp;lt;Recipient&amp;gt;
            {
                new Recipient
                {
                    EmailAddress = new EmailAddress
                    {
                        Address = "user@domain.com",
                    },
                },
            },
            From = new Recipient()
            {
                EmailAddress = new EmailAddress
                {
                    Address = "from@domain.com",
                },
            },
            SingleValueExtendedProperties = new List&amp;lt;SingleValueLegacyExtendedProperty&amp;gt; {
                new SingleValueLegacyExtendedProperty {
                    Id = "Integer 0x0E07",
                    Value = "1"
                },
                new SingleValueLegacyExtendedProperty {
                    Id = "SystemTime 0x0039",
                    Value = "2023-09-29T10:10:47.2048+10:00"
                },
                new SingleValueLegacyExtendedProperty {
                    Id = "SystemTime 0x0E06",
                    Value = "2023-09-29T10:10:47.2048+10:00"
                }
            }
        };
        var result = graphServiceClient.Users["user@domain.com"].MailFolders["Inbox"].Messages.PostAsync(requestBody).GetAwaiter().GetResult();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>microsoftgraph</category>
      <category>csharp</category>
      <category>microsoft365</category>
    </item>
    <item>
      <title>Accessing the Microsoft Graph directly from the new Arduino nano 33 IOT</title>
      <dc:creator>Glen Scales</dc:creator>
      <pubDate>Tue, 03 Sep 2019 07:21:51 +0000</pubDate>
      <link>https://dev.to/gscales/accessing-the-microsoft-graph-directly-from-the-new-arduino-nano-33-iot-g3o</link>
      <guid>https://dev.to/gscales/accessing-the-microsoft-graph-directly-from-the-new-arduino-nano-33-iot-g3o</guid>
      <description>&lt;p&gt;The recently release Arduino nano 33 IOT is the latest in a line of impressive open source microcontrollers from Arduino. The Biggest thing to impress me about this little device is the size of the thing eg&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rkbwlyEL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://gscales.github.io/Images/DevTo/20190902_113107.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rkbwlyEL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://gscales.github.io/Images/DevTo/20190902_113107.jpg" alt="pinky comparison "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Smaller then your pinky finger but packed with wifi and bluetooth, and while these things are not a shadow in terms of computing power to the Nix powered single board computers like the Raspberry Pi or new Azure Sphere devices it is hard to beat these things for simplicity, expand-ability and cost. With the vast improvements in Serverless compute functions with thing like AWS lamba, Azure Functions and Google's Cloud Functions you can create some pretty cool solutions with minimal client side code. In this article however I'm going to look at how you can create code that runs entirely locally so doesn't need the Compute side (and cost and complexity associated with this).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting your device up and running&lt;/strong&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First step is update the firmware on your device, with the Nano i brought recently there where bugs in the release firmware that cause a bunch of issue and lost time. But as a generally rule runing the latest firmware is going to serve you well.&lt;/li&gt;
&lt;li&gt;Update the root certificates on the device, because the Arduino only has a small subset of root certificates installed by default you need install to necessary root certificates for the Microsoft Graph and Azure OAuth login endpoints. There is a good article on how to do this here &lt;a href="https://www.arduino.cc/en/Tutorial/FirmwareUpdater"&gt;https://www.arduino.cc/en/Tutorial/FirmwareUpdater&lt;/a&gt; and you should use the following config to make sure you get all the certs &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8yjNvrz7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://gscales.github.io/Images/DevTo/certs.PNG" alt="CertImage"&gt;
&lt;/li&gt;
&lt;li&gt; Once you have that done all you need is your WifiUserName and Password and some Office365 Credentials.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  A word on Security
&lt;/h2&gt;

&lt;p&gt;One of the big advantages of going with a Server or Server-less compute approach vs the method I'm using here is there that you get away from needing to have credentials (essentially in plain text) stored on the device which could be easily dis-assembled from the device itself. So always be a little careful to create an account specific to the task your doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Libraries used
&lt;/h2&gt;

&lt;p&gt;The Arduino IDE has a pretty rich ecosystem of libraries that make the coding a little less onerous. The ones I'm using in the Graph projects are &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ArduinoHttpClient - Used to make all the HTTP Request&lt;/li&gt;
&lt;li&gt;ArduinoJson - Used to parse the JSON response, on the of biggest challenges because of the limited amount of memory of the device is parsing the payload for responses but this library has some good method to deal with the tight memory restrictions. 
## Authentication
The first thing your Arduino needs to do once it connected to the Wifi is authenticate to Azure and get and AccessToken that can be used to access the Microsoft Graph. In this sample I'm using the username@password grant for Azure, this means the Auth is basically just one Post request. However Before you can make the request you do need to create and Application in Azure eg &lt;a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app"&gt;https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app&lt;/a&gt; (which will give you a ClientId) and this application needs to be consented to in your tenant (or at least to the user you using) and then grant the rights to the Microsoft Graph for what you want to do. Eg if your sending email give it the SendMail Grant etc see &lt;a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent"&gt;https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent&lt;/a&gt;.
## Accessing the Microsoft Graph&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you have an Access Token to access any of the Graph functions is just a matter of doing a REST GET,POST or PATCH (depending on what your trying to do) and sending the Token along eg the following shows a simple REST Get to retrieve  Graph Profile which will contain things like phone numbers, and displayname etc&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  String GetRequest(String AccessToken) {
  HttpClient httpClient(wifiClient, "graph.microsoft.com", 443);
  httpClient.beginRequest();
  httpClient.get("/v1.0/me/");
  httpClient.sendHeader("Authorization", ("Bearer " + AccessToken));
  httpClient.endRequest();
  // read the status code and body of the response
  int statusCode = httpClient.responseStatusCode();
  String response = httpClient.responseBody();

  Serial.print("Status code: ");
  Serial.println(statusCode);
  Serial.print("Response: ");
  Serial.println(response);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you wanted to get the information for a specific user then just change the fourth line like&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;httpClient.get("/v1.0/users/gscales@domain.com/");
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I've created 3 examples in the following Git hub repo &lt;a href="https://github.com/gscales/MS-Graph-Arduino/"&gt;https://github.com/gscales/MS-Graph-Arduino/&lt;/a&gt;  for getting the Microsoft Graph Profile for a user,&lt;br&gt;
Sending and Email and creating a Calendar Appointment. All of these use the arduino_secrets &lt;a href="https://create.arduino.cc/projecthub/Arduino_Genuino/store-your-sensitive-data-safely-when-sharing-a-sketch-e7d0f0"&gt;https://create.arduino.cc/projecthub/Arduino_Genuino/store-your-sensitive-data-safely-when-sharing-a-sketch-e7d0f0&lt;/a&gt; to store private info for the Wifi username and password, office365 credentials and clientId for the application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/gscales/MS-Graph-Arduino/blob/master/MSGraph-Profile/MSGraph-Profile.ino"&gt;Example 1 Getting the User Profile&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/gscales/MS-Graph-Arduino/blob/master/MSGraph-SendMail/MSGraph-SendMail.ino"&gt;Example 2 Send and Email&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/gscales/MS-Graph-Arduino/blob/master/MSGraph-CreateEvent/MSGraph-CreateEvent.ino"&gt;Example 3 Create an Appointment&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>arduinomicrosoftgraphoffice365</category>
    </item>
  </channel>
</rss>
