配合nginx代理,进行扩展有很大的进一步开发空间
使用示例
go get gopkg.in/gomail.v2
复制代码
示例目录结构
email
| http_demo.go //示例文件
| http_demo.txt //附件文件
| email | email.go //lib文件 需要修改相应的smtp配置
复制代码
详细内容如下:
http_demo.go代码:
package main
import (
"fmt"
"net/http"
"log"
"encoding/json"
"./email"
)
type Msg struct {
CODE int
MSG string
DATA []string
}
func send_email(msg map[string][]string) string {
_, err := email.SendEmail_163(msg)
if err != "" {
fmt.Println(err)
}
return err
}
func handle(w http.ResponseWriter, r *http.Request) {
msg := Msg {
CODE : 200,
MSG : "成功",
DATA : []string {},
}
r.ParseForm() //解析参数,默认是不会解析的
fmt.Println(r.Form) //这些信息是输出到服务器端的打印信息
fmt.Println("path:", r.URL.Path + "\n")
fmt.Println("scheme:", r.URL.Scheme + "\n")
fmt.Println("method:", r.Method + "\n")
if r.Method == "POST" {
email := r.Form
err := send_email(email)
if err != "" {
msg = Msg {
CODE : 400,
MSG : err,
DATA : []string {},
}
}
data, _ := json.Marshal(msg)
//这个写入到w的是输出到客户端的
fmt.Fprintf(w, string(data))
} else {
msg = Msg {
CODE : 400,
MSG : "请求method有错",
DATA : []string {},
}
data, _ := json.Marshal(msg)
//这个写入到w的是输出到客户端的
fmt.Fprintf(w, string(data))
}
}
func main() {
http.HandleFunc("/", handle) //设置访问的路由
err := http.ListenAndServe(":8888", nil) //设置监听的端口
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
复制代码
email | email.go 代码:
package email_web
import (
"log"
"gopkg.in/gomail.v2"
"fmt"
"strings"
"os"
"net/http"
"io"
)
func SendEmail_163(data map[string][]string) (bool, string) {
var exist = true
// 必填项
from, exist := data["from"]
if !exist || from[0] == "" {
return exist, "发送人邮箱为空";
}
from_user, exist := data["from_user"]
if !exist || from_user[0] == "" {
return exist, "发送人名字为空";
}
to, exist := data["to"]
if !exist || to[0] == "" {
return exist, "接收人邮箱为空";
}
subject, exist := data["subject"]
if !exist || subject[0] == "" {
return exist, "邮件标题为空";
}
content, exist := data["content"]
if !exist || content[0] == "" {
return exist, "邮件内容为空";
}
email := gomail.NewMessage()
email.SetAddressHeader("From", from[0], from_user[0])
// 接收人
var to_emails []string
var to_users []string
// 选填项判断
to_user, to_users_exist := data["to_user"]
if to_users_exist && to_user[0] != "" {
for _, v := range strings.Split(data["to_user"][0], ",") {
to_users = append(to_users, v)
}
}
// 构造接收人数组
for k, v := range strings.Split(data["to"][0], ",") {
// 选填项判断
if to_users_exist {
to_emails = append(to_emails, email.FormatAddress(v, to_users[k]))
} else {
to_emails = append(to_emails, v)
}
}
email.SetHeaders(map[string][]string{"To": to_emails})
email.SetHeader("Subject", subject[0])
//text/plain 这个参数可以进一步抽象
email.SetBody("text/plain;charset=UTF-8", content[0] + "\n")
//抄送人
_, cc_exists := data["cc"]
if cc_exists {
// 选填项判断
var cc_emails []string
var cc_users []string
cc_user, cc_users_exist := data["cc_user"]
if cc_users_exist && cc_user[0] != "" {
for _, v := range strings.Split(data["cc_user"][0], ",") {
cc_users = append(cc_users, v)
}
}
// 构造抄送人数组
for k, v := range strings.Split(data["cc"][0], ",") {
// 选填项判断
if cc_users_exist {
cc_emails = append(cc_emails, email.FormatAddress(v, cc_users[k]))
} else {
cc_emails = append(cc_emails, v)
}
}
email.SetHeaders(map[string][]string{"Cc": cc_emails})
}
// 选填项 附件
// 相对于email/http_demo.go的路径
filename, file_exist := data["filename"]
var filepaths []string
if file_exist && filename[0] != "" {
files := strings.Split(filename[0], ",")
for _, file := range files {
tmp := strings.Split(file, "/")
if tmp[0] == "http:" || tmp[0] == "https:" {
filepath, err := download_file(file, tmp[len(tmp) - 1])
filepaths = append(filepaths, filepath)
if err != ""{
for _, filepath = range filepaths {
os.Remove(filepath)
}
return exist, err
}
} else {
filepaths = append(filepaths, file)
}
}
for _, file := range filepaths {
email.Attach(fmt.Sprintf("%s", file))
}
}
dialer := &gomail.Dialer{
Host: "smtp.163.com",
Port: 25,
Username: "jacoovan@163.com", // 替换自己的邮箱地址
Password: "163smtp", // 自定义smtp服务器密码
SSL: false,
}
if err := dialer.DialAndSend(email); err != nil {
remove_file(filepaths)
log.Println("邮件发送失败!err: ", err)
return false, fmt.Sprintf("邮件发送失败!err: %s", err)
}
remove_file(filepaths)
log.Println("邮件发送成功!")
return exist, ""
}
func download_file(url string, filename string)(string, string){
res, err := http.Get(url)
if err != nil {
return "/tmp/" + filename, "文件下载出错,检查文件地址"
}
f, err := os.Create("/tmp/" + filename)
if err != nil {
return "/tmp/" + filename, "文件保存出错,检查目录"
}
io.Copy(f, res.Body)
return "/tmp/" + filename, ""
}
func remove_file(filepaths []string) {
for _, filepath := range filepaths {
os.Remove(filepath)
}
}
复制代码