1

I want to get the delivery notification after sending a mail whether is was success or failure, on google I got to know about DeliveryNotificationOptions, but when i tried to create one poc to check this I am not getting proper answer.

 class Program
    {
        static string smtpAddress = "smtp.gmail.com";
        static int portNumber = 587;
        static bool enableSSL = true;
        static string emailFromAddress = "MyId@gmail.com"; //Sender Email Address  
        static string password = "password"; //Sender Password  
        static string emailToAddress = "SomeEmailToTest@gmail.com"; //Receiver Email Address  
        static string subject = "Hello";
        static string body = "Hello, This is Email sending test using gmail.";
        static void Main(string[] args)
        {
            SendEmail();
        }
        public static void SendEmail()
        {
            using (MailMessage mail = new MailMessage())
            {
                mail.From = new MailAddress(emailFromAddress);
                mail.To.Add(emailToAddress);
                mail.Subject = subject;
                mail.Body = body;
                mail.IsBodyHtml = true;
                //mail.Attachments.Add(new Attachment("D:\\TestFile.txt"));//--Uncomment this to send any attachment  
                using (SmtpClient smtp = new SmtpClient(smtpAddress, portNumber))
                {
                    smtp.Credentials = new NetworkCredential(emailFromAddress, password);
                    smtp.EnableSsl = enableSSL;

                    mail.Headers.Add("Disposition-Notification-To", emailToAddress);

                    mail.DeliveryNotificationOptions = DeliveryNotificationOptions.OnSuccess;
                    smtp.Send(mail);
                  
                }
            }
        }
    }

On output I am getting success even though the from email is wrong. Can someone please help me to explain how can I achieve this scenario.

Thanks, Shreya

  • `Console.WriteLine(mail.DeliveryNotificationOptions);` - what do you think this line does? You only output what you _specified_. Not any result of the send operation nor delivery notification. – Fildor Jan 27 '21 at 09:03
  • @Fildor, no i am aware of the WriteLine functionality , i wrote it there just to explain that i am getting success as an output there even the mail is some random mail. If you can help me out to fetch the delivery recipient (success/Failure) that would be great. – Shreya Singh Jan 27 '21 at 09:22
  • _"even the mail is some random mail"_ - that's irrelevant. You gave it a recipe to cook by, then you ask to tell you what's on the recipe. That has nothing to do with whether it used a pot instead of a wok. – Fildor Jan 27 '21 at 09:40
  • You are doing `mail.DeliveryNotificationOptions = DeliveryNotificationOptions.OnSuccess` so when you do `Console.WriteLine(mail.DeliveryNotificationOptions)` you get the same value back. It is not the other value you are getting after email sent from the SMTP. So this does not indicate anything of what happened to the email. There is no way you can verify that the emailid is wrong or not. You can use try...catch block to handle exception thrown from client.Send method. https://learn.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient.send?view=net-5.0 – Chetan Jan 27 '21 at 09:50
  • @ChetanRanpariya , how can i receive that notification ? whether mail send was success or failure ? – Shreya Singh Jan 27 '21 at 09:51
  • @Fildor, So what should i do to know whether the recipe is properly cooked or not :P . please help i am a lil confused here – Shreya Singh Jan 27 '21 at 09:53
  • https://learn.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient.send?view=net-5.0 – Chetan Jan 27 '21 at 09:54
  • Chetan linked already some stuff. There are two steps here: 1. Check if the email has been _sent_ successfully. You can do that by checking for exceptions and / or registering to an event. _But_ that doesn't say it has also been received. So, that's probably why you set this option in the first place. Keep in mind, that the receiving mail server has to "play along". That means: _if_ you receive a success notification, you can be sure it has been received. But if _not_ it _does not mean it **it has not been received**_. – Fildor Jan 27 '21 at 10:00
  • It practically not possible to determine if the email was sent successfully or not. `client.Send` will send the mail to SMTP server. It will throw and error if it encounters any issue in that. Once it is handed over to SMTP server, it can not be controlled. `DeliveryNotificationOptions` can be used to get notification in the sender's email inbox about the email's delivery. – Chetan Jan 27 '21 at 10:00
  • And then again: It having been received doesn't imply it has been seen, read, ... it could as well rot in an inbox forever. – Fildor Jan 27 '21 at 10:03
  • @Fildor So can i check whether mail is valid or not before sending it ? is that possible ? or can i check whether the mail has been bounced ? one more thing i work in a company which is very secure oriented so on STG/ DEV I don't have any smtp architecture to check anything. – Shreya Singh Jan 27 '21 at 10:12
  • @Fildor , I found this https://www.c-sharpcorner.com/UploadFile/kirtan007/check-if-email-address-really-exist-or-not-using-C-Sharp/ this one is working fine for Gmail smtp server on my personal machine, but I am not sure this will work with companies SMTP server in my organization's intranet – Shreya Singh Jan 27 '21 at 10:17

2 Answers2

0

So i didn't found the answer for this particular scenario but found some different workarounds

 class Program
    {
        static string smtpAddress = "smtp.gmail.com";
    static int portNumber = 587;
    static bool enableSSL = true;
    static string emailFromAddress = "MyId@gmail.com"; //Sender Email Address  
    static string password = "password"; //Sender Password  
    static string emailToAddress = "SomeEmailToTest@gmail.com"; //Receiver Email Address  
    static string subject = "Hello";
    static string body = "Hello, This is Email sending test using gmail.";
        static void Main(string[] args)
        {
            testValidEmail();
        }
 public static void testValidEmail()
        {
            TcpClient tClient = new TcpClient("gmail-smtp-in.l.google.com", 25);
            string CRLF = "\r\n";
            byte[] dataBuffer;
            string ResponseString;
            NetworkStream netStream = tClient.GetStream();
            StreamReader reader = new StreamReader(netStream);
            ResponseString = reader.ReadLine();
            /* Perform HELO to SMTP Server and get Response */
            dataBuffer = BytesFromString("HELO Shreya" + CRLF);
            netStream.Write(dataBuffer, 0, dataBuffer.Length);
            ResponseString = reader.ReadLine();
            dataBuffer = BytesFromString("MAIL FROM:<MyEmailID>" + CRLF);
            netStream.Write(dataBuffer, 0, dataBuffer.Length);
            ResponseString = reader.ReadLine();
            /* Read Response of the RCPT TO Message to know from google if it exist or not */
            dataBuffer = BytesFromString("RCPT TO:<" + "TESTEmailID" + ">" + CRLF);
            netStream.Write(dataBuffer, 0, dataBuffer.Length);
            ResponseString = reader.ReadLine();
            if (GetResponseCode(ResponseString) == 550)
            {
                Console.Write("Mai Address Does not Exist !<br/><br/>");
                Console.Write("<B><font color='red'>Original Error from Smtp Server :</font></b>" + ResponseString);
            }
            /* QUITE CONNECTION */
            dataBuffer = BytesFromString("QUITE" + CRLF);
            netStream.Write(dataBuffer, 0, dataBuffer.Length);
            tClient.Close();
        }
        private static  byte[] BytesFromString(string str)
        {
            return Encoding.ASCII.GetBytes(str);
        }

        public static  int GetResponseCode(string ResponseString)
        {
            return int.Parse(ResponseString.Substring(0, 3));
        }
       }
}
0

I also found different workaround using ASPNETMX , you can find Licence-key, Code example and Dll on that site

class Program
    {
        static string smtpAddress = "smtp.gmail.com";
        static int portNumber = 587;
        static bool enableSSL = true;
        static string emailFromAddress = "MYID"; //Sender Email Address  
        static string password = "password"; //Sender Password  
        static string emailToAddress = "RecieverID"; //Receiver Email Address  
        static string subject = "Hello";
        static string body = "Hello, This is Email sending test using gmail.";
         static void Main(string[] args)
        {
            SendEmail();
        }
public static void SendEmail()
        {
            using (MailMessage mail = new MailMessage())
            {
                mail.From = new MailAddress(emailFromAddress);
                mail.To.Add(emailToAddress);
                mail.Subject = subject;
                mail.Body = body;
                mail.IsBodyHtml = true;
                //mail.Attachments.Add(new Attachment("D:\\TestFile.txt"));//--Uncomment this to send any attachment  
                using (SmtpClient smtp = new SmtpClient(smtpAddress, portNumber))
                {
                    smtp.Credentials = new NetworkCredential(emailFromAddress, password);
                    smtp.EnableSsl = enableSSL;

                    mail.Headers.Add("Disposition-Notification-To", emailToAddress);

                    mail.DeliveryNotificationOptions = DeliveryNotificationOptions.OnSuccess;
                    try {
                     
                        MXValidate.LoadLicenseKey("aaa-bbb-ccc");
                        aspNetMX.MXValidate mx = new aspNetMX.MXValidate();

                        // your server infos
                        mx.SMTPHello = "smtp.gmail.com";
                        mx.SMTPFrom = emailFromAddress;
                        mx.LogInMemory = true;

                        mx.RecurseMailDomains = true;

                        MXValidateLevel level = mx.Validate("randomtest@gmail.com");


                        //aspNetMX.MXValidateLevel level = mx.Validate("valiemailToTest@gmail.com", aspNetMX.MXValidateLevel.Mailbox);

                        if (level == aspNetMX.MXValidateLevel.Mailbox)
                        {
                            // Valid email address.
                        }
                        else
                        {
                            // NOT valid email address.
                        }
                        smtp.Send(mail);
                    
                    }
                    catch (SmtpFailedRecipientsException ex) {
                        for (int i = 0; i < ex.InnerExceptions.Length; i++)
                        {
                            SmtpStatusCode status = ex.InnerExceptions[i].StatusCode;
                            if (status == SmtpStatusCode.MailboxBusy ||
                                status == SmtpStatusCode.MailboxUnavailable)
                            {
                                Console.WriteLine("Delivery failed - retrying in 5 seconds.");
                                System.Threading.Thread.Sleep(5000);
                                smtp.Send(mail);
                            }
                            else
                            {
                                Console.WriteLine("Failed to deliver message to {0}",
                                    ex.InnerExceptions[i].FailedRecipient);
                            }
                        }
                    }
                    catch (SmtpException e)
                    {
                        Console.WriteLine("Error: {0}", e.StatusCode);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Exception caught in RetryIfBusy(): {0}",
                                ex.ToString());
                    }
                    Console.WriteLine(mail.DeliveryNotificationOptions);
                }
            }
        }
   }

}