2023-06-13 23:31:19 -04:00
package main
import (
2023-06-15 09:45:14 -04:00
"fmt"
2023-06-15 10:30:20 -04:00
"io"
2023-06-13 23:31:19 -04:00
"os"
2023-06-15 10:59:25 -04:00
"strings"
2023-06-13 23:31:19 -04:00
tea "github.com/charmbracelet/bubbletea"
2023-06-15 10:30:20 -04:00
"github.com/resendlabs/resend-go"
2023-06-13 23:31:19 -04:00
"github.com/spf13/cobra"
)
2023-06-15 09:45:14 -04:00
const RESEND_API_KEY = "RESEND_API_KEY"
2023-07-11 10:21:28 -04:00
const POP_FROM = "POP_FROM"
const POP_SIGNATURE = "POP_SIGNATURE"
2023-06-15 10:30:20 -04:00
var (
from string
to [ ] string
subject string
body string
attachments [ ] string
2023-07-10 12:37:02 -04:00
preview bool
2023-07-11 10:21:28 -04:00
signature string
2023-06-15 10:30:20 -04:00
)
2023-06-15 09:45:14 -04:00
2023-06-13 23:31:19 -04:00
var rootCmd = & cobra . Command {
Use : "email" ,
Short : "email is a command line interface for sending emails." ,
Long : ` email is a command line interface for sending emails. ` ,
RunE : func ( cmd * cobra . Command , args [ ] string ) error {
2023-06-15 15:17:22 -04:00
if os . Getenv ( RESEND_API_KEY ) == "" {
fmt . Printf ( "\n %s %s %s\n\n" , errorHeaderStyle . String ( ) , inlineCodeStyle . Render ( RESEND_API_KEY ) , "environment variable is required." )
2023-06-20 10:21:01 -04:00
fmt . Printf ( " %s %s\n\n" , commentStyle . Render ( "You can grab one at" ) , linkStyle . Render ( "https://resend.com/api-keys" ) )
2023-06-15 15:17:22 -04:00
os . Exit ( 1 )
}
2023-06-15 10:30:20 -04:00
if hasStdin ( ) {
b , err := io . ReadAll ( os . Stdin )
if err != nil {
return err
}
body = string ( b )
}
2023-07-11 10:21:28 -04:00
if signature != "" {
body += "\n\n" + signature
}
2023-07-10 12:37:02 -04:00
if len ( to ) > 0 && from != "" && subject != "" && body != "" && ! preview {
2023-06-15 10:30:20 -04:00
err := sendEmail ( to , from , subject , body , attachments )
if err != nil {
2023-06-15 10:52:27 -04:00
cmd . SilenceUsage = true
cmd . SilenceErrors = true
fmt . Println ( errorStyle . Render ( err . Error ( ) ) )
2023-06-15 10:30:20 -04:00
return err
}
2023-06-15 11:03:14 -04:00
fmt . Print ( emailSummary ( to , subject ) )
2023-06-15 10:30:20 -04:00
return nil
}
p := tea . NewProgram ( NewModel ( resend . SendEmailRequest {
2023-06-27 14:34:28 -04:00
From : from ,
To : to ,
Subject : subject ,
Text : body ,
Attachments : makeAttachments ( attachments ) ,
2023-06-15 10:30:20 -04:00
} ) )
2023-06-15 10:59:25 -04:00
m , err := p . Run ( )
2023-06-13 23:31:19 -04:00
if err != nil {
return err
}
2023-06-15 10:59:25 -04:00
mm := m . ( Model )
2023-06-15 11:04:38 -04:00
if ! mm . abort {
fmt . Print ( emailSummary ( strings . Split ( mm . To . Value ( ) , TO_SEPARATOR ) , mm . Subject . Value ( ) ) )
}
2023-06-13 23:31:19 -04:00
return nil
} ,
}
2023-06-15 10:30:20 -04:00
// hasStdin returns whether there is data in stdin.
func hasStdin ( ) bool {
stat , err := os . Stdin . Stat ( )
return err == nil && ( stat . Mode ( ) & os . ModeCharDevice ) == 0
}
func init ( ) {
2023-06-15 11:27:20 -04:00
rootCmd . Flags ( ) . StringSliceVar ( & to , "bcc" , [ ] string { } , "BCC recipients" )
rootCmd . Flags ( ) . StringSliceVar ( & to , "cc" , [ ] string { } , "CC recipients" )
2023-06-15 10:30:20 -04:00
rootCmd . Flags ( ) . StringSliceVarP ( & attachments , "attach" , "a" , [ ] string { } , "Email's attachments" )
2023-06-15 11:27:20 -04:00
rootCmd . Flags ( ) . StringSliceVarP ( & to , "to" , "t" , [ ] string { } , "Recipients" )
rootCmd . Flags ( ) . StringVarP ( & body , "body" , "b" , "" , "Email's contents" )
2023-07-11 10:21:28 -04:00
envFrom := os . Getenv ( POP_FROM )
rootCmd . Flags ( ) . StringVarP ( & from , "from" , "f" , envFrom , "Email's sender " + commentStyle . Render ( "($" + POP_FROM + ")" ) )
2023-06-15 10:30:20 -04:00
rootCmd . Flags ( ) . StringVarP ( & subject , "subject" , "s" , "" , "Email's subject" )
2023-07-10 12:37:02 -04:00
rootCmd . Flags ( ) . BoolVarP ( & preview , "preview" , "p" , false , "Whether to preview the email before sending" )
2023-07-11 10:21:28 -04:00
envSignature := os . Getenv ( "POP_SIGNATURE" )
rootCmd . Flags ( ) . StringVarP ( & signature , "signature" , "x" , envSignature , "Signature to display at the end of the email. " + commentStyle . Render ( "($" + POP_SIGNATURE + ")" ) )
2023-06-15 10:30:20 -04:00
}
2023-06-13 23:31:19 -04:00
func main ( ) {
err := rootCmd . Execute ( )
if err != nil {
os . Exit ( 1 )
}
}