2014-10-22 16:20:45 +08:00
|
|
|
|
package service
|
|
|
|
|
|
|
|
|
|
import (
|
2016-10-29 16:38:13 +08:00
|
|
|
|
"crypto/tls"
|
|
|
|
|
"net"
|
2015-11-13 17:58:41 +08:00
|
|
|
|
"bytes"
|
|
|
|
|
"fmt"
|
2014-10-22 16:20:45 +08:00
|
|
|
|
"github.com/leanote/leanote/app/db"
|
2015-11-13 17:58:41 +08:00
|
|
|
|
"github.com/leanote/leanote/app/info"
|
2014-10-22 16:20:45 +08:00
|
|
|
|
. "github.com/leanote/leanote/app/lea"
|
|
|
|
|
"gopkg.in/mgo.v2/bson"
|
2015-11-13 17:58:41 +08:00
|
|
|
|
"html/template"
|
2014-10-22 16:20:45 +08:00
|
|
|
|
"net/smtp"
|
|
|
|
|
"strconv"
|
2015-11-13 17:58:41 +08:00
|
|
|
|
"strings"
|
|
|
|
|
"time"
|
2014-10-22 16:20:45 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 发送邮件
|
|
|
|
|
|
|
|
|
|
type EmailService struct {
|
|
|
|
|
tpls map[string]*template.Template
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-13 17:58:41 +08:00
|
|
|
|
func NewEmailService() *EmailService {
|
2014-10-22 16:20:45 +08:00
|
|
|
|
return &EmailService{tpls: map[string]*template.Template{}}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 发送邮件
|
|
|
|
|
var host = ""
|
|
|
|
|
var emailPort = ""
|
|
|
|
|
var username = ""
|
|
|
|
|
var password = ""
|
2016-10-29 16:38:13 +08:00
|
|
|
|
var ssl = false
|
2014-10-22 16:20:45 +08:00
|
|
|
|
|
|
|
|
|
func InitEmailFromDb() {
|
|
|
|
|
host = configService.GetGlobalStringConfig("emailHost")
|
|
|
|
|
emailPort = configService.GetGlobalStringConfig("emailPort")
|
|
|
|
|
username = configService.GetGlobalStringConfig("emailUsername")
|
|
|
|
|
password = configService.GetGlobalStringConfig("emailPassword")
|
2016-10-29 16:38:13 +08:00
|
|
|
|
if configService.GetGlobalStringConfig("emailSSL") == "1" {
|
|
|
|
|
ssl = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//return a smtp client
|
|
|
|
|
func dial(addr string) (*smtp.Client, error) {
|
|
|
|
|
conn, err := tls.Dial("tcp", addr, nil)
|
|
|
|
|
if err != nil {
|
|
|
|
|
LogW("Dialing Error:", err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
//分解主机端口字符串
|
|
|
|
|
host, _, _ := net.SplitHostPort(addr)
|
|
|
|
|
return smtp.NewClient(conn, host)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func SendEmailWithSSL (auth smtp.Auth, to []string, msg []byte) (err error) {
|
|
|
|
|
//create smtp client
|
|
|
|
|
c, err := dial(host + ":" + emailPort)
|
|
|
|
|
if err != nil {
|
|
|
|
|
LogW("Create smpt client error:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
defer c.Close()
|
|
|
|
|
|
|
|
|
|
if auth != nil {
|
|
|
|
|
if ok, _ := c.Extension("AUTH"); ok {
|
|
|
|
|
if err = c.Auth(auth); err != nil {
|
|
|
|
|
LogW("Error during AUTH", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err = c.Mail(username); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, addr := range to {
|
|
|
|
|
if err = c.Rcpt(addr); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
w, err := c.Data()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_, err = w.Write(msg)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = w.Close()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return c.Quit()
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (this *EmailService) SendEmail(to, subject, body string) (ok bool, e string) {
|
|
|
|
|
InitEmailFromDb()
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
if host == "" || emailPort == "" || username == "" || password == "" {
|
2015-11-13 17:58:41 +08:00
|
|
|
|
return
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
|
|
|
|
hp := strings.Split(host, ":")
|
|
|
|
|
auth := smtp.PlainAuth("", username, password, hp[0])
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
var content_type string
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
mailtype := "html"
|
|
|
|
|
if mailtype == "html" {
|
2015-11-13 17:58:41 +08:00
|
|
|
|
content_type = "Content-Type: text/" + mailtype + "; charset=UTF-8"
|
|
|
|
|
} else {
|
2014-10-22 16:20:45 +08:00
|
|
|
|
content_type = "Content-Type: text/plain" + "; charset=UTF-8"
|
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
|
|
|
|
msg := []byte("To: " + to + "\r\nFrom: " + username + "<" + username + ">\r\nSubject: " + subject + "\r\n" + content_type + "\r\n\r\n" + body)
|
2014-10-22 16:20:45 +08:00
|
|
|
|
send_to := strings.Split(to, ";")
|
2016-10-29 16:38:13 +08:00
|
|
|
|
|
|
|
|
|
var err error
|
|
|
|
|
if ssl {
|
|
|
|
|
err = SendEmailWithSSL(auth, send_to, msg)
|
|
|
|
|
} else {
|
|
|
|
|
Log("no ssl")
|
|
|
|
|
err = smtp.SendMail(host + ":" + emailPort, auth, username, send_to, msg)
|
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
e = fmt.Sprint(err)
|
2015-11-13 17:58:41 +08:00
|
|
|
|
return
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
|
|
|
|
ok = true
|
2015-11-13 17:58:41 +08:00
|
|
|
|
return
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AddUser调用
|
|
|
|
|
// 可以使用一个goroutine
|
|
|
|
|
func (this *EmailService) RegisterSendActiveEmail(userInfo info.User, email string) bool {
|
|
|
|
|
token := tokenService.NewToken(userInfo.UserId.Hex(), email, info.TokenActiveEmail)
|
|
|
|
|
if token == "" {
|
|
|
|
|
return false
|
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
|
|
|
|
subject := configService.GetGlobalStringConfig("emailTemplateRegisterSubject")
|
|
|
|
|
tpl := configService.GetGlobalStringConfig("emailTemplateRegister")
|
|
|
|
|
|
|
|
|
|
if tpl == "" {
|
2014-10-22 16:20:45 +08:00
|
|
|
|
return false
|
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-11-10 16:26:04 +08:00
|
|
|
|
tokenUrl := configService.GetSiteUrl() + "/user/activeEmail?token=" + token
|
2014-10-22 16:20:45 +08:00
|
|
|
|
// {siteUrl} {tokenUrl} {token} {tokenTimeout} {user.id} {user.email} {user.username}
|
2014-11-10 16:26:04 +08:00
|
|
|
|
token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(), "tokenUrl": tokenUrl, "token": token, "tokenTimeout": strconv.Itoa(int(tokenService.GetOverHours(info.TokenActiveEmail))),
|
2014-10-22 16:20:45 +08:00
|
|
|
|
"user": map[string]interface{}{
|
2015-11-13 17:58:41 +08:00
|
|
|
|
"userId": userInfo.UserId.Hex(),
|
|
|
|
|
"email": userInfo.Email,
|
2014-10-22 16:20:45 +08:00
|
|
|
|
"username": userInfo.Username,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var ok bool
|
|
|
|
|
ok, _, subject, tpl = this.renderEmail(subject, tpl, token2Value)
|
|
|
|
|
if !ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
// 发送邮件
|
|
|
|
|
ok, _ = this.SendEmail(email, subject, tpl)
|
|
|
|
|
return ok
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 修改邮箱
|
|
|
|
|
func (this *EmailService) UpdateEmailSendActiveEmail(userInfo info.User, email string) (ok bool, msg string) {
|
|
|
|
|
// 先验证该email是否被注册了
|
|
|
|
|
if userService.IsExistsUser(email) {
|
|
|
|
|
ok = false
|
|
|
|
|
msg = "该邮箱已注册"
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
token := tokenService.NewToken(userInfo.UserId.Hex(), email, info.TokenUpdateEmail)
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
if token == "" {
|
|
|
|
|
return
|
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
|
|
|
|
subject := configService.GetGlobalStringConfig("emailTemplateUpdateEmailSubject")
|
|
|
|
|
tpl := configService.GetGlobalStringConfig("emailTemplateUpdateEmail")
|
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
// 发送邮件
|
2014-11-10 16:26:04 +08:00
|
|
|
|
tokenUrl := configService.GetSiteUrl() + "/user/updateEmail?token=" + token
|
2014-10-22 16:20:45 +08:00
|
|
|
|
// {siteUrl} {tokenUrl} {token} {tokenTimeout} {user.userId} {user.email} {user.username}
|
2014-11-10 16:26:04 +08:00
|
|
|
|
token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(), "tokenUrl": tokenUrl, "token": token, "tokenTimeout": strconv.Itoa(int(tokenService.GetOverHours(info.TokenActiveEmail))),
|
2014-10-22 16:20:45 +08:00
|
|
|
|
"newEmail": email,
|
|
|
|
|
"user": map[string]interface{}{
|
2015-11-13 17:58:41 +08:00
|
|
|
|
"userId": userInfo.UserId.Hex(),
|
|
|
|
|
"email": userInfo.Email,
|
2014-10-22 16:20:45 +08:00
|
|
|
|
"username": userInfo.Username,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ok, msg, subject, tpl = this.renderEmail(subject, tpl, token2Value)
|
|
|
|
|
if !ok {
|
2015-11-13 17:58:41 +08:00
|
|
|
|
return
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
// 发送邮件
|
|
|
|
|
ok, msg = this.SendEmail(email, subject, tpl)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (this *EmailService) FindPwdSendEmail(token, email string) (ok bool, msg string) {
|
2015-11-13 17:58:41 +08:00
|
|
|
|
subject := configService.GetGlobalStringConfig("emailTemplateFindPasswordSubject")
|
|
|
|
|
tpl := configService.GetGlobalStringConfig("emailTemplateFindPassword")
|
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
// 发送邮件
|
2014-11-10 16:26:04 +08:00
|
|
|
|
tokenUrl := configService.GetSiteUrl() + "/findPassword/" + token
|
2014-10-22 16:20:45 +08:00
|
|
|
|
// {siteUrl} {tokenUrl} {token} {tokenTimeout} {user.id} {user.email} {user.username}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(), "tokenUrl": tokenUrl,
|
2014-10-22 16:20:45 +08:00
|
|
|
|
"token": token, "tokenTimeout": strconv.Itoa(int(tokenService.GetOverHours(info.TokenActiveEmail)))}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
ok, msg, subject, tpl = this.renderEmail(subject, tpl, token2Value)
|
|
|
|
|
if !ok {
|
2015-11-13 17:58:41 +08:00
|
|
|
|
return
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
|
|
|
|
// 发送邮件
|
|
|
|
|
ok, msg = this.SendEmail(email, subject, tpl)
|
2015-11-13 17:58:41 +08:00
|
|
|
|
return
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 发送邀请链接
|
|
|
|
|
func (this *EmailService) SendInviteEmail(userInfo info.User, email, content string) bool {
|
2015-11-13 17:58:41 +08:00
|
|
|
|
subject := configService.GetGlobalStringConfig("emailTemplateInviteSubject")
|
|
|
|
|
tpl := configService.GetGlobalStringConfig("emailTemplateInvite")
|
|
|
|
|
|
2014-11-10 16:26:04 +08:00
|
|
|
|
token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(),
|
|
|
|
|
"registerUrl": configService.GetSiteUrl() + "/register?from=" + userInfo.Username,
|
2015-11-13 17:58:41 +08:00
|
|
|
|
"content": content,
|
2014-10-22 16:20:45 +08:00
|
|
|
|
"user": map[string]interface{}{
|
|
|
|
|
"username": userInfo.Username,
|
2015-11-13 17:58:41 +08:00
|
|
|
|
"email": userInfo.Email,
|
2014-10-22 16:20:45 +08:00
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
var ok bool
|
|
|
|
|
ok, _, subject, tpl = this.renderEmail(subject, tpl, token2Value)
|
|
|
|
|
if !ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
// 发送邮件
|
|
|
|
|
ok, _ = this.SendEmail(email, subject, tpl)
|
|
|
|
|
return ok
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 发送评论
|
|
|
|
|
func (this *EmailService) SendCommentEmail(note info.Note, comment info.BlogComment, userId, content string) bool {
|
2015-11-13 17:58:41 +08:00
|
|
|
|
subject := configService.GetGlobalStringConfig("emailTemplateCommentSubject")
|
|
|
|
|
tpl := configService.GetGlobalStringConfig("emailTemplateComment")
|
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
// title := "评论提醒"
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
/*
|
2015-11-13 17:58:41 +08:00
|
|
|
|
toUserId := note.UserId.Hex()
|
|
|
|
|
// title := "评论提醒"
|
|
|
|
|
|
|
|
|
|
// 表示回复回复的内容, 那么发送给之前回复的
|
|
|
|
|
if comment.CommentId != "" {
|
|
|
|
|
toUserId = comment.UserId.Hex()
|
|
|
|
|
}
|
|
|
|
|
toUserInfo := userService.GetUserInfo(toUserId)
|
|
|
|
|
sendUserInfo := userService.GetUserInfo(userId)
|
|
|
|
|
|
|
|
|
|
subject := note.Title + " 收到 " + sendUserInfo.Username + " 的评论";
|
|
|
|
|
if comment.CommentId != "" {
|
|
|
|
|
subject = "您在 " + note.Title + " 发表的评论收到 " + sendUserInfo.Username;
|
|
|
|
|
if userId == note.UserId.Hex() {
|
|
|
|
|
subject += "(作者)";
|
|
|
|
|
}
|
|
|
|
|
subject += " 的评论";
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
|
|
|
|
*/
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
toUserId := note.UserId.Hex()
|
|
|
|
|
// 表示回复回复的内容, 那么发送给之前回复的
|
|
|
|
|
if comment.CommentId != "" {
|
|
|
|
|
toUserId = comment.UserId.Hex()
|
|
|
|
|
}
|
|
|
|
|
toUserInfo := userService.GetUserInfo(toUserId) // 被评论者
|
|
|
|
|
sendUserInfo := userService.GetUserInfo(userId) // 评论者
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
|
|
|
|
// {siteUrl} {blogUrl}
|
2014-10-22 16:20:45 +08:00
|
|
|
|
// {blog.id} {blog.title} {blog.url}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
// {commentUser.userId} {commentUser.username} {commentUser.email}
|
2014-10-22 16:20:45 +08:00
|
|
|
|
// {commentedUser.userId} {commentedUser.username} {commentedUser.email}
|
2014-11-10 16:26:04 +08:00
|
|
|
|
token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(), "blogUrl": configService.GetBlogUrl(),
|
2014-10-22 16:20:45 +08:00
|
|
|
|
"blog": map[string]string{
|
2015-11-13 17:58:41 +08:00
|
|
|
|
"id": note.NoteId.Hex(),
|
2014-10-22 16:20:45 +08:00
|
|
|
|
"title": note.Title,
|
2015-11-13 17:58:41 +08:00
|
|
|
|
"url": configService.GetBlogUrl() + "/view/" + note.NoteId.Hex(),
|
2014-10-22 16:20:45 +08:00
|
|
|
|
},
|
|
|
|
|
"commentContent": content,
|
|
|
|
|
// 评论者信息
|
2015-11-13 17:58:41 +08:00
|
|
|
|
"commentUser": map[string]interface{}{"userId": sendUserInfo.UserId.Hex(),
|
|
|
|
|
"username": sendUserInfo.Username,
|
|
|
|
|
"email": sendUserInfo.Email,
|
2014-10-22 16:20:45 +08:00
|
|
|
|
"isBlogAuthor": userId == note.UserId.Hex(),
|
|
|
|
|
},
|
|
|
|
|
// 被评论者信息
|
|
|
|
|
"commentedUser": map[string]interface{}{"userId": toUserId,
|
2015-11-13 17:58:41 +08:00
|
|
|
|
"username": toUserInfo.Username,
|
|
|
|
|
"email": toUserInfo.Email,
|
2014-10-22 16:20:45 +08:00
|
|
|
|
"isBlogAuthor": toUserId == note.UserId.Hex(),
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ok := false
|
|
|
|
|
ok, _, subject, tpl = this.renderEmail(subject, tpl, token2Value)
|
|
|
|
|
if !ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
// 发送邮件
|
|
|
|
|
ok, _ = this.SendEmail(toUserInfo.Email, subject, tpl)
|
|
|
|
|
return ok
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 验证模板是否正确
|
2015-11-13 17:58:41 +08:00
|
|
|
|
func (this *EmailService) ValidTpl(str string) (ok bool, msg string) {
|
|
|
|
|
defer func() {
|
2014-10-22 16:20:45 +08:00
|
|
|
|
if err := recover(); err != nil {
|
|
|
|
|
ok = false
|
|
|
|
|
msg = fmt.Sprint(err)
|
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
}()
|
|
|
|
|
header := configService.GetGlobalStringConfig("emailTemplateHeader")
|
|
|
|
|
footer := configService.GetGlobalStringConfig("emailTemplateFooter")
|
2014-10-22 16:20:45 +08:00
|
|
|
|
str = strings.Replace(str, "{{header}}", header, -1)
|
|
|
|
|
str = strings.Replace(str, "{{footer}}", footer, -1)
|
|
|
|
|
_, err := template.New("tpl name").Parse(str)
|
2015-11-13 17:58:41 +08:00
|
|
|
|
if err != nil {
|
2014-10-22 16:20:45 +08:00
|
|
|
|
msg = fmt.Sprint(err)
|
2015-11-13 17:58:41 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
ok = true
|
2014-10-22 16:20:45 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ok, msg, subject, tpl
|
2015-11-13 17:58:41 +08:00
|
|
|
|
func (this *EmailService) getTpl(str string) (ok bool, msg string, tpl *template.Template) {
|
|
|
|
|
defer func() {
|
2014-10-22 16:20:45 +08:00
|
|
|
|
if err := recover(); err != nil {
|
|
|
|
|
ok = false
|
|
|
|
|
msg = fmt.Sprint(err)
|
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
}()
|
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
var err error
|
|
|
|
|
var has bool
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
if tpl, has = this.tpls[str]; !has {
|
2015-11-13 17:58:41 +08:00
|
|
|
|
tpl, err = template.New("tpl name").Parse(str)
|
|
|
|
|
if err != nil {
|
2014-10-22 16:20:45 +08:00
|
|
|
|
msg = fmt.Sprint(err)
|
2015-11-13 17:58:41 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
this.tpls[str] = tpl
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
|
|
|
|
ok = true
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 通过subject, body和值得到内容
|
|
|
|
|
func (this *EmailService) renderEmail(subject, body string, values map[string]interface{}) (ok bool, msg string, o string, b string) {
|
|
|
|
|
ok = false
|
|
|
|
|
msg = ""
|
|
|
|
|
defer func() { // 必须要先声明defer,否则不能捕获到panic异常
|
|
|
|
|
if err := recover(); err != nil {
|
|
|
|
|
ok = false
|
2015-11-13 17:58:41 +08:00
|
|
|
|
msg = fmt.Sprint(err) // 这里的err其实就是panic传入的内容,
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
}()
|
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
var tpl *template.Template
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
|
|
|
|
values["siteUrl"] = configService.GetSiteUrl()
|
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
// subject
|
|
|
|
|
if subject != "" {
|
|
|
|
|
ok, msg, tpl = this.getTpl(subject)
|
2015-11-13 17:58:41 +08:00
|
|
|
|
if !ok {
|
2014-10-22 16:20:45 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var buffer bytes.Buffer
|
2015-11-13 17:58:41 +08:00
|
|
|
|
err := tpl.Execute(&buffer, values)
|
|
|
|
|
if err != nil {
|
2014-10-22 16:20:45 +08:00
|
|
|
|
msg = fmt.Sprint(err)
|
|
|
|
|
return
|
2015-11-13 17:58:41 +08:00
|
|
|
|
}
|
|
|
|
|
o = buffer.String()
|
|
|
|
|
} else {
|
|
|
|
|
o = ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// content
|
|
|
|
|
header := configService.GetGlobalStringConfig("emailTemplateHeader")
|
|
|
|
|
footer := configService.GetGlobalStringConfig("emailTemplateFooter")
|
2014-10-22 16:20:45 +08:00
|
|
|
|
body = strings.Replace(body, "{{header}}", header, -1)
|
|
|
|
|
body = strings.Replace(body, "{{footer}}", footer, -1)
|
|
|
|
|
values["subject"] = o
|
|
|
|
|
ok, msg, tpl = this.getTpl(body)
|
2015-11-13 17:58:41 +08:00
|
|
|
|
if !ok {
|
2014-10-22 16:20:45 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var buffer2 bytes.Buffer
|
2015-11-13 17:58:41 +08:00
|
|
|
|
err := tpl.Execute(&buffer2, values)
|
|
|
|
|
if err != nil {
|
2014-10-22 16:20:45 +08:00
|
|
|
|
msg = fmt.Sprint(err)
|
|
|
|
|
return
|
2015-11-13 17:58:41 +08:00
|
|
|
|
}
|
|
|
|
|
b = buffer2.String()
|
|
|
|
|
|
|
|
|
|
return
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 发送email给用户
|
|
|
|
|
// 需要记录
|
|
|
|
|
func (this *EmailService) SendEmailToUsers(users []info.User, subject, body string) (ok bool, msg string) {
|
2015-11-13 17:58:41 +08:00
|
|
|
|
if users == nil || len(users) == 0 {
|
2014-10-22 16:20:45 +08:00
|
|
|
|
msg = "no users"
|
2015-11-13 17:58:41 +08:00
|
|
|
|
return
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
// 尝试renderHtml
|
|
|
|
|
ok, msg, _, _ = this.renderEmail(subject, body, map[string]interface{}{})
|
2015-11-13 17:58:41 +08:00
|
|
|
|
if !ok {
|
2014-10-22 16:20:45 +08:00
|
|
|
|
Log(msg)
|
2015-11-13 17:58:41 +08:00
|
|
|
|
return
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
go func() {
|
|
|
|
|
for _, user := range users {
|
|
|
|
|
LogJ(user)
|
|
|
|
|
m := map[string]interface{}{}
|
|
|
|
|
m["userId"] = user.UserId.Hex()
|
|
|
|
|
m["username"] = user.Username
|
|
|
|
|
m["email"] = user.Email
|
|
|
|
|
ok2, msg2, subject2, body2 := this.renderEmail(subject, body, m)
|
|
|
|
|
ok = ok2
|
|
|
|
|
msg = msg2
|
2015-11-13 17:58:41 +08:00
|
|
|
|
if ok2 {
|
|
|
|
|
sendOk, msg := this.SendEmail(user.Email, subject2, body2)
|
2014-10-22 16:20:45 +08:00
|
|
|
|
this.AddEmailLog(user.Email, subject, body, sendOk, msg) // 把模板记录下
|
|
|
|
|
// 记录到Email Log
|
|
|
|
|
if sendOk {
|
|
|
|
|
// Log("ok " + user.Email)
|
|
|
|
|
} else {
|
|
|
|
|
// Log("no " + user.Email)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Log(msg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}()
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
|
|
|
|
return
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (this *EmailService) SendEmailToEmails(emails []string, subject, body string) (ok bool, msg string) {
|
2015-11-13 17:58:41 +08:00
|
|
|
|
if emails == nil || len(emails) == 0 {
|
2014-10-22 16:20:45 +08:00
|
|
|
|
msg = "no emails"
|
2015-11-13 17:58:41 +08:00
|
|
|
|
return
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
// 尝试renderHtml
|
|
|
|
|
ok, msg, _, _ = this.renderEmail(subject, body, map[string]interface{}{})
|
2015-11-13 17:58:41 +08:00
|
|
|
|
if !ok {
|
2014-10-22 16:20:45 +08:00
|
|
|
|
Log(msg)
|
2015-11-13 17:58:41 +08:00
|
|
|
|
return
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
|
|
|
|
// go func() {
|
|
|
|
|
for _, email := range emails {
|
|
|
|
|
if email == "" {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
m := map[string]interface{}{}
|
|
|
|
|
m["email"] = email
|
|
|
|
|
ok, msg, subject, body = this.renderEmail(subject, body, m)
|
|
|
|
|
if ok {
|
|
|
|
|
sendOk, msg := this.SendEmail(email, subject, body)
|
|
|
|
|
this.AddEmailLog(email, subject, body, sendOk, msg)
|
|
|
|
|
// 记录到Email Log
|
|
|
|
|
if sendOk {
|
|
|
|
|
Log("ok " + email)
|
2014-10-22 16:20:45 +08:00
|
|
|
|
} else {
|
2015-11-13 17:58:41 +08:00
|
|
|
|
Log("no " + email)
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
} else {
|
|
|
|
|
Log(msg)
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
}
|
|
|
|
|
// }()
|
|
|
|
|
|
|
|
|
|
return
|
2014-10-22 16:20:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加邮件日志
|
|
|
|
|
func (this *EmailService) AddEmailLog(email, subject, body string, ok bool, msg string) {
|
|
|
|
|
log := info.EmailLog{LogId: bson.NewObjectId(), Email: email, Subject: subject, Body: body, Ok: ok, Msg: msg, CreatedTime: time.Now()}
|
|
|
|
|
db.Insert(db.EmailLogs, log)
|
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
// 展示邮件日志
|
|
|
|
|
|
|
|
|
|
func (this *EmailService) DeleteEmails(ids []string) bool {
|
|
|
|
|
idsO := make([]bson.ObjectId, len(ids))
|
|
|
|
|
for i, id := range ids {
|
|
|
|
|
idsO[i] = bson.ObjectIdHex(id)
|
|
|
|
|
}
|
|
|
|
|
db.DeleteAll(db.EmailLogs, bson.M{"_id": bson.M{"$in": idsO}})
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-10-22 16:20:45 +08:00
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
func (this *EmailService) ListEmailLogs(pageNumber, pageSize int, sortField string, isAsc bool, email string) (page info.Page, emailLogs []info.EmailLog) {
|
|
|
|
|
emailLogs = []info.EmailLog{}
|
|
|
|
|
skipNum, sortFieldR := parsePageAndSort(pageNumber, pageSize, sortField, isAsc)
|
|
|
|
|
query := bson.M{}
|
|
|
|
|
if email != "" {
|
|
|
|
|
query["Email"] = bson.M{"$regex": bson.RegEx{".*?" + email + ".*", "i"}}
|
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
q := db.EmailLogs.Find(query)
|
2014-10-22 16:20:45 +08:00
|
|
|
|
// 总记录数
|
|
|
|
|
count, _ := q.Count()
|
|
|
|
|
// 列表
|
|
|
|
|
q.Sort(sortFieldR).
|
|
|
|
|
Skip(skipNum).
|
|
|
|
|
Limit(pageSize).
|
|
|
|
|
All(&emailLogs)
|
|
|
|
|
page = info.NewPage(pageNumber, pageSize, count, nil)
|
|
|
|
|
return
|
2015-11-13 17:58:41 +08:00
|
|
|
|
}
|