1. Go语言中的时间函数介绍
在Go语言中,时间相关的函数都封装在time包中。time包中的时间类型有两种,一种是Time类型,表示时间点;另一种是Duration类型,表示两个时间点之间的时间间隔。在生成日程日历中,我们需要用到的是Time类型的时间函数。
可以通过time.Now()函数获取当前的时间:
import "time"
func main() {
now := time.Now()
fmt.Println(now) // 打印当前时间
}
注意:Go语言中的时间都是UTC时间(Coordinated Universal Time,世界协调时间)。如果要将时间转换成本地时间,可以使用time.LoadLocation()函数。
2. 生成日程日历
2.1 创建事件结构体
为了方便地管理事件,我们可以创建一个事件的结构体。
type Event struct {
Name string // 事件名称
StartTime time.Time // 事件开始时间
EndTime time.Time // 事件结束时间
}
2.2 创建日程表
日程表可以使用一个切片来存储所有的事件。
var schedule []Event
2.3 添加事件到日程表
可以通过append()函数将一个事件添加到日程表中。
event := Event{
Name: "Go语言学习",
StartTime: time.Date(2021, time.September, 1, 8, 0, 0, 0, time.Local),
EndTime: time.Date(2021, time.September, 1, 10, 0, 0, 0, time.Local),
}
schedule = append(schedule, event)
3. 生成微信提醒
生成微信提醒需要使用微信开放平台提供的API接口。在使用API之前,需要在微信开放平台上创建一个应用,并获取应用的AppID和AppSecret。
3.1 获取AccessToken
调用微信API需要先获取Access Token。可以通过以下接口获取Access Token:
const (
grantType = "client_credential"
apiUrl = "https://api.weixin.qq.com/cgi-bin/token"
)
type TokenResponse struct {
AccessToken string `json:"access_token"`
ExpiresIn int64 `json:"expires_in"`
ErrCode int `json:"errcode"`
ErrMsg string `json:"errmsg"`
}
func GetAccessToken() (string, error) {
res, err := http.Get(fmt.Sprintf("%s?grant_type=%s&appid=%s&secret=%s", apiUrl, grantType, appId, appSecret))
if err != nil {
return "", err
}
defer res.Body.Close()
var token TokenResponse
err = json.NewDecoder(res.Body).Decode(&token)
if err != nil {
return "", err
}
if token.ErrCode != 0 {
return "", fmt.Errorf("Get access token error: %s", token.ErrMsg)
}
return token.AccessToken, nil
}
注意:Access Token有有效时间限制,需要在获取之后存储并定时更新。
3.2 发送模板消息
在获取了Access Token之后,可以使用模板消息接口向用户发送消息。
const (
templateId = "your_template_id" // 模板ID
apiUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send"
)
type TemplateMessage struct {
ToUser string `json:"touser"`
TemplateId string `json:"template_id"`
Data struct {
First templateMsgValue `json:"first"`
Keyword1 templateMsgValue `json:"keyword1"`
Keyword2 templateMsgValue `json:"keyword2"`
Keyword3 templateMsgValue `json:"keyword3"`
Remark templateMsgValue `json:"remark"`
} `json:"data"`
}
type templateMsgValue struct {
Value string `json:"value"`
}
func SendTemplateMsg(accessToken string, openId string, event Event) error {
msg := TemplateMessage{
ToUser: openId,
TemplateId: templateId,
Data: struct {
First templateMsgValue `json:"first"`
Keyword1 templateMsgValue `json:"keyword1"`
Keyword2 templateMsgValue `json:"keyword2"`
Keyword3 templateMsgValue `json:"keyword3"`
Remark templateMsgValue `json:"remark"`
}{
First: templateMsgValue{Value: fmt.Sprintf("您有一个新的事件:%s", event.Name)},
Keyword1: templateMsgValue{Value: event.Name},
Keyword2: templateMsgValue{Value: event.StartTime.Format("2006-01-02 15:04")},
Keyword3: templateMsgValue{Value: event.EndTime.Format("2006-01-02 15:04")},
Remark: templateMsgValue{Value: "请及时处理"},
},
}
body, err := json.Marshal(msg)
if err != nil {
return err
}
res, err := http.Post(fmt.Sprintf("%s?access_token=%s", apiUrl, accessToken), "application/json", bytes.NewReader(body))
if err != nil {
return err
}
defer res.Body.Close()
var result ApiResult
err = json.NewDecoder(res.Body).Decode(&result)
if err != nil {
return err
}
if result.ErrCode != 0 {
return fmt.Errorf("Send template message error: %s", result.ErrMsg)
}
return nil
}
4. 生成邮件提醒
生成邮件提醒需要使用SMTP协议。可以使用Go语言自带的net/smtp包来实现邮件发送。
4.1 连接到SMTP服务器
const (
smtpAddr = "smtp.example.com" // SMTP服务器地址
smtpPort = "465" // SMTP服务器端口
smtpUser = "your_username" // SMTP用户名
smtpPass = "your_password" // SMTP密码
)
var auth = smtp.PlainAuth("", smtpUser, smtpPass, smtpAddr)
func dial() (*smtp.Client, error) {
host := fmt.Sprintf("%s:%s", smtpAddr, smtpPort)
return smtp.DialTLS(host, nil)
}
4.2 发送邮件
func SendMail(email string, event Event) error {
subject := fmt.Sprintf("您有一个新的事件:%s", event.Name)
body := fmt.Sprintf("事件名称:%s\n开始时间:%s\n结束时间:%s\n", event.Name, event.StartTime.Format("2006-01-02 15:04"), event.EndTime.Format("2006-01-02 15:04"))
msg := []byte(fmt.Sprintf("To: %s\r\nSubject: %s\r\n\r\n%s", email, subject, body))
auth := smtp.PlainAuth("", smtpUser, smtpPass, smtpAddr)
err := smtp.SendMail(fmt.Sprintf("%s:%s", smtpAddr, smtpPort), auth, "your_email@example.com", []string{email}, msg)
if err != nil {
return err
}
return nil
}
5. 完整代码
以下是生成日程日历并生成微信和邮件提醒的完整代码:
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/smtp"
"time"
)
type Event struct {
Name string // 事件名称
StartTime time.Time // 事件开始时间
EndTime time.Time // 事件结束时间
}
var schedule []Event
const (
grantType = "client_credential"
apiUrl = "https://api.weixin.qq.com/cgi-bin/token"
appId = "your_app_id" // 应用的AppID
appSecret = "your_app_secret" // 应用的AppSecret
)
type TokenResponse struct {
AccessToken string `json:"access_token"`
ExpiresIn int64 `json:"expires_in"`
ErrCode int `json:"errcode"`
ErrMsg string `json:"errmsg"`
}
type TemplateMessage struct {
ToUser string `json:"touser"`
TemplateId string `json:"template_id"`
Data struct {
First templateMsgValue `json:"first"`
Keyword1 templateMsgValue `json:"keyword1"`
Keyword2 templateMsgValue `json:"keyword2"`
Keyword3 templateMsgValue `json:"keyword3"`
Remark templateMsgValue `json:"remark"`
} `json:"data"`
}
type templateMsgValue struct {
Value string `json:"value"`
}
type ApiResult struct {
ErrCode int `json:"errcode"`
ErrMsg string `json:"errmsg"`
}
func GetAccessToken() (string, error) {
res, err := http.Get(fmt.Sprintf("%s?grant_type=%s&appid=%s&secret=%s", apiUrl, grantType, appId, appSecret))
if err != nil {
return "", err
}
defer res.Body.Close()
var token TokenResponse
err = json.NewDecoder(res.Body).Decode(&token)
if err != nil {
return "", err
}
if token.ErrCode != 0 {
return "", fmt.Errorf("Get access token error: %s", token.ErrMsg)
}
return token.AccessToken, nil
}
const (
templateId = "your_template_id" // 模板ID
apiUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send"
)
func SendTemplateMsg(accessToken string, openId string, event Event) error {
msg := TemplateMessage{
ToUser: openId,
TemplateId: templateId,
Data: struct {
First templateMsgValue `json:"first"`
Keyword1 templateMsgValue `json:"keyword1"`
Keyword2 templateMsgValue `json:"keyword2"`
Keyword3 templateMsgValue `json:"keyword3"`
Remark templateMsgValue `json:"remark"`
}{
First: templateMsgValue{Value: fmt.Sprintf("您有一个新的事件:%s", event.Name)},
Keyword1: templateMsgValue{Value: event.Name},
Keyword2: templateMsgValue{Value: event.StartTime.Format("2006-01-02 15:04")},
Keyword3: templateMsgValue{Value: event.EndTime.Format("2006-01-02 15:04")},
Remark: templateMsgValue{Value: "请及时处理"},
},
}
body, err := json.Marshal(msg)
if err != nil {
return err
}
res, err := http.Post(fmt.Sprintf("%s?access_token=%s", apiUrl, accessToken), "application/json", bytes.NewReader(body))
if err != nil {
return err
}
defer res.Body.Close()
var result ApiResult
err = json.NewDecoder(res.Body).Decode(&result)
if err != nil {
return err
}
if result.ErrCode != 0 {
return fmt.Errorf("Send template message error: %s", result.ErrMsg)
}
return nil
}
const (
smtpAddr = "smtp.example.com" // SMTP服务器地址
smtpPort = "465" // SMTP服务器端口
smtpUser = "your_username" // SMTP用户名
smtpPass = "your_password" // SMTP密码
)
var auth = smtp.PlainAuth("", smtpUser, smtpPass, smtpAddr)
func dial() (*smtp.Client, error) {
host := fmt.Sprintf("%s:%s", smtpAddr, smtpPort)
return smtp.DialTLS(host, nil)
}
func SendMail(email string, event Event) error {
subject := fmt.Sprintf("您有一个新的事件:%s", event.Name)
body := fmt.Sprintf("事件名称:%s\n开始时间:%s\n结束时间:%s\n", event.Name, event.StartTime.Format("2006-01-02 15:04"), event.EndTime.Format("2006-01-02 15:04"))
msg := []byte(fmt.Sprintf("To: %s\r\nSubject: %s\r\n\r\n%s", email, subject, body))
auth := smtp.PlainAuth("", smtpUser, smtpPass, smtpAddr)
err := smtp.SendMail(fmt.Sprintf("%s:%s", smtpAddr, smtpPort), auth, "your_email@example.com", []string{email}, msg)
if err != nil {
return err
}
return nil
}
func main() {
event := Event{
Name: "Go语言学习",
StartTime: time.Date(2021, time.September, 1, 8, 0, 0, 0, time.Local),
EndTime: time.Date(2021, time.September, 1, 10, 0, 0, 0, time.Local),
}
schedule = append(schedule, event)
// 发送微信提醒
accessToken, err := GetAccessToken()
if err != nil {
panic(err)
}
openId := "your_open_id"
err = SendTemplateMsg(accessToken, openId, event)
if err != nil {
panic(err)
}
// 发送邮件提醒
email := "your_email@example.com"
err = SendMail(email, event)
if err != nil {
panic(err)
}
}