9

While trying to send an e-mail using MailKit and MimeKit,is there a way to collect the SMTP Output?.

ps: I am trying to migrate my email code from Easymail to Mimekit and Mailkit and I apologize if this is a rather basic query.

1 Answers1

15

There's actually a FAQ about this, but for convenience, I'll paste it here:

All of MailKit's client implementations have a constructor that takes a nifty IProtocolLogger interface for logging client/server communications. Out of the box, you can use the handy ProtocolLogger class. Here are some examples of how to use it:

// log to a file called 'smtp.log'
var client = new SmtpClient (new ProtocolLogger ("smtp.log"));

// log to standard output (i.e. the console)
var client = new SmtpClient (new ProtocolLogger (Console.OpenStandardOutput ()));
jstedfast
  • 35,744
  • 5
  • 97
  • 110
  • Thanks!. I am working on an application that sends mails to 1000 people.I will need to record every send with the result. I just need to know if it was sent or whether it failed with an exception code. Is there a simple way to just collect the SMTP server response codes synchronously?. I noticed that the method void Data (FormatOptions options, MimeMessage message, CancellationToken cancellationToken, ITransferProgress progress) does have an event being triggered OnMessageSent (new MessageSentEventArgs (message, response.Response));. Is there a way for me to collect that after each send?. – Krishnan Venkiteswaran Jun 25 '16 at 08:42
  • Yes. It's emitted after every message is sent. – jstedfast Jun 25 '16 at 10:26
  • @jstedfast using the new ProtocolLogger ("smtp.log") rewrites the LOG file everytime I run the program, how can I append the file ? so that the previous data is not deleted ? – Fuzed Mass Nov 06 '17 at 06:19
  • 1
    You could implement your own IProtocolLogger and use that, but the default ProtocolLogger class does not support that. – jstedfast Nov 06 '17 at 11:18
  • 1
    @jstedfast Used this approach to create a quick and dirty [implementation for log4Net](https://gist.github.com/lankymart/8867fb39c43ced877ec23333f339640d). – user692942 Sep 24 '19 at 11:18
  • Hi @jstedfast, is there a way to convert the log into a string without writing to a file? I tried grabbing the Stream to convert it to a string, but it looks like the Stream needs to open a file (and not be null) otherwise it throws an exception. `using( var client = new SmtpClient( new MailKit.ProtocolLogger( LogStream ) ) )` The idea here is to record the log to a database field as a string. Thanks. – Scho Feb 22 '23 at 04:10
  • You can use a MemoryStream instead of a filename. I would avoid trying to convert the stream data into a string, though, because the data is not guaranteed to all be the same charset. Just save it to the database as a binary blob. – jstedfast Feb 22 '23 at 14:40
  • @jstedfast When I use `// log to a file called 'smtp.log' var client = new SmtpClient (new ProtocolLogger ("smtp.log")); `. It throws an error on the next iteration saying file in use. Can't check the contents unless I stop the application. How to resolve this? – Zedverse07 Feb 22 '23 at 15:52
  • @KrishnanVenkiteswaran I am looking for the same solution where you can log all emails sent. Were you able to find it? logger that appends the logs in the same file. – Zedverse07 Feb 22 '23 at 15:54
  • @Zedverse07 @krishnan-venkiteswaran As of MailKit 3.x, the Send and SendAsync methods return a `string` that contains the SMTP server response to the DATA command. You can "parse" that to find the token you are looking for. – jstedfast Feb 24 '23 at 15:11