golang打造基於mail的提醒服務

初識golang html

邏輯以下:

程序開啓http服務器接收請求,且每隔20秒查詢一次表auto_backup中flag爲0的值,若是有查到且計劃執行時間小於當前時間,則將表to_do的數據抓出來,經過郵件發送,完成後將數據表flag update 爲1mysql

 

表結構:git

MySQL []> desc auto_backup;
+----------+---------------+------+-----+---------+----------------+
| Field    | Type          | Null | Key | Default | Extra          |
+----------+---------------+------+-----+---------+----------------+
| id       | int(11)       | NO   | PRI | NULL    | auto_increment |
| datetime | int(11)       | NO   |     | NULL    |                |
| to_do    | varchar(2000) | NO   |     | NULL    |                |
| flag     | int(11)       | NO   | MUL | NULL    |                |
+----------+---------------+------+-----+---------+----------------+
4 rows in set (0.04 sec)

表數據:github

MySQL []> SELECT 
    -> `id`,
    -> FROM_UNIXTIME(`auto_backup`.`datetime`) AS `datetimes`,
    -> `auto_backup`.`to_do` AS `to_do`,
    -> `auto_backup`.`flag` AS `flag`
    -> FROM
    -> `auto_backup`
    -> order by datetimes desc
    -> limit 1;
+----+---------------------+-----------------+------+
| id | datetimes           | to_do           | flag |
+----+---------------------+-----------------+------+
| 63 | 2019-04-02 17:30:00 | 哈哈哈測試      |    1 |
+----+---------------------+-----------------+------+
1 row in set (0.04 sec)

 

 

效果以下:

添加記錄golang

 

 

發送記錄 sql

服務器log:數據庫

 

 

代碼以下:

package main

// 導入相關包
import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "gopkg.in/gomail.v2"
    "log"
    "net/http"
    "strconv"
    "time"
)

// http 服務器
func Httpd_beiwang(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()

    // 賽選掉訪問的url路徑爲 /favicon.ico
    if "/favicon.ico" != r.URL.Path {
        log.Println(r.Form)

        // 獲取url參數
        time_value, timeOK := r.Form["time"]
        beiwang_value, beiwangOK := r.Form["beiwang"]

        // 若是兩個參數正確,則判斷參數正確,須要將定時任務寫到數據庫中去
        if timeOK && beiwangOK {
            log.Println("參數判斷ok,參數值爲:")

            log.Println(time_value[0])
            log.Println(beiwang_value[0])

            // 定義初始時間
            const base_format = "\"2006-01-02 15:04\""

            // 轉化爲unix時間
            loc, _ := time.LoadLocation("Local")
            parse_time, err := time.ParseInLocation(base_format, time_value[0], loc)

            unix_parse_time := parse_time.Unix()

            log.Println("Unix 時間爲: ", unix_parse_time)

            if err != nil {
                fmt.Println(err)
            }

            // 須要Insert的sql
            insert_sql := fmt.Sprintf("insert into auto_backup (datetime , to_do , flag) values (%d,%s , 0);", unix_parse_time, beiwang_value[0])

            log.Println("執行的sql: ", insert_sql)

            // 執行sql
            results, err := db.Exec(insert_sql)

            if err != nil {
                log.Println("sql執行錯誤,錯誤內容爲:")
                log.Println(err)
            } else {
                log.Println("執行成功,", results)
                fmt.Fprintf(w, "request ok")
            }

        } else {
            fmt.Fprintf(w, "request error")
        }
    }
}

// 發送郵件
func SendMail(body string) error {
    mailConn := map[string]string{
        "user": "from_user",
        "pass": "password",
        "host": "smtp",
        "port": "port",
    }

    port, _ := strconv.Atoi(mailConn["port"])

    m := gomail.NewMessage()
    //m.SetHeader("From" , "XD Game" + "<" mailConn["user"] + ">")
    m.SetHeader("From", "XD Game"+"<"+mailConn["user"]+">")
    m.SetHeader("To", "to_user")
    m.SetHeader("Subject", "執行計劃")
    m.SetBody("text/html", body)

    d := gomail.NewDialer(mailConn["host"], port, mailConn["user"], mailConn["pass"])

    err := d.DialAndSend(m)

    return err
}

// 返回須要執行定時任務的id,返回值爲Int數組
func Deal_Exec_id(db *sql.DB) []int {
    var send_id []int
    // 獲取當前時間戳
    now_t := time.Now()
    // 執行查詢sql
    select_datetime := fmt.Sprintf("select id from auto_backup where flag = 0 and datetime <= %d", now_t.Unix())

    // 執行sql
    select_rows, err := db.Query(select_datetime)
    log.Println(select_datetime)

    if err != nil {
        log.Println(err)
    }

    for select_rows.Next() {
        var id int

        if err := select_rows.Scan(&id); err != nil {
            log.Println(err)
        }

        //fmt.Println(id)
        // 將查詢的結果追加到send_id中
        send_id = append(send_id, id)

    }
    log.Println("查詢結果返回ID", send_id)

    // 將send_id數組返回
    return send_id
}

func Deal_SendMail(db *sql.DB, send_id []int) {

    var to_do string

    for id := range (send_id) {
        fmt.Println(send_id[id])

        // 根據send_id查詢 messages
        select_sql := fmt.Sprintf("SELECT to_do FROM auto_backup WHERE id = '%d';", send_id[id])
        log.Println(select_sql)

        err := db.QueryRow(select_sql).Scan(&to_do)

        if err != nil {
            log.Println(err)
        }

        log.Println("發送的內容", to_do)
        SendMail(to_do)

        // 執行 update sql
        update_sql := fmt.Sprintf("UPDATE auto_backup SET flag = 1 WHERE id = '%d'", send_id[id])
        log.Println(update_sql)

        results, err := db.Exec(update_sql)

        if err != nil {
            log.Println(err)
        } else {
            log.Println(results)
        }
    }
}



func start_jobs() {
    
    for {
        log.Println("Auto Time jobs Start")
        send_id := Deal_Exec_id(db)
        if 0 == len(send_id) {
            log.Println("未找到相關jobs")
        } else {
            Deal_SendMail(db, send_id)
        }
        // 每隔20秒刷新一次數據庫,查看是否存在新數據
        time.Sleep(time.Second * 20)
    }
}

// 定義*sql.DB 變量
var db *sql.DB

func main() {
    // 鏈接mysql
    var err error
    c := make(chan int, 1)
    db, err = sql.Open("mysql", "username:password@tcp(host)/database_name")

    // 在main退出時關閉連接
    defer db.Close()

    if err != nil {
        log.Println("Connect DB failed")
        log.Println(err)
    }

    // 開啓http服務器
    http.HandleFunc("/", Httpd_beiwang)

    // 開啓協程
    go func() {

        err = http.ListenAndServe("0.0.0.0:9090", nil)

        if err != nil {
            log.Fatal(err)
        }
    }()

    go start_jobs()
    <- c
}
相關文章
相關標籤/搜索