Skip to content

Commit

Permalink
Merge pull request #9 from wneessen/v0.2.0_echo
Browse files Browse the repository at this point in the history
v0.2.0 - Complete refactor to use echo as underlying framework
  • Loading branch information
wneessen authored Sep 4, 2021
2 parents ac0377b + 3c4e96c commit 7982eeb
Show file tree
Hide file tree
Showing 27 changed files with 789 additions and 691 deletions.
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/js-mailer.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package api

import (
"github.com/ReneKroon/ttlcache/v2"
"github.com/wneessen/js-mailer/config"
)

// Route represents an API route object
type Route struct {
Cache *ttlcache.Cache
Config *config.Config
}
10 changes: 5 additions & 5 deletions apirequest/form.go → api/form.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package apirequest
package api

import (
"fmt"
Expand All @@ -8,20 +8,20 @@ import (

// GetForm gets a form.Form object either from the in-memory cache or if not cached
// yet, from the file system
func (a *ApiRequest) GetForm(i string) (form.Form, error) {
func (r *Route) GetForm(i string) (form.Form, error) {
var formObj form.Form
cacheForm, err := a.Cache.Get(fmt.Sprintf("formObj_%s", i))
cacheForm, err := r.Cache.Get(fmt.Sprintf("formObj_%s", i))
if err != nil && err != ttlcache.ErrNotFound {
return formObj, err
}
if cacheForm != nil {
formObj = cacheForm.(form.Form)
} else {
formObj, err = form.NewForm(a.Config, i)
formObj, err = form.NewForm(r.Config, i)
if err != nil {
return formObj, err
}
if err := a.Cache.Set(fmt.Sprintf("formObj_%s", formObj.Id), formObj); err != nil {
if err := r.Cache.Set(fmt.Sprintf("formObj_%s", formObj.Id), formObj); err != nil {
return formObj, err
}
}
Expand Down
24 changes: 24 additions & 0 deletions api/ping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package api

import (
"github.com/labstack/echo/v4"
"net/http"
)

// PingResponse reflects the JSON structure for a ping response
type PingResponse struct {
StatusCode int
Status string
Data interface{}
}

// Ping is a test route for the API
func (r *Route) Ping(c echo.Context) error {
return c.JSON(http.StatusOK, &PingResponse{
StatusCode: http.StatusOK,
Status: http.StatusText(http.StatusOK),
Data: map[string]string{
"Ping": "Pong",
},
})
}
84 changes: 84 additions & 0 deletions api/sendform.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package api

import (
"fmt"
"github.com/wneessen/js-mailer/response"
"net/http"
"time"

"github.com/go-mail/mail"
"github.com/labstack/echo/v4"
)

// SentSuccessfull represents confirmation JSON structure for a successfully sent message
type SentSuccessfull struct {
FormId string `json:"form_id"`
SendTime int64 `json:"send_time"`
}

// SendForm handles the HTTP form sending API request
func (r *Route) SendForm(c echo.Context) error {
sr := c.Get("formobj").(*SendFormRequest)
if sr == nil {
c.Logger().Errorf("no form object found in context")
return echo.NewHTTPError(http.StatusInternalServerError, "Internal Server Error")
}

// Compose the mail message
mailMsg := mail.NewMessage()
mailMsg.SetHeader("From", sr.FormObj.Sender)
mailMsg.SetHeader("To", sr.FormObj.Recipients...)
mailMsg.SetHeader("Subject", sr.FormObj.Content.Subject)

mailBody := "The following form fields have been transmitted:\n"
for _, k := range sr.FormObj.Content.Fields {
if v := c.FormValue(k); v != "" {
mailBody = fmt.Sprintf("%s\n* %s => %s", mailBody, k, v)
}
}
mailMsg.SetBody("text/plain", mailBody)

// Send the mail message
var serverTimeout time.Duration
var err error
serverTimeout, err = time.ParseDuration(sr.FormObj.Server.Timeout)
if err != nil {
c.Logger().Warnf("Could not parse configured server timeout: %s", err)
serverTimeout = time.Second * 5
}
mailDailer := mail.NewDialer(sr.FormObj.Server.Host, sr.FormObj.Server.Port, sr.FormObj.Server.Username,
sr.FormObj.Server.Password)
mailDailer.Timeout = serverTimeout
if sr.FormObj.Server.ForceTLS {
mailDailer.StartTLSPolicy = mail.MandatoryStartTLS
}
mailSender, err := mailDailer.Dial()
if err != nil {
c.Logger().Errorf("Could not connect to configured mail server: %s", err)
return echo.NewHTTPError(http.StatusInternalServerError, &response.ErrorObj{
Message: "could not connect to configured mail server",
Data: err.Error(),
})
}
defer func() {
if err := mailSender.Close(); err != nil {
c.Logger().Errorf("Failed to close mail server connection: %s", err)
}
}()
if err := mail.Send(mailSender, mailMsg); err != nil {
c.Logger().Errorf("Could not send mail message: %s", err)
return echo.NewHTTPError(http.StatusInternalServerError, &response.ErrorObj{
Message: "could not send mail message",
Data: err.Error(),
})
}

return c.JSON(http.StatusOK, response.SuccessResponse{
StatusCode: http.StatusOK,
Status: http.StatusText(http.StatusOK),
Data: &SentSuccessfull{
FormId: sr.FormObj.Id,
SendTime: time.Now().Unix(),
},
})
}
Loading

0 comments on commit 7982eeb

Please sign in to comment.