Daniel J. Summers adbbf9cf4e Update deps
- formatting changes
2024-06-27 07:36:24 -04:00

116 lines
3.8 KiB
Forth

/// Methods for sending e-mails
module PrayerTracker.Email
open MailKit.Net.Smtp
open Microsoft.Extensions.Localization
open MimeKit
open PrayerTracker.Entities
/// Parameters required to send an e-mail
type EmailOptions =
{ /// The SMTP client
Client: SmtpClient
/// The people who should receive the e-mail
Recipients: Member list
/// The small group for which this e-mail is being sent
Group: SmallGroup
/// The subject of the e-mail
Subject: string
/// The body of the e-mail in HTML
HtmlBody: string
/// The body of the e-mail in plain text
PlainTextBody: string
/// Use the current user's preferred language
Strings: IStringLocalizer }
/// Options to use when sending e-mail
type SmtpServerOptions() =
/// The hostname of the SMTP server
member val SmtpHost: string = "localhost" with get, set
/// The port over which SMTP communication should occur
member val Port: int = 25 with get, set
/// Whether to use SSL when communicating with the SMTP server
member val UseSsl: bool = false with get, set
/// The authentication to use with the SMTP server
member val Authentication: string = "" with get, set
/// The e-mail address from which messages should be sent
member val FromAddress: string = "prayer@bitbadger.solutions" with get, set
/// The options for the SMTP server
let smtpOptions = SmtpServerOptions()
/// Get an SMTP client connection
let getConnection () = task {
let client = new SmtpClient()
do! client.ConnectAsync(smtpOptions.SmtpHost, smtpOptions.Port, smtpOptions.UseSsl)
do! client.AuthenticateAsync(smtpOptions.FromAddress, smtpOptions.Authentication)
return client
}
/// Create a mail message object, filled with everything but the body content
let createMessage opts =
let msg = new MimeMessage()
msg.From.Add(MailboxAddress(opts.Group.Preferences.EmailFromName, smtpOptions.FromAddress))
msg.Subject <- opts.Subject
msg.ReplyTo.Add(MailboxAddress(opts.Group.Preferences.EmailFromName, opts.Group.Preferences.EmailFromAddress))
msg
open MimeKit.Text
/// Create an HTML-format e-mail message
let createHtmlMessage opts =
let bodyText =
[ """<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head><title></title></head><body>"""
opts.HtmlBody
"""<hr><div style="text-align:right;font-family:Arial,Helvetica,sans-serif;font-size:8pt;padding-right:10px;">"""
opts.Strings["Generated by P R A Y E R T R A C K E R"].Value
"<br><small>"
opts.Strings["from Bit Badger Solutions"].Value
"</small></div></body></html>" ]
|> String.concat ""
let msg = createMessage opts
msg.Body <- new TextPart(TextFormat.Html, Text = bodyText)
msg
/// Create a plain-text-format e-mail message
let createTextMessage opts =
let bodyText =
[ opts.PlainTextBody
"\n\n--\n"
opts.Strings["Generated by P R A Y E R T R A C K E R"].Value
"\n"
opts.Strings["from Bit Badger Solutions"].Value ]
|> String.concat ""
let msg = createMessage opts
msg.Body <- new TextPart(TextFormat.Plain, Text = bodyText)
msg
/// Send e-mails to a class
let sendEmails opts = task {
use htmlMsg = createHtmlMessage opts
use plainTextMsg = createTextMessage opts
for mbr in opts.Recipients do
let emailTo = MailboxAddress(mbr.Name, mbr.Email)
match defaultArg mbr.Format opts.Group.Preferences.DefaultEmailType with
| HtmlFormat ->
htmlMsg.To.Add emailTo
let! _ = opts.Client.SendAsync htmlMsg
htmlMsg.To.Clear()
| PlainTextFormat ->
plainTextMsg.To.Add emailTo
let! _ = opts.Client.SendAsync plainTextMsg
plainTextMsg.To.Clear()
}