Email sending/queue api now works nicer.

master
Zed A. Shaw 4 weeks ago
parent 94e0970fd3
commit 5c07583ba4
  1. 100
      common/email/api.go
  2. 35
      common/email/data.go
  3. 7
      data/models.go
  4. 4
      features/email/api.go
  5. 1
      static/style.css
  6. 67
      tools/cmd/mailer/main.go
  7. 34
      tools/cmd/qmgr/main.go
  8. 3
      views/email/index.html

@ -0,0 +1,100 @@
package common_email
import (
"github.com/wneessen/go-mail"
"encoding/json"
"context"
"github.com/redis/go-redis/v9"
)
func NewSender(ctx context.Context, config Config) (Sender){
client := redis.NewClient(&redis.Options{
Addr: config.RedisHostPort,
Password: config.RedisPassword,
DB: config.RedisDB,
})
return Sender{client, ctx}
}
func NewRouter(ctx context.Context, config Config) (Router, error) {
var router Router
var err error
router.ctx = ctx
router.redis_client = redis.NewClient(&redis.Options{
Addr: config.RedisHostPort,
Password: config.RedisPassword,
DB: config.RedisDB,
})
router.smtp_client, err = mail.NewClient(config.SMTPHost,
mail.WithPort(config.SMTPPort),
mail.WithTLSPolicy(mail.NoTLS))
return router, err
}
func (router *Router) Close() {
router.redis_client.Close()
router.smtp_client.Close()
}
func (sender *Sender) Close() {
sender.redis_client.Close()
}
func (router *Router) DeliverEmail(msg EmailMessage) error {
email_msg := mail.NewMsg()
err := email_msg.From(msg.From)
if err != nil { return err }
err = email_msg.To(msg.To)
if err != nil { return err }
email_msg.Subject(msg.Subject)
email_msg.SetBodyString(mail.TypeTextPlain, msg.Text)
email_msg.SetBodyString(mail.TypeTextHTML, msg.HTML)
if err != nil { return err }
err = router.smtp_client.DialAndSendWithContext(router.ctx, email_msg)
if err != nil { return err }
return nil
}
func (router *Router) ReceiveEmail() (EmailMessage, error) {
var msg EmailMessage
result, err := router.redis_client.BRPop(router.ctx, 0, "queue").Result()
if err != nil { return msg, err }
// NOTE: 0=queue name, 1=message
err = json.Unmarshal([]byte(result[1]), &msg)
if err != nil { return msg, err }
return msg, nil
}
func (router *Router) HandleEmailRequest() error {
msg, err := router.ReceiveEmail()
if err != nil { return err }
err = router.DeliverEmail(msg)
if err != nil { return err }
return nil
}
func (sender *Sender) QueueEmail(msg EmailMessage) error {
msg_json, err := json.Marshal(msg)
if err != nil { return err }
_, err = sender.redis_client.LPush(sender.ctx, "queue", string(msg_json)).Result()
if err != nil { return err }
return nil
}

@ -0,0 +1,35 @@
package common_email
import (
"github.com/redis/go-redis/v9"
"github.com/wneessen/go-mail"
"context"
)
type Config struct {
RedisHostPort string
RedisPassword string
RedisDB int
SMTPHost string
SMTPPort int
}
type EmailMessage struct {
To string
From string
Subject string
Text string
HTML string
}
type Sender struct {
redis_client *redis.Client
ctx context.Context
}
type Router struct {
redis_client *redis.Client
smtp_client *mail.Client
ctx context.Context
}

@ -32,11 +32,4 @@ func Models() map[string]reflect.Type {
}
}
type EmailMessage struct {
To string
From string
Subject string
Text string
HTML string
}

@ -5,11 +5,11 @@ import (
)
func GetApiExample(c *fiber.Ctx) error {
tables := []string{"test", "that"}
tables := []string{"To", "From"}
return c.JSON(tables)
}
func SetupApi(app *fiber.App) {
app.Get("/api/email/example", GetApiExample)
app.Get("/api/email/send", GetApiExample)
}

@ -11,7 +11,6 @@
--color-red-300: oklch(80.8% 0.114 19.571);
--color-red-500: oklch(63.7% 0.237 25.331);
--color-red-800: oklch(44.4% 0.177 26.899);
--color-red-900: oklch(39.6% 0.141 25.723);
--color-orange-500: oklch(70.5% 0.213 47.604);
--color-yellow-300: oklch(90.5% 0.182 98.111);
--color-green-400: oklch(79.2% 0.209 151.711);

@ -1,75 +1,36 @@
package main
import (
"github.com/wneessen/go-mail"
"fmt"
"context"
"github.com/redis/go-redis/v9"
"time"
"encoding/json"
"MY/webapp/data"
"fmt"
email "MY/webapp/common/email"
)
func SendEmail(msg data.EmailMessage) {
email_msg := mail.NewMsg()
err := email_msg.From(msg.From)
if err != nil { panic(err) }
err = email_msg.To(msg.To)
if err != nil { panic(err) }
email_msg.Subject(msg.Subject)
email_msg.SetBodyString(mail.TypeTextPlain, msg.Text)
email_msg.SetBodyString(mail.TypeTextHTML, msg.HTML)
client, err := mail.NewClient("localhost",
mail.WithPort(1025),
mail.WithTLSPolicy(mail.NoTLS))
if err != nil { panic(err) }
err = client.DialAndSend(email_msg)
if err != nil { panic(err) }
}
func LoadMessage(result string) data.EmailMessage {
var msg data.EmailMessage
func EmailReceiver(ctx context.Context) {
router, err := email.NewRouter(ctx, email.Config{
RedisHostPort: "127.0.0.1:6379",
SMTPHost: "localhost",
SMTPPort: 1025,
})
err := json.Unmarshal([]byte(result), &msg)
if err != nil { panic(err) }
return msg
}
func EmailListener(ctx context.Context) {
client := redis.NewClient(&redis.Options{
Addr: "127.0.0.1:6379",
Password: "",
DB: 0,
})
defer router.Close()
for {
result, err := client.BRPop(ctx, 0, "queue").Result()
err := router.HandleEmailRequest()
if err != nil { panic(err) }
fmt.Printf("received: %v\n", result)
// NOTE: 0=queue name, 1=message
msg := LoadMessage(result[1])
SendEmail(msg)
fmt.Println("SENT EMAIL")
if err != nil {
fmt.Println(err)
}
}
}
func main() {
ctx := context.Background()
go EmailListener(ctx)
go EmailReceiver(ctx)
time.Sleep(time.Second * 100)
}

@ -1,39 +1,27 @@
package main
import (
"context"
"github.com/redis/go-redis/v9"
"encoding/json"
email "MY/webapp/common/email"
"fmt"
"MY/webapp/data"
"context"
)
func producer(ctx context.Context) {
client := redis.NewClient(&redis.Options{
Addr: "127.0.0.1:6379",
Password: "",
DB: 0,
})
_, err := client.Ping(ctx).Result()
if err != nil { panic(err) }
func main() {
ctx := context.Background()
msg := data.EmailMessage{
msg := email.EmailMessage{
To: "tina.recip@example.com",
From: "toni.sender@example.com",
Subject: "This is my first mail.",
Subject: "This is my first mail.",
Text: fmt.Sprintf("Random number %v", 200),
HTML: fmt.Sprintf("<h1>Random number %v</h1>", 200),
}
msg_json, err := json.Marshal(msg)
if err != nil { panic(err) }
sender := email.NewSender(ctx, email.Config{
RedisHostPort: "127.0.0.1:6379",
})
defer sender.Close()
_, err = client.LPush(ctx, "queue", string(msg_json)).Result()
err := sender.QueueEmail(msg)
if err != nil { panic(err) }
}
func main() {
ctx := context.Background()
producer(ctx)
}

@ -0,0 +1,3 @@
<h1>email</h1>
<p>Replace me.</p>
Loading…
Cancel
Save