Skip to main content

Notifications

Sending Emails from Microsoft Dynamics AX 2012 using the Microsoft Graph API with Modern Authentication Including an Attachment

People have asked for an example of sending Emails with attachments using the MSGraph API directly from AX 2012.  Below is the same code I published in an earlier post but with an attachment.  Before running this make sure the attachment exists in the location specified in the code.  A filename with a UNC path is a better choice given you may have more than one AOS server.  For this example I am running in a development single AOS environment with the client also running on the same server. 

static void MSgraphSendMailWithAttach_Job(Args _args)
{
    System.Net.HttpWebRequest          webRequest;
    System.Net.HttpWebResponse         webResponse;
    System.IO.Stream                   stream;
    System.IO.StreamReader             streamReader;
    System.Byte[]                      bytes;
    System.Net.WebHeaderCollection     headers;
    str response, respCode, ErrorString;
    System.Text.UTF8Encoding           encoding;
    Dialog      dialog;
    DialogField dialogFieldEA, dialogFieldAT;
    str email_Address, access_token;
    // Added for Attachement
    str MyJson;
    str path;
    FileName filePath, fileName, fileExt;
    BinaryIO binaryIO;
    FileIoPermission _perm;
    str base64;
    bindata bindata = new bindata();
    ;

    // Get basic user input
    dialog = new Dialog("Send Email Using MsGrpah API with Token");
    //dialogGroup1 = dialog.addGroup("Enter All These");
    dialogFieldEA = dialog.addFieldValue(extendedTypeStr(InfoMessage),'someone@somewhere.com', 'Email Addr');
    dialogFieldAT = dialog.addFieldValue(extendedTypeStr(InfologText),'0a1b2c3d-4e5f....', 'Access Token');
    dialog.run();
    email_Address = dialogFieldEA.value();
    access_token  = dialogFieldAT.value();

    try
    {
        path = "C:\\Temp\\Example.pdf";
        [filePath, filename, fileExt] = fileNameSplit(path);

        _perm = new FileIoPermission(path,'r');
        _perm.assert();

        if(System.IO.File::Exists(path))
        {
          bindata.loadFile(path);
          base64 = bindata.base64Encode();
        }
    }
    catch
    {
        ErrorString = AifUtil::getClrErrorMessage();
        throw error(ErrorString);
    }
    bindata = null; //close file
    CodeAccessPermission::revertAssert();  //Revert permissions although this shouild go away when method is over

    new InteropPermission(InteropKind::ClrInterop).assert();

    //Create webRequest
    webRequest = System.Net.WebRequest::Create('https://graph.microsoft.com/v1.0/me/sendMail') as  System.Net.HttpWebRequest;
    headers = new System.Net.WebHeaderCollection();
    headers.Add("Authorization: Bearer "   access_token);
    webRequest.set_Headers(headers);
    webRequest.set_Method('POST');
    webRequest.set_ContentType('application/json');
    webRequest.set_Timeout(15000); // Set the 'Timeout' property in Milliseconds.

    MyJson = "{\"message\": { \"subject\": \"Test Subject\", \"body\": { \"contentType\": \"Text\", \"content\": \"Hello World !\" }, \"toRecipients\": [ { \"emailAddress\": { \"address\": \""   email_Address   "\"} } ] ";
       //Add in the attachement
       MyJson = MyJson   " , ";
       MyJson = MyJson   "  \"attachments\": [ ";
       MyJson = MyJson   "    { ";
       MyJson = MyJson   "      \"isInline\": false, ";
       MyJson = MyJson   "    \"@odata.type\": \"#microsoft.graph.fileAttachment\", ";
       MyJson = MyJson   "    \"contentBytes\": \""   base64   "\", ";
       MyJson = MyJson   "    \"name\": \""   fileName   fileExt   "\" } ";
       MyJson = MyJson   "  ] ";
    MyJson = MyJson   "}, \"saveToSentItems\": \"true\" }";
    
    //Force TLS12 which I had to add later (Mid2022)
    System.Net.ServicePointManager::set_SecurityProtocol(System.Net.SecurityProtocolType::Tls12);
    
    

    try
    {
       //Create the data string to POST
       encoding    = new System.Text.UTF8Encoding();
       bytes  = encoding.GetBytes(MyJson);
       webRequest.set_ContentLength(bytes.get_Length());
       //Setup the stream and Submit the request
       stream = webRequest.GetRequestStream();
       stream.Write(bytes, 0, bytes.get_Length());
       stream.Close();
       //Get the response
       webResponse = webRequest.GetResponse();
       stream = webResponse.GetResponseStream();
       streamReader = new System.IO.StreamReader(stream);
       response = streamReader.ReadToEnd();
       streamReader.Close();
       stream.Close();
    }
    catch
    {  //If contains 401 then get new token
        ErrorString = AifUtil::getClrErrorMessage();
        throw error(ErrorString);
    }

    CodeAccessPermission::revertAssert();
    info("Success");
}
 

Comments

*This post is locked for comments