mirror of
https://github.com/ivabus/pop
synced 2024-12-04 22:15:08 +03:00
feat: convert markdown to html
This commit is contained in:
parent
d6f2498dbd
commit
616601a34a
5 changed files with 78 additions and 7 deletions
22
email.go
22
email.go
|
@ -1,12 +1,17 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/resendlabs/resend-go"
|
||||
"github.com/yuin/goldmark"
|
||||
)
|
||||
|
||||
const TO_SEPARATOR = ","
|
||||
|
||||
// sendEmailSuccessMsg is the tea.Msg handled by Bubble Tea when the email has
|
||||
// been sent successfully.
|
||||
type sendEmailSuccessMsg struct{}
|
||||
|
@ -26,7 +31,7 @@ func (m Model) sendEmailCmd() tea.Cmd {
|
|||
}
|
||||
attachments[i] = string(at)
|
||||
}
|
||||
err := sendEmail(m.From.Value(), m.To.Value(), m.Subject.Value(), m.Body.Value(), attachments)
|
||||
err := sendEmail(strings.Split(m.To.Value(), TO_SEPARATOR), m.From.Value(), m.Subject.Value(), m.Body.Value(), attachments)
|
||||
if err != nil {
|
||||
return sendEmailFailureMsg(err)
|
||||
}
|
||||
|
@ -34,17 +39,24 @@ func (m Model) sendEmailCmd() tea.Cmd {
|
|||
}
|
||||
}
|
||||
|
||||
func sendEmail(from, to, subject, body string, attachments []string) error {
|
||||
func sendEmail(to []string, from, subject, body string, attachments []string) error {
|
||||
client := resend.NewClient(os.Getenv(RESEND_API_KEY))
|
||||
|
||||
var html, text = bytes.NewBufferString(""), bytes.NewBufferString("")
|
||||
err := goldmark.Convert([]byte(body), html)
|
||||
if err != nil {
|
||||
text.WriteString(body)
|
||||
}
|
||||
|
||||
request := &resend.SendEmailRequest{
|
||||
From: from,
|
||||
To: []string{to},
|
||||
To: to,
|
||||
Subject: subject,
|
||||
Html: body,
|
||||
Html: html.String(),
|
||||
Text: text.String(),
|
||||
}
|
||||
|
||||
_, err := client.Emails.Send(request)
|
||||
_, err = client.Emails.Send(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
1
go.mod
1
go.mod
|
@ -8,6 +8,7 @@ require (
|
|||
github.com/charmbracelet/lipgloss v0.7.1
|
||||
github.com/resendlabs/resend-go v1.6.0
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/yuin/goldmark v1.5.4
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
|
||||
)
|
||||
|
||||
|
|
2
go.sum
2
go.sum
|
@ -48,6 +48,8 @@ github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRM
|
|||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/yuin/goldmark v1.5.4 h1:2uY/xC0roWy8IBEGLgB1ywIoEJFGmRrX21YQcvGZzjU=
|
||||
github.com/yuin/goldmark v1.5.4/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
|
|
50
main.go
50
main.go
|
@ -2,20 +2,52 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/resendlabs/resend-go"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const RESEND_API_KEY = "RESEND_API_KEY"
|
||||
const RESEND_FROM = "RESEND_FROM"
|
||||
|
||||
var (
|
||||
from string
|
||||
to []string
|
||||
subject string
|
||||
body string
|
||||
attachments []string
|
||||
)
|
||||
|
||||
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 {
|
||||
p := tea.NewProgram(NewModel())
|
||||
if hasStdin() {
|
||||
b, err := io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
body = string(b)
|
||||
}
|
||||
|
||||
if len(to) > 0 && from != "" && subject != "" && body != "" {
|
||||
err := sendEmail(to, from, subject, body, attachments)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
p := tea.NewProgram(NewModel(resend.SendEmailRequest{
|
||||
From: from,
|
||||
To: to,
|
||||
Subject: subject,
|
||||
Text: body,
|
||||
}))
|
||||
_, err := p.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -24,6 +56,22 @@ var rootCmd = &cobra.Command{
|
|||
},
|
||||
}
|
||||
|
||||
// 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() {
|
||||
rootCmd.Flags().StringSliceVar(&to, "bcc", []string{}, "Blind carbon copy recipients")
|
||||
rootCmd.Flags().StringSliceVar(&to, "cc", []string{}, "Carbon copy recipients")
|
||||
rootCmd.Flags().StringSliceVarP(&attachments, "attach", "a", []string{}, "Email's attachments")
|
||||
rootCmd.Flags().StringSliceVarP(&to, "to", "t", []string{}, "Recipient emails")
|
||||
rootCmd.Flags().StringVarP(&body, "body", "b", "", "Email's body (markdown)")
|
||||
rootCmd.Flags().StringVarP(&from, "from", "f", os.Getenv(RESEND_FROM), "Email's sender ($RESEND_FROM)")
|
||||
rootCmd.Flags().StringVarP(&subject, "subject", "s", "", "Email's subject")
|
||||
}
|
||||
|
||||
func main() {
|
||||
key := os.Getenv(RESEND_API_KEY)
|
||||
if key == "" {
|
||||
|
|
10
model.go
10
model.go
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/charmbracelet/bubbles/textarea"
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/resendlabs/resend-go"
|
||||
"golang.org/x/exp/constraints"
|
||||
)
|
||||
|
||||
|
@ -54,7 +55,7 @@ type Model struct {
|
|||
err error
|
||||
}
|
||||
|
||||
func NewModel() Model {
|
||||
func NewModel(defaults resend.SendEmailRequest) Model {
|
||||
from := textinput.New()
|
||||
from.Prompt = "From "
|
||||
from.Placeholder = "me@example.com"
|
||||
|
@ -63,6 +64,7 @@ func NewModel() Model {
|
|||
from.TextStyle = activeTextStyle
|
||||
from.Cursor.Style = cursorStyle
|
||||
from.PlaceholderStyle = placeholderStyle
|
||||
from.SetValue(defaults.From)
|
||||
from.Focus()
|
||||
|
||||
to := textinput.New()
|
||||
|
@ -70,14 +72,18 @@ func NewModel() Model {
|
|||
to.PromptStyle = labelStyle.Copy()
|
||||
to.Cursor.Style = cursorStyle
|
||||
to.PlaceholderStyle = placeholderStyle
|
||||
to.TextStyle = textStyle
|
||||
to.Placeholder = "you@example.com"
|
||||
to.SetValue(strings.Join(defaults.To, TO_SEPARATOR))
|
||||
|
||||
subject := textinput.New()
|
||||
subject.Prompt = "Subject "
|
||||
subject.PromptStyle = labelStyle.Copy()
|
||||
subject.Cursor.Style = cursorStyle
|
||||
subject.PlaceholderStyle = placeholderStyle
|
||||
subject.TextStyle = textStyle
|
||||
subject.Placeholder = "Hello!"
|
||||
subject.SetValue(defaults.Subject)
|
||||
|
||||
body := textarea.New()
|
||||
body.Placeholder = "# Email"
|
||||
|
@ -91,6 +97,8 @@ func NewModel() Model {
|
|||
body.BlurredStyle.Text = textStyle
|
||||
body.BlurredStyle.Placeholder = placeholderStyle
|
||||
body.Cursor.Style = cursorStyle
|
||||
body.CharLimit = 4000
|
||||
body.SetValue(defaults.Text)
|
||||
body.Blur()
|
||||
|
||||
attachments := list.New([]list.Item{}, attachmentDelegate{}, 0, 3)
|
||||
|
|
Loading…
Reference in a new issue