diff --git a/app/app.go b/app/app.go deleted file mode 100644 index 4879f7a..0000000 --- a/app/app.go +++ /dev/null @@ -1 +0,0 @@ -package app diff --git a/app/mail-config.go b/app/mail-config.go index fbe4f5a..26a4d31 100644 --- a/app/mail-config.go +++ b/app/mail-config.go @@ -1,21 +1,12 @@ package app import ( - "bytes" "fmt" - "log" "net/smtp" "os" "strconv" - "text/template" ) -const CONFIG_SMTP_HOST = "smtp.gmail.com" -const CONFIG_SMTP_PORT = 587 -const CONFIG_SENDER_NAME = "HIS " -const CONFIG_AUTH_EMAIL = "hats.nutech@gmail.com" -const CONFIG_AUTH_PASSWORD = "lbfjfuywqktkexij" - type MailConfig struct { SMTPHost string SMTPPort int @@ -25,13 +16,6 @@ type MailConfig struct { } func Mail() *MailConfig { - // dialer := gomail.NewDialer( - // CONFIG_SMTP_HOST, - // CONFIG_SMTP_PORT, - // CONFIG_AUTH_EMAIL, - // CONFIG_AUTH_PASSWORD, - // ) - port, err := strconv.Atoi(os.Getenv("SMTP_PORT")) if err != nil { fmt.Println("error parsing to int", err.Error()) @@ -46,45 +30,17 @@ func Mail() *MailConfig { } } -func SendEmail(to []string, cc []string, subject, message string) error { - tmpl, err := template.ParseFiles("template/test.html") - if err != nil { - log.Fatalf("Error parsing template: %v", err) - } - - fmt.Println("qwqwqw", os.Getenv("PORT")) - - type Data struct { - Name string - Company string - } - - data := Data{Name: "Salwa Balqis Sulaeman", Company: "HIS"} - - var buf bytes.Buffer - if err := tmpl.Execute(&buf, data); err != nil { - log.Fatalf("Error executing template: %v", err) - } - - // content, err := os.ReadFile("template/test.html") - // if err != nil { - // fmt.Println("Error reading file:", err) - // return err - // } - - htmlString := buf.String() - +func SendEmail(to []string, cc []string, name, subject, message, htmlString string) error { sender := "From: " + Mail().SMTPSenderName + "\n" - subjectt := "Subject: 👋 Hello from Go\n" + subjectt := "Subject: " + subject + "\n" mime := "MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n" body := htmlString messages := []byte(sender + subjectt + mime + body) auth := smtp.PlainAuth("", Mail().AuthEmail, Mail().AuthPassword, Mail().SMTPHost) smtpAddr := fmt.Sprintf("%s:%d", Mail().SMTPHost, Mail().SMTPPort) - fmt.Println("cek dong", Mail()) - err = smtp.SendMail(smtpAddr, auth, Mail().AuthEmail, append(to, cc...), messages) + err := smtp.SendMail(smtpAddr, auth, Mail().AuthEmail, append(to, cc...), messages) if err != nil { return err } diff --git a/go.mod b/go.mod index 3da1f21..420ef36 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module email-notification go 1.21.1 require ( + github.com/google/uuid v1.6.0 github.com/joho/godotenv v1.5.1 gorm.io/driver/postgres v1.5.11 gorm.io/gorm v1.25.12 diff --git a/go.sum b/go.sum index ad9624e..0d139dd 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= diff --git a/helper/helper.go b/helper/helper.go new file mode 100644 index 0000000..69eb2b3 --- /dev/null +++ b/helper/helper.go @@ -0,0 +1,67 @@ +package helper + +import ( + "bytes" + "fmt" + "html/template" + "log" + "time" + + "github.com/google/uuid" +) + +func GenerateSessionID() string { + return uuid.New().String() +} + +func ParseHTML(filePath string, v any) string { + tmpl, err := template.ParseFiles(filePath) + if err != nil { + log.Fatalf("Error parsing template: %v", err) + } + + // type Data struct { + // Name string + // } + + // data := Data{Name: name} + + var buf bytes.Buffer + if err := tmpl.Execute(&buf, v); err != nil { + log.Fatalf("Error executing template: %v", err) + } + + return buf.String() +} + +func FormatSince(t time.Time) string { + now := time.Now() + dur := now.Sub(t) + + years := int(dur.Hours() / 24 / 365) + if years > 0 { + return fmt.Sprintf("%d", years) + } + + // months := int(dur.Hours() / 24 / 30) + // if months > 0 { + // return fmt.Sprintf("%d bulan yang lalu", months) + // } + + // days := int(dur.Hours() / 24) + // if days > 0 { + // return fmt.Sprintf("%d hari yang lalu", days) + // } + + // hours := int(dur.Hours()) + // if hours > 0 { + // return fmt.Sprintf("%d jam yang lalu", hours) + // } + + // minutes := int(dur.Minutes()) + // if minutes > 0 { + // return fmt.Sprintf("%d menit yang lalu", minutes) + // } + + return "baru saja" +} diff --git a/main.go b/main.go index ab1cbb1..cecc894 100644 --- a/main.go +++ b/main.go @@ -2,11 +2,9 @@ package main import ( "context" - "email-notification/app" "email-notification/config" - "email-notification/model" - "email-notification/query" - "fmt" + "email-notification/middleware" + "email-notification/route" "log" "net/http" "os" @@ -15,51 +13,19 @@ import ( ) func main() { - fmt.Println("Test") + log.Println("Email Notification Service") err := godotenv.Load() if err != nil { log.Fatal("Error loading .env file") } + http.Handle("/", middleware.ResponseTimeMiddleware(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("Welcome!")) + })) + db := config.NewDatabase().WithContext(context.Background()) - to := []string{"teddy.nutech@gmail.com"} - cc := []string{"teddy.nutech@gmail.com"} - subject := "test" - message := "test" - - fmt.Println(to, cc, subject, message) - - http.HandleFunc("/birthday-notification", func(w http.ResponseWriter, r *http.Request) { - - data := new([]model.Birthday) - - err := query.GetBirthday(db, data, "1", "1") - if err != nil { - w.WriteHeader(500) - w.Write([]byte(err.Error())) - } - - fmt.Println("hasil query data", data) - - for _, v := range *data { - fmt.Println("Birthday", v.Fullname) - sendTo := []string{v.Email} - go func() { - fmt.Println("sending email...") - err := app.SendEmail(sendTo, sendTo, subject, message) - if err != nil { - fmt.Println("error", err.Error()) - w.WriteHeader(500) - w.Write([]byte(err.Error())) - } else { - fmt.Println("email sent") - } - }() - } - - w.Write([]byte("success")) - }) + route.Route(db) port := os.Getenv("PORT") diff --git a/middleware/middleware.go b/middleware/middleware.go new file mode 100644 index 0000000..0cc65e0 --- /dev/null +++ b/middleware/middleware.go @@ -0,0 +1,17 @@ +package middleware + +import ( + "log" + "net/http" + "time" +) + +func ResponseTimeMiddleware(next http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + start := time.Now() + path := r.URL.Path + next(w, r) + duration := time.Since(start) + log.Printf("%+v response time %+v", path, duration) + } +} diff --git a/route/route.go b/route/route.go new file mode 100644 index 0000000..6e0b777 --- /dev/null +++ b/route/route.go @@ -0,0 +1,123 @@ +package route + +import ( + "email-notification/app" + "email-notification/helper" + "email-notification/middleware" + "email-notification/model" + "email-notification/query" + "fmt" + "log" + "net/http" + "time" + + "gorm.io/gorm" +) + +func Route(db *gorm.DB) { + http.HandleFunc("/birthday-notification", middleware.ResponseTimeMiddleware(func(w http.ResponseWriter, r *http.Request) { + sessionID := helper.GenerateSessionID() + module := "BIRTHDAY NOTIFICATION" + log.Printf("%+v %+v request %+v", sessionID, module, nil) + + data := new([]model.Birthday) + + month := int(time.Now().Month()) + day := time.Now().Day() + subject := "Happy Birthday 🎉🎂🥳" + + err := query.GetBirthday(db, data, fmt.Sprint(month), fmt.Sprint(day)) + if err != nil { + log.Fatalf("%+v %+v response %+v", sessionID, module, err.Error()) + w.WriteHeader(500) + w.Write([]byte(err.Error())) + } + + for _, v := range *data { + fmt.Println("Birthday", v.Fullname) + + sendTo := []string{v.Email} + + type Data struct { + Name string + } + + data := Data{Name: v.Fullname} + + htmlString := helper.ParseHTML("template/birthday.html", data) + + go func(v model.Birthday) { + log.Printf("%+v %+v SENDING EMAIL TO %+v", sessionID, module, v.Email) + err := app.SendEmail(sendTo, sendTo, "", subject, "", htmlString) + if err != nil { + log.Printf("%+v %+v response %+v", sessionID, module, err.Error()) + w.WriteHeader(500) + w.Write([]byte(err.Error())) + } else { + log.Fatalf("%+v %+v EMAIL SENT TO %+v", sessionID, module, v.Email) + } + }(v) + } + + log.Printf("%+v %+v response %+v", sessionID, module, "success") + w.Write([]byte("success")) + })) + + http.HandleFunc("/workanniversary-notification", middleware.ResponseTimeMiddleware(func(w http.ResponseWriter, r *http.Request) { + sessionID := helper.GenerateSessionID() + module := "WORKANNIVERSARY NOTIFICATION" + log.Printf("%+v %+v request %+v", sessionID, module, nil) + + data := new([]model.Workanniversary) + + month := int(time.Now().Month()) + day := time.Now().Day() + + err := query.GetWorkanniversary(db, data, fmt.Sprint(month), fmt.Sprint(day)) + if err != nil { + log.Fatalf("%+v %+v response %+v", sessionID, module, err.Error()) + w.WriteHeader(500) + w.Write([]byte(err.Error())) + } + + subject := "Work Anniversary 🎉" + + for _, v := range *data { + fmt.Println("Workanniversary", v.Fullname) + + sendTo := []string{v.Email} + + type Data struct { + Name string + Year string + } + + duration := helper.FormatSince(v.HireDate) + + fmt.Println("durasi", duration) + + data := Data{Name: v.Fullname, Year: duration} + + htmlString := helper.ParseHTML("template/workanniversary.html", data) + + go func(v model.Workanniversary) { + log.Printf("%+v %+v SENDING EMAIL TO %+v", sessionID, module, v.Email) + err := app.SendEmail(sendTo, sendTo, "", subject, "", htmlString) + if err != nil { + log.Printf("%+v %+v response %+v", sessionID, module, err.Error()) + w.WriteHeader(500) + w.Write([]byte(err.Error())) + } else { + log.Fatalf("%+v %+v EMAIL SENT TO %+v", sessionID, module, v.Email) + } + }(v) + } + + log.Printf("%+v %+v response %+v", sessionID, module, "success") + w.Write([]byte("success")) + })) + + http.HandleFunc("/test", middleware.ResponseTimeMiddleware(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("success")) + })) +} diff --git a/template/test.html b/template/birthday.html similarity index 96% rename from template/test.html rename to template/birthday.html index 77685cd..1eba20a 100644 --- a/template/test.html +++ b/template/birthday.html @@ -5,7 +5,7 @@ Selamat Ulang Tahun! + + +
+
+

🎉 Work Anniversary!

+
+
+ logo +

Hai {{.Name}},

+

+ Hari ini menandai tahun ke-{{.Year}} kamu di + perusahaan ini. Terima kasih atas dedikasi, semangat, dan kontribusimu + selama ini! +

+

+ Kami bangga memiliki kamu dalam tim teknologi kami. Mari terus + berkembang bersama — satu commit, satu deploy, satu milestone pada + satu waktu. 🚀 +

+
+ +
+ +