Monday, October 26, 2020

Sending Email from VFP Applications: Supporting Newer SMTP Protocols

There are many libraries you can use to send emails from VFP applications. I created my own several years ago: a C# wrapper class using the .NET SMTPClient class, which I call using Rick Strahl's wwDotNetBridge. However, as discussed here, Microsoft no longer recommends using this class because it doesn't support modern protocols (which I can attest to, thanks to several support tickets from customers). As suggested in the article, I've rewritten my wrapper class to use the open source MailKit project.

Here's some code that shows how to use this wrapper class:

local loMail, ;
   llReturn
loMail = newobject('SFMail', 'SFMail.prg')
with loMail
   .cServer      = 'MyMailServer.com'
   .cUser        = 'MyUserName'
   .cPassword    = 'MyPassword'
   .nSMTPPort    = 25
   .cSenderEmail = .cUser
   .cSenderName  = 'My Name'
   .cRecipients  = 'someone@somewhere.com'
   .cSubject     = 'Test email'
   .cBody        = 'This is a test message. ' + ;
      '<strong>This is bold text</strong>. ' + ;
      '<font color="red">This is red text</font>'
   .cAttachments = 'koko.jpg'
   llReturn      = .SendMail()
   if llReturn
      messagebox('Message sent')
   else
      messagebox('Message not sent: ' + .cErrorMessage)
   endif llReturn
endwith

Here's what the received email looks like. Notice the attached image and the formatted text.

The class supports the following:

  • Text or HTML body: simply include HTML tags in the cBody property and SFMail automatically handles it
  • Attachments: cAttachments is a comma-separated list of file names
  • Normal, CC (the cCCRecipients property), and BCC recipients (the cBCCRecipients property): separate multiple email addresses with commas or semi-colons
  • SMTP or MAPI (using Craig Boyd's VFPExMAPI.fll): set lUseMAPI to .T. to use MAPI or .F. (the default) to use SMTP
  • Adjustable timeout (the nTimeout property, which is in seconds)
  • Adjustable security settings (the nSecurityOptions property; see the MailKit documentation for the values). I find the default setting of 1 (Auto) works best for most servers.
  • Diagnostic logging: set cLogFile to the name and pass of a log file; it will contain the dialog between MailKit and the mail server so you can debug any problems.

You can download SFMail and the supporting files from the Technical Papers page of my web site or directly from here.

6 comments:

Rick Schummer said...

What version of .NET has to be deployed/ensured on the user's computer?

Doug Hennig said...

It needs .NET 4.6 or later because it needs TLS 1.2 support.

Unknown said...

Doug! Thank you for this! I first heard of the issue back in July and couldn't find a way forward. Decided to leave it on the back burner, but now this will be a piece of cake. I owe you a beer at the very least the next time I see you!

F-Charles Waud said...

Thank you very much ... greatly appreciated!

F-Charles Waud said...

Doug, does this also solve the Google oauth changes we discussed several months ago?

Doug Hennig said...

I knew you were going to ask that 😁. No, I looked into the GMail API and while the MailKit library can help with it, it's a lot more involved than a simple SMTP call. It's still on my list of things to do.

Doug