Search code examples
c#.net-coresmtpgmail

Sending an email via Gmail SMTP using .NET Core


I am unable to send an email in .NET Core using Gmail's SMTP server.

My class:

public class Sender
{

    private Setting _setting;
    public Sender(Setting setting)
    {
        _setting = setting;
    }

    public void Send(string receiverAddress, string message) => Send(new MailAddress(receiverAddress), message);
    public void Send(MailAddress receiverAddress, string message)
    {
        using(MailMessage mail = new MailMessage())
        {
            MailAddress senderAddress = new MailAddress(_setting.SenderAddress);

            mail.From = senderAddress;
            mail.To.Add(receiverAddress);

            mail.Subject = "Integration Test";
            mail.SubjectEncoding = System.Text.Encoding.UTF8;
            mail.Body = "Hello, World!";
            mail.BodyEncoding = System.Text.Encoding.UTF8;

            using(SmtpClient smtpClient = new SmtpClient(_setting.SmtpServer, _setting.SmtpPort)){
                smtpClient.EnableSsl = true;
                smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
                // smtpClient.UseDefaultCredentials= false;
                smtpClient.Credentials = new NetworkCredential(_setting.SenderAddress, _setting.Password);
                smtpClient.Timeout = 20000;
                smtpClient.Send(mail);
            }
        }
    }
}

My Test

[Test]
  public void SendEmailGmail()
  {
      Setting setting = new Setting();
      setting.SmtpServer = "smtp.google.com";
      setting.SmtpPort = 587; // also tried 465
      setting.SenderAddress = "my@googlemail.com";
      setting.Username = "Display Name";
      setting.Password = "GoogleGeneratedAppPassword";

      Sender sender = new Sender(setting);

      sender.Send("i@dont.tell", "Hello, World!");

  }

When I execute the test, the test doesn't finish. It even exceeds the timeout of 20 seconds.


Solution

  • To make this code work with Gmail, install a postfix SMTP server locally and replay your test. Do not use Gmail SMTP directly.

    In postfix, set in /etc/postfix/main.cf:

    relayhost = [smtp.google.fr]
    

    And restart postfix:

    systemctl restart postfix
    

    In your google account, allow the public IP of your postfix server to login without credential on smtp.google.com for your gmail managed domain (your sender domain)

    Next, change your code to use the local IP of your Postfix server in replacement of smtp.google.fr

    setting.SmtpServer = "local.ip.address.of.your.postfix.server";
    setting.SmtpPort = 25;
    

    Postfix will have no troubles to deal with SMTP transactions, TLS, and whatever security google ask when connecting to smtp.google.fr