summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2022-02-28 02:14:27 +0700
committerShulhan <ms@kilabit.info>2022-02-28 14:39:41 +0700
commit1c0f0a63b6030f06708687ea4db6a07e36c6a767 (patch)
tree8a36a251d88a9da0473ba4a0db10ae78b32456d3
parentf8e4959352cd6653b8bdb10c445d06196406006a (diff)
downloadpakakeh.go-1c0f0a63b6030f06708687ea4db6a07e36c6a767.tar.xz
cmd/sendemail: command line interface to send an email
The sendemail command is proof of concept on how to use lib/email and lib/smtp to write and send email through SMTP.
-rw-r--r--cmd/sendemail/body.html1
-rw-r--r--cmd/sendemail/body.txt1
-rw-r--r--cmd/sendemail/main.go191
3 files changed, 193 insertions, 0 deletions
diff --git a/cmd/sendemail/body.html b/cmd/sendemail/body.html
new file mode 100644
index 00000000..107d9acf
--- /dev/null
+++ b/cmd/sendemail/body.html
@@ -0,0 +1 @@
+Hello, this is email body as <b>text/html</b>.
diff --git a/cmd/sendemail/body.txt b/cmd/sendemail/body.txt
new file mode 100644
index 00000000..a0bc3536
--- /dev/null
+++ b/cmd/sendemail/body.txt
@@ -0,0 +1 @@
+Hello, this is email body as text/plain.
diff --git a/cmd/sendemail/main.go b/cmd/sendemail/main.go
new file mode 100644
index 00000000..3289b7d0
--- /dev/null
+++ b/cmd/sendemail/main.go
@@ -0,0 +1,191 @@
+// Program sendemail is command line interface that use lib/email and lib/smtp
+// to send email.
+package main
+
+import (
+ "flag"
+ "fmt"
+ "log"
+ "os"
+
+ "github.com/shuLhan/share/lib/email"
+ "github.com/shuLhan/share/lib/smtp"
+)
+
+const (
+ envSmtpUsername = "SMTP_USERNAME"
+ envSmtpPassword = "SMTP_PASSWORD"
+)
+
+func main() {
+ var (
+ smtpc *smtp.Client
+ smtpRes *smtp.Response
+ mailtx *smtp.MailTx
+ clientOpts smtp.ClientOptions
+ msg email.Message
+ err error
+
+ from string
+ to string
+ subject string
+ fileBodyText string
+ fileBodyHtml string
+ serverUrl string
+
+ content []byte
+ mailb []byte
+
+ isHelp bool
+ )
+
+ log.SetFlags(0)
+ log.SetPrefix("sendemail: ")
+
+ flag.BoolVar(&isHelp, "help", false, "Print the command usage and flags.")
+ flag.StringVar(&from, "from", "", "Set the sender address.")
+ flag.StringVar(&to, "to", "", "Set the recipients.")
+ flag.StringVar(&subject, "subject", "", "Set the subject.")
+ flag.StringVar(&fileBodyText, "bodytext", "", "Set the text body from content of file.")
+ flag.StringVar(&fileBodyHtml, "bodyhtml", "", "Set the HTML body from content of file.")
+ flag.Usage = usage
+ flag.Parse()
+
+ if isHelp {
+ usage()
+ os.Exit(1)
+ }
+
+ serverUrl = flag.Arg(0)
+ if len(serverUrl) == 0 {
+ log.Printf("missing server URL")
+ os.Exit(1)
+ }
+
+ if len(from) == 0 {
+ log.Printf("missing -from flag")
+ os.Exit(1)
+ }
+ err = msg.SetFrom(from)
+ if err != nil {
+ log.Println(err)
+ os.Exit(1)
+ }
+
+ if len(to) == 0 {
+ log.Printf("missing -to flag")
+ os.Exit(1)
+ }
+ err = msg.SetTo(to)
+ if err != nil {
+ log.Println(err)
+ os.Exit(1)
+ }
+
+ if len(subject) == 0 {
+ log.Printf("missing -subject flag")
+ os.Exit(1)
+ }
+ msg.SetSubject(subject)
+
+ if len(fileBodyText) == 0 && len(fileBodyHtml) == 0 {
+ log.Printf("missing -bodytext or -bodyhtml")
+ os.Exit(1)
+ }
+
+ if len(fileBodyText) > 0 {
+ content, err = os.ReadFile(fileBodyText)
+ if err != nil {
+ log.Println(err)
+ }
+ _ = msg.SetBodyText(content)
+ }
+
+ if len(fileBodyHtml) > 0 {
+ content, err = os.ReadFile(fileBodyHtml)
+ if err != nil {
+ log.Println(err)
+ }
+ _ = msg.SetBodyHtml(content)
+ }
+
+ mailb, err = msg.Pack()
+ if err != nil {
+ log.Println(err)
+ os.Exit(1)
+ }
+
+ fmt.Printf("mail data:\n%s\n", mailb)
+
+ mailtx = smtp.NewMailTx(from, []string{to}, mailb)
+
+ clientOpts = smtp.ClientOptions{
+ ServerUrl: serverUrl,
+ AuthUser: os.Getenv(envSmtpUsername),
+ AuthPass: os.Getenv(envSmtpPassword),
+ AuthMechanism: smtp.SaslMechanismPlain,
+ }
+
+ smtpc, err = smtp.NewClient(clientOpts)
+ if err != nil {
+ log.Println(err)
+ os.Exit(1)
+ }
+
+ smtpRes, err = smtpc.MailTx(mailtx)
+ if err != nil {
+ log.Println(err)
+ os.Exit(1)
+ }
+
+ fmt.Printf("SMTP response: %+v\n", smtpRes)
+}
+
+func usage() {
+ fmt.Println(`
+sendemail - command line interface to send an email using SMTP.
+
+== SYNOPSIS
+
+ sendemail <FLAGS> <SERVER_URL>
+
+== FLAGS
+
+Unless otherwise noted, all of the flags below are required.`)
+
+ fmt.Println()
+ flag.PrintDefaults()
+
+ fmt.Println(`
+The 'from' and 'to' flags are set using mailbox format, for example
+"John <john@domain.tld>, Jane <jane@domain.tld>"
+
+Only one of 'bodytext' and 'bodyhtml' is required.
+
+== SERVER_URL
+
+The SERVER_URL argument define the SMTP server where the email will be submitted.
+Its use the following URL format,
+
+ <scheme://><ip_address / domain>[:port]
+
+The scheme can be 'smtps' for SMTP with implicit TLS (port 465) or
+'smtp+starttls' for SMTP with STARTTLS (port 587).
+
+The following environment variables are read for authentication with SMTP,
+
+* SMTP_USERNAME: for SMTP user
+* SMTP_PASSWORD: for SMTP password
+
+== EXAMPLES
+
+Send an email with message body set and read from HTML file,
+
+ $ SMTP_USERNAME=myuser
+ $ SMTP_PASSWORD=mypass
+ $ sendemail -from="my@email.tld" \
+ -to="John <john@example.com>, Jane <jane@example.com>" \
+ -subject="Happy new years!" \
+ -bodytext=/path/to/message.html \
+ smtps://mail.myserver.com`)
+}