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

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
}