Skip to content

Instantly share code, notes, and snippets.

@u007
Last active April 14, 2017 10:11
Show Gist options
  • Save u007/7cea82c4c4dc5e219661b8e5d9acf9bc to your computer and use it in GitHub Desktop.
Save u007/7cea82c4c4dc5e219661b8e5d9acf9bc to your computer and use it in GitHub Desktop.
go buffalo mailer
// actions/action_signup.go //in action handler file
import (
g "project/actions/shared"
"project/models"
"github.com/gobuffalo/buffalo"
// "github.com/pkg/errors"
// "fmt"
"project/actions/mailer/user"
)
func Signup(c buffalo.Context) error {
if err = user_mailer.Signup(c, user); err != nil {
g.App.Logger.Errorf("mailer failed: %v", err.Error())
//...render html of result
}
}
//actions/app.go
import(
//...
"project/actions/shared"
)
app = buffalo.Automatic(buffalo.Options{
Env: ENV,
Host: global.Config.AppFullHost,
SessionName: "_project_session",
})
global.SetApp(app)
//actions/mailer/base.go
package mailer
import (
g "projecy/actions/shared"
"bytes"
rice "github.com/GeertJohan/go.rice"
"github.com/aymerick/douceur/inliner"
"github.com/gobuffalo/buffalo"
"github.com/gobuffalo/buffalo/render"
"github.com/gobuffalo/buffalo/render/resolvers"
"github.com/gobuffalo/velvet"
"gopkg.in/gomail.v2"
"strings"
)
var MailConfig MailerConfig
var r *render.Engine
type MailerConfig struct {
From string
Cc string
Bcc string
Type string
Host string
Port int
Auth bool
Username string
Password string
}
func init() {
MailConfig = MailerConfig{
From: "[email protected]",
Cc: "[email protected]",
Type: "smtp", // or sendmail
Host: "smtp.mailgun.org",
Port: 2525,
Auth: true,
Username: "[email protected]",
Password: "password",
}
r = render.New(render.Options{
HTMLLayout: "mail.html",
TemplateEngine: velvet.BuffaloRenderer,
FileResolverFunc: func() resolvers.FileResolver {
return &resolvers.RiceBox{
Box: rice.MustFindBox("../../templates"),
}
},
Helpers: map[string]interface{}{},
})
}
func GetMailer() *gomail.Dialer {
if MailConfig.Type == "smtp" {
return gomail.NewDialer(MailConfig.Host, MailConfig.Port, MailConfig.Username, MailConfig.Password)
}
return nil
}
func GetMessage() *gomail.Message {
m := gomail.NewMessage()
m.SetHeader("From", MailConfig.From)
if MailConfig.Bcc != "" {
m.SetHeader("Bcc", MailConfig.Bcc)
}
if MailConfig.Cc != "" {
m.SetHeader("Cc", MailConfig.Cc)
}
return m
}
func SendMail(context buffalo.Context, to string, subject string, cc string, block func(*render.Engine, *gomail.Message) (render.Renderer, error)) error {
tos := strings.Split(to, ",")
m := GetMessage()
m.SetHeader("To", tos...)
if MailConfig.Cc != "" {
cc1 := strings.SplitN(MailConfig.Cc, " ", 2)
cc_name := ""
if len(cc1) > 1 {
cc_name = cc1[1]
}
m.SetAddressHeader("Cc", cc1[0], cc_name)
}
if cc != "" {
cc2 := strings.SplitN(cc, " ", 2)
cc_name := ""
if len(cc2) > 1 {
cc_name = cc2[1]
}
m.SetAddressHeader("Cc", cc2[0], cc_name)
}
}
func GetMessage() *gomail.Message {
m := gomail.NewMessage()
m.SetHeader("From", MailConfig.From)
if MailConfig.Bcc != "" {
m.SetHeader("Bcc", MailConfig.Bcc)
}
if MailConfig.Cc != "" {
m.SetHeader("Cc", MailConfig.Cc)
}
return m
}
func SendMail(context buffalo.Context, to string, subject string, cc string, block func(*render.Engine, *gomail.Message) (render.Renderer, error)) error {
tos := strings.Split(to, ",")
m := GetMessage()
m.SetHeader("To", tos...)
if MailConfig.Cc != "" {
cc1 := strings.SplitN(MailConfig.Cc, " ", 2)
cc_name := ""
if len(cc1) > 1 {
cc_name = cc1[1]
}
m.SetAddressHeader("Cc", cc1[0], cc_name)
}
if cc != "" {
cc2 := strings.SplitN(cc, " ", 2)
cc_name := ""
if len(cc2) > 1 {
cc_name = cc2[1]
}
m.SetAddressHeader("Cc", cc2[0], cc_name)
}
m.SetHeader("Subject", subject)
rr, err := block(r, m)
if err != nil {
context.Logger().Fatalf("SendMail: Block failed: %v", err.Error())
return err
}
data := context.Data()
// pp := map[string]string{}
// params := context.Params()
// for k, v := range params {
// pp[k] = v[0]
// }
// data["params"] = pp
// data["flash"] = context.Flash().data
bb := &bytes.Buffer{}
if err = rr.Render(bb, data); err != nil {
context.Logger().Fatalf("SendMail: Render failed: %v", err.Error())
return err
}
html, err := inliner.Inline(bb.String())
if err != nil {
context.Logger().Fatalf("SendMail: Inliner failed: %v", err.Error())
return err
}
m.SetBody("text/html", html)
if g.App.Env == "development" {
context.Logger().Infof("SendMail: body: %s", html)
}
// m.Attach("/home/Alex/lolcat.jpg")
if g.Config.SendEmail {
mailer := GetMailer()
if err := mailer.DialAndSend(m); err != nil {
if !g.Config.IgnoreMailError {
context.Logger().Errorf("SendMail: send failed: %v", err.Error())
return err
}
}
}
return nil
}
//actions/shared/global.go
package global
import (
"encoding/json"
"fmt"
"github.com/gobuffalo/buffalo"
"github.com/gobuffalo/envy"
"path"
"runtime"
"strconv"
"strings"
// "log"
)
var ENV = envy.Get("GO_ENV", "development")
var App *buffalo.App
var Config *AppGlobalConfig
var app_url *string
type AppGlobalConfig struct {
PageSize int
IgnoreMailError bool
SendEmail bool
RootPath string
AppName string
AppProtocol string
AppHost string
AppPort int
AppUri string
AppFullHost string
SessionDuration int //second
ResetTokenDuration int
DefaultLocale string
}
func init() {
Config = &AppGlobalConfig{
AppName: "Site name",
PageSize: 10,
IgnoreMailError: false,
AppHost: "127.0.0.1",
AppProtocol: "http",
AppPort: 3000,
AppUri: "/",
SendEmail: true,
DefaultLocale: "en-US",
SessionDuration: 60 * 60, //60mins
ResetTokenDuration: 30 * 60, //30mins
}
switch ENV {
case "production":
Config.AppHost = "example.com"
Config.AppPort = 80
case "staging":
Config.AppHost = "stg1.example.com"
Config.AppPort = 80
default:
Config.SendEmail = false
}
//Config.AppUri = "/"
url := "://"
if Config.AppProtocol == "ssl" {
url = "https" + url
} else {
url = "http" + url
}
url += Config.AppHost
if Config.AppPort != 80 && Config.AppPort != 443 {
url += ":" + strconv.Itoa(Config.AppPort)
}
Config.AppFullHost = url
url += Config.AppUri
app_url = &url
}
func AppUrl() string {
return *app_url
}
func SetApp(t_app *buffalo.App) {
App = t_app
Config.IgnoreMailError = App.Env != "production"
_, file, _, ok := runtime.Caller(0)
if !ok {
panic("No caller information")
}
dir := path.Dir(path.Dir(path.Dir(file)))
// log.Printf("Filename : %q, Dir : %q\n", filename, )
// dir, err := filepath.Abs(filepath.Dir(filepath.Dir(os.Args[0])))
// if err != nil {
// App.Logger.Panic(err.Error())
// }
Config.RootPath = dir
App.Logger.Infof("env: %s, root: %s", App.Env, dir)
if App.Env == "production" {
} else if App.Env == "staging" {
} else {
//development / testing
}
App.ErrorHandlers[404] = customErrorHandler()
}
//actions/mailer/user/signup.go
package user_mailer
import (
"project/actions/mailer"
"project/models"
"github.com/gobuffalo/buffalo"
"github.com/gobuffalo/buffalo/render"
"gopkg.in/gomail.v2"
)
// HomeHandler is a default handler to serve up
// a home page.
func Signup(c buffalo.Context, user models.User) error {
c.Set("user", user)
c.Set("user_name", user.Name())
return mailer.SendMail(c, *user.Email, "Welcome", "", func(r *render.Engine, m *gomail.Message) (render.Renderer, error) {
return r.HTML("mailer/user/signup.html"), nil
})
}
//templates/mailer/user/signup.html
<style>
.body {
border: 1px solid #ff000;
}
</style>
{{ partial "mailer/header.html"}}
<h1>Welcome {{user_name}}</h1>
<p class="body">
We have created an account for you to access to our web site at:
<br/>
<a href="{{_RootUrl}}">{{_RootUrl}}</a>
<br/>
Please sign in with your eMail as username, and password provided by system administrator.
</p>
{{ partial "mailer/footer.html"}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment