go發送郵件(web接口訪問)

配合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: "[email protected]",    // 替換自己的郵箱地址
        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)
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章