安装
某天通过v2了解到了golang编写的redis客户端,感觉很奇妙,没想到可以这样构建应用,正好有简单需求,所以想起来这个,于是简单尝试了一下。
首先通过官网的指引,一步步的进行安装。前置依赖需要golang 和 Node,然后直接go install github.com/wailsapp/wails/v2/cmd/wails@latest
安装就行
要注意golang的环境变量配置,不然可能找不到。
安装完成后,需要执行下 wails doctor
,检查下相关的依赖和环境。
运行
使用命令wails init -n myproject -t vue-ts
也可以使用第三方模板进行初始化wails init -n <Your Appname> -t https://github.com/misitebao/wails-template-vue[@version]
如果需要调试的话,创建项目的时候可以加上wails init -n yourProject --ide goland
这里,我使用最简单的方式构建一下wails init -n MyJob -t vue-ts --ide goland
开发运行的话使用 wails dev
构建项目使用wails build
需求:群发邮箱
1 使用smtp
发送邮件
2 使用imap
保存邮件
3 根据文件读取发件人和附件
首先创建邮件,在app.go
中创建函数
func createEmail(to, cc, bcc []string, attachmentPath string) []byte {
var b bytes.Buffer
writer := multipart.NewWriter(&b)
smtpUser := "user@user.com"
subject := GetFileName(attachmentPath)
body := `<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>月度账单通知</title>
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
}
.indent {
text-indent: 2em; /* 缩进 2em */
}
.section {
margin-bottom: 1em; /* 段落间距 */
}
.redfont {
color: red;
}
</style>
</head>
<body>
<p>尊敬的合作伙伴:</p>
<p class="indent">大家好!</p>
<br>
<p class="indent">顺颂商祺。</p>
</body>
</html>
`
// 写入邮件头
header := textproto.MIMEHeader{}
header.Set("From", smtpUser)
header.Set("To", strings.Join(to, ", "))
if len(cc) > 0 {
header.Set("Cc", strings.Join(cc, ", "))
}
header.Set("Subject", subject)
header.Set("MIME-Version", "1.0")
header.Set("Content-Type", fmt.Sprintf("multipart/mixed; boundary=%s", writer.Boundary()))
for k, v := range header {
fmt.Fprintf(&b, "%s: %s\r\n", k, v[0])
}
b.WriteString("\r\n")
// 写入邮件正文
part, _ := writer.CreatePart(textproto.MIMEHeader{"Content-Type": {"text/html"}})
part.Write([]byte(body))
// 添加附件
attachment, err := os.ReadFile(attachmentPath)
if err != nil {
log.Fatal(err)
}
part, _ = writer.CreatePart(textproto.MIMEHeader{
"Content-Type": {"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
"Content-Transfer-Encoding": {"base64"},
"Content-Disposition": {"attachment; filename=\" " + subject + ".xlsx\""},
})
encoder := base64.NewEncoder(base64.StdEncoding, part)
encoder.Write(attachment)
encoder.Close()
writer.Close()
return b.Bytes()
}
因为需要支持 抄送和密送,所以传入的时候要加上header.Set("Cc", strings.Join(cc, ", "))
附件的Content-Type
不确定的话,可以使用writer := multipart.NewWriter(body)
来获取合适的类型
然后使用smtp
发送邮件
func sendEmail(to, cc, bcc []string, emailContent []byte) error {
// 配置 SMTP 服务器信息
smtpHost := "smtp.xx.com"
smtpPort := "465"
smtpUsername := "user@user.com"
smtpPassword := "xxxxxxxxxx"
from := smtpUsername
// 发送邮件
// 设置 TLS 配置
tlsConfig := &tls.Config{
ServerName: smtpHost,
}
// 建立 TLS 连接
conn, err := tls.Dial("tcp", smtpHost+":"+smtpPort, tlsConfig)
if err != nil {
return fmt.Errorf("failed to create TLS connection: %v", err)
}
// 创建 SMTP 客户端
client, err := smtp.NewClient(conn, smtpHost)
if err != nil {
return fmt.Errorf("failed to create SMTP client: %v", err)
}
defer client.Close()
// 认证
auth := smtp.PlainAuth("", smtpUsername, smtpPassword, smtpHost)
if err = client.Auth(auth); err != nil {
return fmt.Errorf("failed to authenticate: %v", err)
}
// 设置发件人和收件人
if err = client.Mail(from); err != nil {
return fmt.Errorf("failed to set sender: %v", err)
}
// 设置所有收件人(包括 To、Cc 和 Bcc)
recipients := append(append(to, cc...), bcc...)
for _, recipient := range recipients {
if err = client.Rcpt(recipient); err != nil {
return fmt.Errorf("failed to add recipient %s: %v", recipient, err)
}
}
// 发送邮件内容
writer, err := client.Data()
if err != nil {
return fmt.Errorf("failed to create data writer: %v", err)
}
_, err = writer.Write(emailContent)
if err != nil {
return fmt.Errorf("failed to write email content: %v", err)
}
err = writer.Close()
if err != nil {
return fmt.Errorf("failed to close data writer: %v", err)
}
return client.Quit()
}
这里有一个问题,就是需要配置TLS,然后将上一步构建的邮件内容添加上就行
然后再说保存,如果需要在其他客户端查看自动发送的记录,就需要imap
协议登录邮箱后,单独保存到指定的邮箱目录中
func saveToSentFolder(emailContent []byte) error {
// 连接到 IMAP 服务器
imapAddr := "imap.xxx.com:993"
client, err := imapclient.DialTLS(imapAddr, nil)
if err != nil {
return err
}
defer client.Close()
// 登录
if err := client.Login("user@user.com", "xxxxxxxxx").Wait(); err != nil {
return err
}
mailboxes, err := client.List("", "%", nil).Collect()
if err != nil {
log.Fatalf("failed to list mailboxes: %v", err)
}
log.Printf("Found %v mailboxes", len(mailboxes))
for _, mbox := range mailboxes {
log.Printf(" - %v", mbox.Mailbox)
}
// 使用 APPEND 命令保存邮件
size := int64(len(emailContent))
appendCmd := client.Append("Sent Messages", size, nil)
if _, err := appendCmd.Write(emailContent); err != nil {
log.Fatalf("failed to write message: %v", err)
}
if err := appendCmd.Close(); err != nil {
log.Fatalf("failed to close message: %v", err)
}
if _, err := appendCmd.Wait(); err != nil {
log.Fatalf("APPEND command failed: %v", err)
}
return err
}
到此,基本的需求已经搞定了,剩下就是根据读取的配置目录和文件,进行发送就行