2026-08-15 01:38:05 +08:00
|
|
|
|
// 使用示例:展示 mailx 的三种典型用法
|
2025-08-30 17:58:23 +08:00
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"context"
|
2026-08-15 01:38:05 +08:00
|
|
|
|
"errors"
|
|
|
|
|
|
"fmt"
|
|
|
|
|
|
"log"
|
2025-08-30 17:58:23 +08:00
|
|
|
|
|
|
|
|
|
|
"code.yun.ink/pkg/mailx"
|
2026-08-15 01:38:05 +08:00
|
|
|
|
"code.yun.ink/pkg/mailx/aliyun"
|
|
|
|
|
|
"code.yun.ink/pkg/mailx/aws"
|
|
|
|
|
|
"code.yun.ink/pkg/mailx/mailgun"
|
|
|
|
|
|
"code.yun.ink/pkg/mailx/smtp"
|
2025-08-30 17:58:23 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
2026-08-15 01:38:05 +08:00
|
|
|
|
// ===== 方式一:单个通道直接发送 =====
|
|
|
|
|
|
// 465 端口走 SSL,587/25 走 STARTTLS;也可显式指定 Encryption
|
|
|
|
|
|
err := smtp.New(smtp.Config{
|
2025-08-30 18:14:09 +08:00
|
|
|
|
Host: "smtpdm-ap-southeast-1.aliyun.com",
|
2026-08-15 01:38:05 +08:00
|
|
|
|
Port: 80,
|
|
|
|
|
|
User: "support@email.blueoceanpay.com",
|
|
|
|
|
|
Password: "SupporT2017",
|
|
|
|
|
|
From: "yun@blueoceanpay.com",
|
|
|
|
|
|
}).Send(ctx, mailx.NewMessage().
|
|
|
|
|
|
From(`"蓝海支付" <yun@blueoceanpay.com>`). // 发件人可带显示名
|
|
|
|
|
|
To("995116474@qq.com").
|
|
|
|
|
|
Subject("Test Email").
|
|
|
|
|
|
Text("纯文本正文").
|
|
|
|
|
|
HTML(`<h1>Hello</h1><p>This is a test email.</p><img src="cid:logo1">`).
|
|
|
|
|
|
InlineImage("logo1", "assets/logo.png"). // 内嵌图片
|
|
|
|
|
|
Build())
|
|
|
|
|
|
fmt.Println("smtp send:", err)
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 方式二:多通道管理器,发送时切换通道 =====
|
|
|
|
|
|
mgr := mailx.NewManager()
|
|
|
|
|
|
_ = mgr.Register(smtp.New(smtp.Config{
|
|
|
|
|
|
Host: "smtp.qq.com", Port: 587, User: "from@qq.com", Password: "auth-code",
|
2025-08-30 18:14:09 +08:00
|
|
|
|
}))
|
2026-08-15 01:38:05 +08:00
|
|
|
|
_ = mgr.Register(aliyun.New(aliyun.Config{
|
|
|
|
|
|
AccessKeyID: "your-access-key-id", AccessKeySecret: "your-access-key-secret",
|
|
|
|
|
|
AccountName: "noreply@example.com",
|
|
|
|
|
|
}))
|
|
|
|
|
|
_ = mgr.Register(aws.New(aws.Config{
|
|
|
|
|
|
AccessKeyID: "your-ak", AccessKeySecret: "your-sk", Region: "ap-northeast-1",
|
|
|
|
|
|
Sender: "noreply@example.com",
|
|
|
|
|
|
}))
|
|
|
|
|
|
_ = mgr.Register(mailgun.New(mailgun.Config{
|
|
|
|
|
|
APIKey: "your-api-key", Domain: "mg.example.com", Sender: "noreply@example.com",
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
|
|
// 同一通道类型(smtp)注册多份不同配置,用实例名区分
|
|
|
|
|
|
_ = mgr.RegisterNamed("smtp-main", smtp.New(smtp.Config{
|
|
|
|
|
|
Host: "smtp.qq.com", Port: 465, User: "a@qq.com", Password: "code-main",
|
|
|
|
|
|
}))
|
|
|
|
|
|
_ = mgr.RegisterNamed("smtp-backup", smtp.New(smtp.Config{
|
|
|
|
|
|
Host: "smtp.163.com", Port: 465, User: "a@163.com", Password: "code-backup",
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
|
|
_ = mgr.SetDefault("aliyun")
|
|
|
|
|
|
|
|
|
|
|
|
// 遍历当前已注册的通道实例信息(实例名 + 类型)
|
|
|
|
|
|
for _, info := range mgr.Senders() {
|
|
|
|
|
|
log.Printf("registered sender: instance=%s type=%s", info.Name, info.Type)
|
|
|
|
|
|
}
|
|
|
|
|
|
log.Println("default:", mgr.Default())
|
|
|
|
|
|
|
|
|
|
|
|
msg := mailx.NewMessage().
|
|
|
|
|
|
From("noreply@example.com").
|
|
|
|
|
|
To("user@example.com").
|
|
|
|
|
|
Subject("Hello").
|
|
|
|
|
|
Text("hello").
|
|
|
|
|
|
HTML("<h1>Hello</h1>").
|
|
|
|
|
|
Build()
|
|
|
|
|
|
|
|
|
|
|
|
if err := mgr.Send(ctx, msg); err != nil { // 默认通道
|
|
|
|
|
|
log.Println("default send:", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
if err := mgr.SendWith(ctx, "aws", msg); err != nil { // 按名称指定通道
|
|
|
|
|
|
log.Println("aws send:", err)
|
2025-08-30 18:14:09 +08:00
|
|
|
|
}
|
2025-08-30 17:58:23 +08:00
|
|
|
|
|
2026-08-15 01:38:05 +08:00
|
|
|
|
// ===== 方式三:发送时临时指定配置(无需提前注册) =====
|
|
|
|
|
|
if err := mgr.SendBy(ctx, mailgun.New(mailgun.Config{
|
|
|
|
|
|
APIKey: "another-key", Domain: "mg2.example.com", Sender: "noreply@example.com",
|
|
|
|
|
|
}), msg); err != nil {
|
|
|
|
|
|
log.Println("mailgun send:", err)
|
2025-08-30 17:58:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-15 01:38:05 +08:00
|
|
|
|
// ===== 错误类型判断 =====
|
|
|
|
|
|
if err := mgr.SendWith(ctx, "no-such-channel", msg); err != nil {
|
|
|
|
|
|
if errors.Is(err, mailx.ErrSenderNotFound) {
|
|
|
|
|
|
log.Println("channel not found, will retry with another channel")
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-30 17:58:23 +08:00
|
|
|
|
}
|