Setup Email SMTP in AX - Song Nghia - Technical Consultant

Dynamic 365 FO Dynamic 365 Retail

Thứ Sáu, 27 tháng 7, 2018

Setup Email SMTP in AX


Setup Email SMTP in AX 






This function is built to alternate Sysmailer class to avoid "error script 25"
//Try to read comment carefully to understand how this method works
static void sendEmail(container          _toAddressCon,
                      str                _mailSubject       = "",
                      str                _mailBody          = "",
                      container          _attachmentCon     = conNull(),
                      container          _ccAddressCon      = conNull(),
                      container          _bccAddressCon     = conNull(),
                      str                _fromAddress       = "ax-automail@scancom.net",//SysEmailParameters::find().SMTPUserName,
                      str                _SMTPServer        = "smtp.office365.com",//SysEmailParameters::find().SMTPRelayServerName,
                      int                _portNumber        = 587,//SysEmailParameters::find().SMTPPortNumber,
                      str                _userName          = "ax-automail@scancom.net",//SysEmailParameters::find().SMTPUserName, //should be a valid email address
                      str                _password          = "P@$$word")//SysEmailParameters::password())

{
    //Define current Live AOSs
    #define.LiveAOSId_01("VNBD-AOS-S01@2712")
    #define.LiveAOSId_02("VNBD-AOS-S02@2712")
    #define.LiveAOSId_03("VNBD-AOS-S03@2712")
    #define.LiveAOSId_04("VNBD-AXTEST-MP@2712")

    System.Net.Mail.MailMessage             mailMessage;

    System.Net.Mail.MailAddress             mailFrom;
    System.Net.Mail.MailAddress             mailTo;

    System.Net.Mail.MailAddressCollection   addressCollection_CC;
    System.Net.Mail.MailAddressCollection   addressCollection_BCC;

    System.Net.Mail.Attachment              attach;
    System.Net.Mail.AttachmentCollection    attachCollection;

    System.Net.Mail.SmtpClient              smtpClient;
    System.Net.NetworkCredential            networkCredential;
    str                                     toAddress_Single;
    str                                     toAddresses_All;
    int                                     i;
    AOSId                                   currentAOSId;
    FileIOPermission                        filePermission;
    boolean                                 hasAttachment;
    str                                     ccAddress, bccAddress;
    str                                     attachmentPath;
    int                                     noOfRecipient;

    //cnt email log
    SCA_ScancomParameters                   scancomParameters;
    SCA_EmailLog                            emailLog;
    str                                     attachmentPathEmail;
    str                                     ccAddress_All;
    str                                     bccAddress_All;
    //-end

    InteropPermission                       permission = new InteropPermission(InteropKind::ClrInterop);
    ;

    scancomParameters = SCA_ScancomParameters::find();
    permission.assert();

    //Temporary disable below code as user can not read AOS due to right limitation
    /*currentAOSId = conpeek(VtvUtil::getCurrentAOSInstance(), 1);

    //Only allow sending email if current environment is Live
    if ( !(currentAOSId == #LiveAOSId_01
        || currentAOSId == #LiveAOSId_02
        || currentAOSId == #LiveAOSId_03
        || currentAOSId == #LiveAOSId_04))
    {
        return;
    }*/


    if (!SysEmailDistributor::validateEmail(_userName))
        throw error("Invalid sender user name. Email sending cancelled!");

    if (conlen(_toAddressCon) == 0)
    {
        throw error("No recipient address to send!");
    }

    //Convert address container to string, seperated by comma
    //toAddresses = con2str(_toAddressCon, ","); // this code is more efficient but should not be used due to:
                                                 // + It does not remove duplicated email addresses
                                                 // + It does not validate single email address format

    //This code wil convert, validate & remove duplicated email address in container
    for (i =1; i <= conlen(_toAddressCon); i++)
    {
        toAddress_Single = conpeek(_toAddressCon, i);

        //Make sure every single recipient address is in correct format
        //if (!SysEmailDistributor::validateEmail(toAddress_Single))
        //     throw error(strfmt("Recipient address: %1 is invalid.", toAddress_Single));

        //Combine all single addresses into one address string, seperated by comma (,)
        if (toAddress_Single// && SysEmailDistributor::validateEmail(toAddress_Single)
            && !strScan(toAddresses_All, toAddress_Single, 1, strlen(toAddresses_All)))
        {
            toAddresses_All = toAddresses_All ? toAddresses_All + "," + toAddress_Single : toAddress_Single;
            noOfRecipient ++;
        }
    }

    try
    {
        smtpClient = new System.Net.Mail.SmtpClient(_SMTPServer, _portNumber);

        //if (noOfRecipient >= 10)
        smtpClient.set_Timeout(1000000); //lan.nguyen - must add to avoid 'Time out' error when send to > 10 recipient

        //Init mail message with sender & receipient
        mailMessage = new System.Net.Mail.MailMessage(_fromAddress, toAddresses_All);

        //Add CC address
        addressCollection_CC = mailMessage.get_CC(); //Note: Method name 'get_CC' is case sensitive

        for (i = 1; i <= conLen(_ccAddressCon); i++)
        {
            ccAddress = conPeek(_ccAddressCon,1);
            if (ccAddress)
            {
                addressCollection_CC.Add(ccAddress);
                 //cnt record email log
                ccAddress_All += ccAddress + ';';
                //cnt - end
            }
        }

        //Add BCC address
        addressCollection_BCC = mailMessage.get_Bcc(); //Note: Method name 'get_Bcc' is case sensitive

        for (i = 1; i <= conLen(_bccAddressCon); i++)
        {
            bccAddress = conPeek(_bccAddressCon,1);
            if (bccAddress)
            {
                addressCollection_BCC.Add(bccAddress);
                //cnt record email log
                bccAddress_All += bccAddress + ';';
                //cnt -end
            }
        }

        //Init mail subject & content
        mailMessage.set_IsBodyHtml(true);       //Enable HTML mail content
        mailMessage.set_Subject(_mailSubject);
        mailMessage.set_Body(_mailBody);

        //Add attachment if any
        for (i = 1; i <= conLen(_attachmentCon); i++)
        {
            attachmentPath = conPeek(_attachmentCon,i);
            if (attachmentPath != '' && WinAPI::fileExists(attachmentPath))
            {
                hasAttachment = true;
            }
        }

        if (hasAttachment)
        {
            for (i = 1; i <= conLen(_attachmentCon); i++)
            {
                attachmentPath = conPeek(_attachmentCon,i);

                //lan.nguyen - do not require permission
                //assert permision to make sure attach file is readable
                //filePermission = new FileIOPermission(attachmentPath, 'r');
                //filePermission.assert();

                attach = new System.Net.Mail.Attachment(attachmentPath);
                //attach.set_Name(VtvUtil::getFileName(_fileToAttach) + VtvUtil::getFileType(_fileToAttach)); //name to display file as in email

                attachCollection = mailMessage.get_Attachments();
                attachCollection.Add(attach);

                //cnt get all attachment path
                attachmentPathEmail += attachmentPath + ';';
                //cnt -end
            }
        }

        // For SSL enabled mail servers. Ex: gmail, smtp.gmail.com
        smtpClient.set_EnableSsl(true);

        networkCredential = new System.Net.NetworkCredential(_userName, _password);
        smtpClient.set_UseDefaultCredentials(false);
        smtpClient.set_Credentials(networkCredential);

        smtpClient.Send(mailMessage);
        mailMessage.Dispose();

        //release asserted permission
        if (hasAttachment && filePermission)
        {
            CodeAccessPermission::revertAssert();
        }

        //cnt - if scancomparameters is setup -- write to email log
        if (scancomParameters.TrackSendEmailLog == Noyes::Yes)
        {
            ttsbegin;
            emailLog.clear();
            emailLog.Subject        = _mailSubject;
            emailLog.EmailBody      = _mailBody;
            emailLog.Recipients     = toAddresses_All;
            emailLog.AttachmentPath = attachmentPathEmail;
            emailLog.NoOfRecepients = noOfRecipient;
            emailLog.CCRecipients   = ccAddress_All;
            emailLog.BCRecipients   = bccAddress_All;
            emailLog.insert();
            ttscommit;
        }

        //cnt -end
    }
    catch(Exception::CLRError)
    {
        throw error(CLRInterop::getLastException().ToString());
    }
}