You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
3.5 KiB
162 lines
3.5 KiB
package biz
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
|
|
"bkb-notify/internal/conf"
|
|
|
|
"crypto/tls"
|
|
"net/smtp"
|
|
|
|
"github.com/go-kratos/kratos/v2/log"
|
|
"github.com/jordan-wright/email"
|
|
)
|
|
|
|
// ErrUserNotFound is user not found.
|
|
|
|
// GreeterRepo is a Greater repo.
|
|
type EmailRepo interface {
|
|
Send(context.Context, *Greeter) (*Greeter, error)
|
|
FindByID(context.Context, int64) (*Greeter, error)
|
|
ListByName(context.Context, string) ([]*Greeter, error)
|
|
ListAll(context.Context) ([]*Greeter, error)
|
|
}
|
|
|
|
// EmailUsecase is a Greeter usecase.
|
|
type EmailUsecase struct {
|
|
repo GreeterRepo
|
|
log *log.Helper
|
|
c *conf.App_Email
|
|
wg *sync.WaitGroup
|
|
ch chan int
|
|
}
|
|
|
|
// NewGreeterUsecase new a Greeter usecase.
|
|
func NewEmailUsecase(repo GreeterRepo, logger log.Logger, c *conf.App) *EmailUsecase {
|
|
return &EmailUsecase{repo: repo, log: log.NewHelper(logger), c: c.Email, wg: &sync.WaitGroup{}, ch: make(chan int, 2)}
|
|
}
|
|
|
|
func (uc *EmailUsecase) SendEmail(to []string, subject string, body string, files []string) (err error) {
|
|
from := uc.c.Account
|
|
nickname := uc.c.Sender
|
|
secret := uc.c.Password
|
|
host := uc.c.Host
|
|
port := uc.c.Port
|
|
//port := 587
|
|
isSSL := uc.c.IsSSL
|
|
|
|
auth := smtp.PlainAuth("", from, secret, host)
|
|
e := email.NewEmail()
|
|
if nickname != "" {
|
|
e.From = fmt.Sprintf("%s <%s>", nickname, from)
|
|
} else {
|
|
e.From = from
|
|
}
|
|
e.Subject = subject
|
|
e.HTML = []byte(body)
|
|
hostAddr := fmt.Sprintf("%s:%d", host, port)
|
|
e.To = to
|
|
|
|
// 创建../docs目录
|
|
os.Mkdir("docs", os.ModePerm)
|
|
// 添加附件
|
|
for _, obsUrl := range files {
|
|
// 下载素材
|
|
resp, err := http.Get(obsUrl)
|
|
if err != nil {
|
|
log.Log(log.LevelError, "email", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
// 获取URL中的文件名
|
|
segments := strings.Split(obsUrl, "/")
|
|
filename := segments[len(segments)-1]
|
|
|
|
// 创建一个文件用于保存下载的内容
|
|
out, err := os.Create("docs/" + filename)
|
|
if err != nil {
|
|
log.Log(log.LevelError, "email", err)
|
|
}
|
|
defer out.Close()
|
|
|
|
// 将响应流和文件流连接起来
|
|
_, err = io.Copy(out, resp.Body)
|
|
if err != nil {
|
|
log.Log(log.LevelError, "email", err)
|
|
}
|
|
|
|
// Attach the file
|
|
_, err = e.AttachFile("docs/" + filename)
|
|
if err != nil {
|
|
log.Log(log.LevelError, "email", err)
|
|
}
|
|
|
|
// 删除临时文件
|
|
err = os.Remove("docs/" + filename)
|
|
if err != nil {
|
|
log.Log(log.LevelError, "email", err)
|
|
}
|
|
}
|
|
|
|
if isSSL {
|
|
err = e.SendWithTLS(hostAddr, auth, &tls.Config{ServerName: host})
|
|
} else {
|
|
err = e.Send(hostAddr, auth)
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
func (uc *EmailUsecase) BulkSendEmail(to []string, subject string, body string) error {
|
|
from := uc.c.Account
|
|
nickname := uc.c.Sender
|
|
secret := uc.c.Password
|
|
host := uc.c.Host
|
|
port := uc.c.Port
|
|
//port := 587
|
|
isSSL := uc.c.IsSSL
|
|
|
|
auth := smtp.PlainAuth("", from, secret, host)
|
|
e := email.NewEmail()
|
|
if nickname != "" {
|
|
e.From = fmt.Sprintf("%s <%s>", nickname, from)
|
|
} else {
|
|
e.From = from
|
|
}
|
|
e.Subject = subject
|
|
e.HTML = []byte(body)
|
|
hostAddr := fmt.Sprintf("%s:%d", host, port)
|
|
var err error
|
|
var errList []string
|
|
for _, vTo := range to {
|
|
|
|
e.To = []string{vTo}
|
|
uc.ch <- 1
|
|
uc.wg.Add(1)
|
|
go func(ve *email.Email) {
|
|
defer uc.wg.Done()
|
|
|
|
if isSSL {
|
|
err = e.SendWithTLS(hostAddr, auth, &tls.Config{ServerName: host})
|
|
} else {
|
|
err = e.Send(hostAddr, auth)
|
|
}
|
|
if err != nil {
|
|
errList = append(errList, e.To...)
|
|
}
|
|
<-uc.ch
|
|
}(e)
|
|
}
|
|
uc.wg.Wait()
|
|
if len(errList) > 0 {
|
|
return fmt.Errorf(fmt.Sprintf("发送失败%d条:%s", len(errList), strings.Join(errList[:3], ",")))
|
|
}
|
|
|
|
return err
|
|
}
|
|
|