第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > Golang实现发送微信公众号模板消息(每日一句和天气预报)

Golang实现发送微信公众号模板消息(每日一句和天气预报)

时间:2020-09-06 09:02:07

相关推荐

Golang实现发送微信公众号模板消息(每日一句和天气预报)

Golang实现发送微信模板消息(每日一句和天气预报)

前言

本文是基于/connect/p/python-wechat-iciba.html 这篇博客写成的。该博客实现了用python将金山词霸的每日一句推送到微信公众测试号,我想既然python能实现,那么用Golang也可以。

后来又加了每天早晨定时给自己和女朋友发天气预报提醒,开始着手做,gogogo!

运行环境

阿里云Linux服务器Go开发环境

完整的项目代码:/qq737310694/WechatTemplate

一、获取接口数据

1、每日一句接口

调用地址:/dsapi/

请求方式:GET

请求参数:

返回类型:JSON

JSON字段解释:

返回示例:

{"sid": "3369","tts": "/admin/tts/-04-23-day.mp3","content": "There is no such thing as a great talent without great will.","note": "没有伟大的意志力,便没有雄才大略。","love": "197","translation": "小编的话:正如爱迪生所说一般,强者容易坚强。只有坚强的意志力才能给我们克服各种困难的勇气和决心。","picture": "/news/word/0423.jpg","picture2": "/news/word/big_0423b.jpg","caption": "词霸每日一句","dateline": "-04-23","s_pv": "0","sp_pv": "0","tags": [{"id": null,"name": null}],"fenxiang_img": "/web/news/longweibo/imag/-04-23.jpg"}

请求示例:

type sentence struct {Contentstring `json:"content"`Note string `json:"note"`Translation string `json:"translation"`}func getsen() (sentence, string) {resp, err := http.Get("/dsapi/?date")sent := sentence{}if err != nil {fmt.Println("获取每日一句失败", err)return sent, ""}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Println("读取内容失败", err)return sent, ""}err = json.Unmarshal(body, &sent)if err != nil {fmt.Println("每日一句解析json失败")return sent, ""}fenxiangurl := gjson.Get(string(body), "fenxiang_img").String()fmt.Println(sent)return sent, fenxiangurl}

这里使用了golang自带的http包发起了一次get请求,然后将返回的json数据解析出来,另外使用了gjon这个包,该包可以直接从json字符串中解析出需要的字段,十分方便。(其实这段代码我偷了个懒,如果内部有错误应该将错误return出去,大家不要学我啊 ~~o(>_<)o ~~)

2、获取天气预报接口

调用地址:/api

请求方式:GET

请求参数:

返回类型:JSON

返回示例:

{"cityid": "10111","update_time": "-04-24 18:00:00","city": "青岛","cityEn": "qingdao","country": "中国","countryEn": "China","data": [{"day": "24日(今天)","date": "-04-24","week": "星期三","wea": "阵雨","wea_img": "lei","air": 45,"humidity": 96,"air_level": "优","air_tips": "空气很好,可以外出活动,呼吸新鲜空气,拥抱大自然!","alarm": {"alarm_type": "大雾","alarm_level": "橙色","alarm_content": "青岛市气象台04月24日02时15分继续发布大雾橙色预警信号:目前我市沿海地区和近海海域已出现能见度小于200米局部小于100米的大雾,预计今天凌晨到白天,我市沿海地区和近海海域仍将有能见度小于200米的大雾天气,局部小于100米,请注意防范。(预警信息来源:国家预警信息发布中心)"},"tem1": "16℃","tem2": "10℃","tem": "13℃","win": ["南风"],"win_speed": "3-4级","hours": [{"day": "24日20时","wea": "晴","tem": "13℃","win": "南风","win_speed": "<3级"},{"day": "24日23时","wea": "多云","tem": "15℃","win": "南风","win_speed": "<3级"},{"day": "25日02时","wea": "多云","tem": "15℃","win": "南风","win_speed": "<3级"},{"day": "25日05时","wea": "多云","tem": "15℃","win": "南风","win_speed": "<3级"}],"index": [{"title": "紫外线指数","level": "最弱","desc": "辐射弱,涂擦SPF8-12防晒护肤品。"},{"title": "减肥指数","level": null,"desc": "天气较舒适,减肥正当时。"},{"title": "健臻·血糖指数","level": "较易波动","desc": "血糖较易波动,注意监测。"},{"title": "穿衣指数","level": "较冷","desc": "建议着厚外套加毛衣等服装。"},{"title": "洗车指数","level": "不宜","desc": "有雨,雨水和泥水会弄脏爱车。"},{"title": "空气污染扩散指数","level": "中","desc": "易感人群应适当减少室外活动。"}]}]}

该接口会返回往后一周的天气预报,因为返回的参数过多,我只截取了当天的数据。如果需要其它数据可以自己请求一下。

请求示例代码:

func getweather(city string) (string, string, string, string) {url := fmt.Sprintf("/api?version=%s&city=%s", WeatherVersion, city)resp, err := http.Get(url)if err != nil {fmt.Println("获取天气失败", err)return "", "", "", ""}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Println("读取内容失败", err)return "", "", "", ""}data := gjson.Get(string(body), "data").Array()thisday := data[0].String()day := gjson.Get(thisday, "day").Str //日期wea := gjson.Get(thisday, "wea").Str//天气tem := gjson.Get(thisday, "tem").Str//平均气温air_tips := gjson.Get(thisday, "air_tips").Str//提示return day, wea, tem, air_tips}

get请求获得天气数据,gjson包将当天的天气信息解析出来后返回。同样地,偷懒错误没return出去 ?。

二、微信公众平台接口测试帐号

通过上一步我们已经成功的获取到了数据,接下来申请一个微信公众平台测试帐号,其实正式帐号的操作也是一样的,但方便起见,我们直接用测试号。

1、每日一句模板

扫码登录公众平台测试号

申请测试号的地址 https://mp./debug/cgi-bin/sandbox?t=sandbox/login手机上确认登录找到新增测试模板,添加模板消息

填写模板标题 《每日一句》,填写如下模板内容

{{content.DATA}}

{{note.DATA}}

{{translation.DATA}}

注意:后面的.DATA必须保留,前面是你定义的字段。

提交保存之后,记住该模板ID,一会儿会用到

找到测试号信息,记住appid和appsecret,一会儿会用到找到测试号二维码。手机扫描此二维码,关注之后,你的昵称会出现在右侧列表里,记住该微信号,一会儿会用到(注:此微信号非你真实的微信号,而是你的微信在关注了该测试号后分配的在该号下的唯一ID)

2、天气预报模板

和每日一句的添加方法一样,区别在于第3步中新增测试模板使用的模板不同:

{{city.DATA}}

{{day.DATA}}

{{wea.DATA}}

{{tem1.DATA}}

{{air_tips.DATA}}

三、发送微信模板消息的程序

//发送每日一句,将json字符串拼接好后调用templatepost函数发送模板func everydaysen() {req, fxurl := getsen()if req.Content == "" {return}access_token := getaccesstoken()if access_token == "" {return}flist := getflist(access_token) //获取公众号关注人列表if flist == nil {return}reqdata := "{\"content\":{\"value\":\"" + req.Content + "\", \"color\":\"#0000CD\"}, \"note\":{\"value\":\"" + req.Note + "\"}, \"translation\":{\"value\":\"" + req.Translation + "\"}}"for _, v := range flist {templatepost(access_token, reqdata, fxurl, SentTemplateID, v.Str)}}//发送天气预报func weather() {access_token := getaccesstoken()if access_token == "" {return}flist := getflist(access_token)if flist == nil {return}var city stringfor _, v := range flist {switch v.Str {case "oeZ6P5kyGsLKn3sIGRVfpb8oT4mg":city = "青岛"go sendweather(access_token, city, v.Str)case "oeZ6P5jvFNh2y_h_2UcaoTXBaC2o":city = "西安"go sendweather(access_token, city, v.Str)default:}}fmt.Println("weather is ok")}//获取微信accesstokenfunc getaccesstoken() string {url := fmt.Sprintf("https://api./cgi-bin/token?grant_type=client_credential&appid=%v&secret=%v", APPID, APPSECRET)resp, err := http.Get(url)if err != nil {fmt.Println("获取微信token失败", err)return ""}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Println("微信token读取失败", err)return ""}token := token{}err = json.Unmarshal(body, &token)if err != nil {fmt.Println("微信token解析json失败", err)return ""}return token.AccessToken}//获取关注人列表func getflist(access_token string) []gjson.Result {url := "https://api./cgi-bin/user/get?access_token=" + access_token + "&next_openid="resp, err := http.Get(url)if err != nil {fmt.Println("获取关注列表失败", err)return nil}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Println("读取内容失败", err)return nil}flist := gjson.Get(string(body), "data.openid").Array()return flist}//发送模板消息代码func templatepost(access_token string, reqdata string, fxurl string, templateid string, openid string) {url := "https://api./cgi-bin/message/template/send?access_token=" + access_tokenreqbody := "{\"touser\":\"" + openid + "\", \"template_id\":\"" + templateid + "\", \"url\":\"" + fxurl + "\", \"data\": " + reqdata + "}"resp, err := http.Post(url,"application/x-www-form-urlencoded",strings.NewReader(string(reqbody)))if err != nil {fmt.Println(err)return}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Println(err)return}fmt.Println(string(body))}//拼接json字符串,调用templatepost函数发送天气模板func sendweather(access_token, city, openid string) {day, wea, tem, air_tips := getweather(city)if day == "" || wea == "" || tem == ""|| air_tips == "" {return}reqdata := "{\"city\":{\"value\":\"城市:" + city + "\", \"color\":\"#0000CD\"}, \"day\":{\"value\":\"" + day + "\"}, \"wea\":{\"value\":\"天气:" + wea + "\"}, \"tem1\":{\"value\":\"平均温度:" + tem + "\"}, \"air_tips\":{\"value\":\"tips:" + air_tips + "\"}}"//fmt.Println(reqdata)templatepost(access_token, reqdata, "", WeatTemplateID, openid)}

在发送模板消息之前要先获取微信accesstoken和关注人列表,再遍历所有关注人,给每位关注人发模板消息,或者给某位特定的人发送。

四、设置定时发送

func main() {spec := "0 0 12 * * *" // 每天12:00spec1 := "0 0 7 * * *" // 每天早晨7:00c := cron.New()c.AddFunc(spec, everydaysen)c.AddFunc(spec1, weather)c.Start()fmt.Println("开启定时任务")select {}//weather()//everydaysen()}

使用了 /robfig/cron 包的定时任务,使每天早晨7点和中午12点发送天气预报和每日一句。

spec := “0 0 12 * * *”

这里对应的分别是 “秒 分 时 日 月 周” 和linux里的crontab定时任务差不多。

在阿里云Linux服务器上后台启动该程序既可。

程序运行结果截图:

完美解决,好吧,并不完美,其实代码还是有很大的优化空间,由于时间紧凑,就不优化了,知道就行,是吧O(∩_∩)O~

完整的项目代码:/qq737310694/WechatTemplate

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。