golang实现微信模板消息推送
Golang实现发送微信模板消息(每日一句和天气预报)
- 前言
- 运行环境
- 获取接口数据
- 1、每日一句接口
- 2、获取天气预报接口
- 二、微信公众平台接口测试帐号
- 1、每日一句模板
- 2、天气预报模板
- 三、发送微信模板消息的程序
- 四、设置定时发送
前言
本文是基于https://www.cnblogs.com/connect/p/python-wechat-iciba.html 这篇博客写成的。该博客实现了用python将金山词霸的每日一句推送到微信公众测试号,我想既然python能实现,那么用Golang也可以。
特别提醒:另外是实际项目开发中,先在正式微信公众号平台找到合适的模板,获取到模板内容设置,然后在测试号中根据获取到的模板设置添加测试模板,获取到测试模板的模板id进行开发(遇到过的坑,因为不知道需要先去正式平台上获取模板内容设置,导致项目上线时找不到可用的模板) 。
运行环境
1、阿里云Linux服务器
2、Go开发环境
完整的项目代码:https://github.com/qq737310694/WechatTemplate
获取接口数据
1、每日一句接口
参数 | 必选 | 参数 | 必选 |
---|---|---|---|
date | 否 | string | 格式为:2013-05-06;如果date为空,则默认取当天 |
type | 否 | string | 可选值为last和next;以date日期为准的,last返回前一天的,next返回后一天的 |
返回类型:JSON
JSON字段解释:
属性名 | 属性值类型 | 说明 |
---|---|---|
sid | string | 每日一句ID |
tts | string | 音频地址 |
content | string | 英文内容 |
note | string | 中文内容 |
love | string | 每日一句喜欢个数 |
translation | string | 词霸小编 |
picture | string | 图片地址 |
picture2 | string | 大图片地址 |
caption | string | 标题 |
dateline | string | 时间 |
s_pv | string | 浏览数 |
sp_pv | string | 语音评测浏览数 |
tags | array | 相关标签 |
fenxiang_img | string | 合成图片,建议分享微博用的 |
返回示例:
{"sid": "3369","tts": "http://news.iciba.com/admin/tts/2019-04-23-day.mp3","content": "There is no such thing as a great talent without great will.","note": "没有伟大的意志力,便没有雄才大略。","love": "197","translation": "小编的话:正如爱迪生所说一般,强者容易坚强。只有坚强的意志力才能给我们克服各种困难的勇气和决心。","picture": "http://cdn.iciba.com/news/word/20190423.jpg","picture2": "http://cdn.iciba.com/news/word/big_20190423b.jpg","caption": "词霸每日一句","dateline": "2019-04-23","s_pv": "0","sp_pv": "0","tags": [{"id": null,"name": null}],"fenxiang_img": "http://cdn.iciba.com/web/news/longweibo/imag/2019-04-23.jpg"
}
请求示例:
type sentence struct {Content string `json:"content"`Note string `json:"note"`Translation string `json:"translation"`
}func getsen() (sentence, string) {resp, err := http.Get("http://open.iciba.com/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、获取天气预报接口
调用地址: https://www.tianqiapi.com/api
请求方式:GET
请求参数:
参数 | 必选 | 类型 | 说明 |
---|---|---|---|
version | 是 | string | v1(版本标识) |
cityid | 以下参数3选1 | string | 101120201(城市编号,不要带CN, 以下参数3选1) |
city | 3选1 | string | 青岛(城市名称,不要带市和区) |
ip | 3选1 | string | 27.193.XX.XXX(IP地址) |
callback | string | jsonp方式 |
返回类型:JSON
返回示例:
{"cityid": "101120201","update_time": "2019-04-24 18:00:00","city": "青岛","cityEn": "qingdao","country": "中国","countryEn": "China","data": [{"day": "24日(今天)","date": "2019-04-24","week": "星期三","wea": "阵雨","wea_img": "lei","air": 45,"humidity": 96,"air_level": "优","air_tips": "空气很好,可以外出活动,呼吸新鲜空气,拥抱大自然!","alarm": {"alarm_type": "大雾","alarm_level": "橙色","alarm_content": "青岛市气象台2019年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("https://www.tianqiapi.com/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、每日一句模板
1、扫码登录公众平台测试号
申请测试号的地址 https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
2、手机上确认登录
3、找到 新增测试模板 ,添加模板消息
填写模板标题 《每日一句》,填写如下模板内容
{{content.DATA}}
{{note.DATA}}
{{translation.DATA}}
注意:后面的.DATA必须保留,前面是你定义的字段。
提交保存之后,记住该模板ID,一会儿会用到
4、找到测试号信息,记住 appid 和 appsecret,一会儿会用到
5、找到测试号二维码。手机扫描此二维码,关注之后,你的昵称会出现在右侧列表里,记住该微信号,一会儿会用到(注:此微信号非你真实的微信号,而是你的微信在关注了该测试号后分配的在该号下的唯一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")
}//获取微信accesstoken
func getaccesstoken() string {url := fmt.Sprintf("https://api.weixin.qq.com/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.weixin.qq.com/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.weixin.qq.com/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()
}
使用了 github.com/robfig/cron 包的定时任务,使每天早晨7点和中午12点发送天气预报和每日一句。
spec := “0 0 12 * * *”
这里对应的分别是 “ 秒 分 时 日 月 周 ” 和linux里的crontab定时任务差不多。
在阿里云Linux服务器上后台启动该程序既可。
程序运行结果截图:
完整的项目代码:https://github.com/qq737310694/WechatTemplate
————————————————
版权声明:本文为CSDN博主「我是要成为大神的男人」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u012140251/article/details/89529540
golang实现微信模板消息推送相关推荐
- php 异步请求微信模板消息_php实现微信模板消息推送
本文实例为大家分享了php微信模板消息推送的具体代码,供大家参考,具体内容如下 1.微信公众号模板消息配置 2.PHP代码/*** 发送模板消息*/ public function send_noti ...
- springboot实现微信模板消息推送
springboot实现微信模板消息推送 在上一篇文章我们已经知道了怎么获取openid 还不知道的可以查看我的上一篇文章springboot+微信小程序用codeid换取openid 这次我们不光要 ...
- java 微信模板_java开发微信模板消息推送
概述 微信公众平台开始支持前端网页,大家可能看到很多网页上都有分享到朋友圈,关注微信等按钮,点击它们都会弹出一个窗口让你分享和关注,这个是怎么实现的呢?今天就给大家讲解下如何在微信公众平台前端网页上添 ...
- PHP之 微信模板消息推送 的相关代码
温馨提示: 微信模板消息推送,得先去微信端,设置模板配置,会生成相应的消息模板id,这个是一串字符,需连同参数数据,传给微信端,切记!~ 第一部分:主体部分代码,负责业务模块,准备微信端所需参数 /* ...
- java开发微信模板消息推送
完整demo下载 概述 微信公众平台开始支持前端网页,大家可能看到很多网页上都有分享到朋友圈,关注微信等按钮,点击它们都会弹出一个窗口让你分享和关注,这个是怎么实现的呢?今天就给大家讲解下如何在微信公 ...
- 微信模板消息推送(内附工具类代码)
文章目录 前言 一.添加模板消息 1.进入微信公众号后台 2.模板消息 3.填写信息 4.审核通过后 二.开发步骤 1.依赖坐标 2.实体类 1)AccessToken 2.WxTemplate模板消 ...
- Java实现微信模板消息推送
模板消息推送功能仅限于微信服务号才行. 1.准备:微信公众号 appId,app密钥(这俩没啥好说的,都知道在哪拿). 模板Id,添加之后就能看到,如果没有合适的模板可以自定义模板(需要审核7-15天 ...
- qhfl-9 微信模板消息推送
开发中用的是测试号 微信公众号认证流程 用户登陆 <!DOCTYPE html> <html lang="en"> <head><meta ...
- 微信模板消息推送接口说明
微信服务号可以给关注此号码的粉丝推送消息.消息分为三种: 1.群发消息:给所有关注此微信的人同时发送,但每个月的发送次数有限制. 2.向单个粉丝发送消息:此种功能发送次数没有限制,但是接受消息的粉丝必 ...
- 微信模板消息推送心得
我使用amp的软件,上百度找到相关的代码,复制,保存到php文件上,然后,打开浏览器,查看效果.遇到下面的问题 1.网页打不开,提示连接已重置. 后来发现,原来在apache下的logs文件夹内的er ...
最新文章
- Verilog中的条件编译语句 `ifdef、`else、`endif 等
- Codeforces 1198 1199
- Apache Maven 入门篇
- php.ini-development和php.ini-production的区别
- JavaSE进阶学习笔记-目录汇总(待完成)
- spark-sql建表语句限制_SparkSQL
- easyui crud java_Easyui 创建 CRUD 应用_EasyUI 插件
- 1.12 深层循环神经网络
- 软考——软件工程——结构化分析与设计方法
- Java实现本地缓存、分布式缓存及多级缓存
- matlab opnet,opnet环境变量和matlab联调心得
- 为什么买入不了创业版_为什么说不能买创业板?
- Fiddler调式使用(一)深入研究[转载]
- C语言读取文件时txt中的汉字出现乱码的解决方案
- 数据管理执行指南 | 你需要知道什么?
- 计算机语言的魅力,四年级语文下册《语言的魅力》说课稿
- linux环境下questasim 10.7的安装步骤
- 【P2P overlay network】跨内外网络虚拟私有云
- 腾讯后台面经大全(整合版)
- Linux基础知识问题解答