小程序如何向公众号推送消息

2022-07-13 14:36:38

 如果你在开发公众号(跟小程序绑在同一个开发平台),那就可以直接使用公众号的相关接口去往用户的公众号推送消息。但你只开发小程序,没有开发公众号,可以参考方法给用户公众号推送消息。

小程序中的接口:下发小程序和公众号统一的服务

意思就是小程序中的这个接口可以使用公众号的模板向用户公众号推送消息

uniformMessage.send | 微信开放文档微信开发者平台文档https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/uniform-message/uniformMessage.send.html前提条件:

微信公众号:AppId和APPSecret(必须认证)
微信小程序:AppId和APPSecret(必须认证)
微信开放平台(小程序和公众号必须绑定到同一个开放平台,必须认证)

UnionID机制说明:

开发者可通过OpenID(每个应用都拥有自己的openID,它们的openID不一样)来获取用户基本信息。特别需要注意的是,如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。(其中的unionid绑定了开放者平台才会有的)

一、获取小程序用户信息

注:如果你已经开始开发小程序,或者已经得到了用户信息,可直接看第二步

1、小程序前端通过调用wx.login()会获取到一个用户登录凭证code(有效期五分钟),将code传给后台,后台通过appId、APPSecret和code能够获取到这个用户的微信基本信息。文档地址:

auth.code2Session | 微信开放文档微信开发者平台文档https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html接口如下:

GET 
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

(其中的unionID是小程序绑定了开放平台才会有的,如果绑定后还是没有unionID,那就是此用户没有关注与小程序相同主体的公众号)

2、将用户信息保存在自己的数据库中

3、通过小程序的AppId和AppSecret获取小程序的access_token(7200秒有效)并保存到数据库中,文档地址:auth.getAccessToken | 微信开放文档微信开发者平台文档https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/access-token/auth.getAccessToken.html

https请求方式: GET(请使用https协议)
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

二、获取微信公众号的所有用户信息(公众号中的用户都是已经关注该公众号的)并存储在自己的数据库中

1、通过微信公众号的AppId和AppSecret(当前ip地址必须在微信公众号的白名单内)
获取微信公众号的access_token(7200秒有效),文档地址:

微信开放文档微信开发者平台文档https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html

https请求方式: GET(请使用https协议)
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

2、通过刚才获取到的access_token去获取所有用户的openId,文档地址:

微信开放文档微信开发者平台文档https://developers.weixin.qq.com/doc/offiaccount/User_Management/Getting_a_User_List.html接口如下:

http请求方式: GET(请使用https协议)
https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID

3、将所有的openId全部放在一个新的数组中,然后for循环,循环次数为openId的数组的长度,然后调用链接循环请求每个用户的基本信息,并存到数据库中,文档地址:
微信开放文档微信开发者平台文档https://developers.weixin.qq.com/doc/offiaccount/User_Management/Get_users_basic_information_UnionID.html#UinonId
接口如下:

http请求方式: GET(请使用https协议)
https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

三、微信公众号推送消息

现在,本地数据库中存放着小程序用户表和关注微信公众号的用户表,下一步就是向小程序用户推送微信公众号信息

1、在本地小程序用户表中获取一个用户M的信息,得到用户M的openId和unionId

2、通过M的unionId到本地微信公众号表里去查找对应的M用户的微信公众号openId

3、通过小程序中的 下发小程序和公众号统一的服务消息(uniformMessage.send)接口链接发送关注模板消息,接口链接如下。文档地址在文章开头。

POST 
https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=ACCESS_TOKEN

注意参数:

1、access_token 这个接口中的access_token必须是小程序的access_token,不能使用公众号的,因为官方黑这个接口就是想大家在开发小程序的时候,如果要发送公众号消息直接使用这个接口就可以了,无需再去调用公众号的模板消息接口。

2、touser 用户openid,发送公众号模板消息,就必须用mp_template_msg.appid对应的公众号的openid

//发送公众号模板消息(uniformMessage.send)下发小程序和公众号统一的服务消息
func SendUniformMessage() {
	//小程序的access_token
	var access_token = `52_f9pr1XSlC4B7UK9oQAjcrYLJ1qdgVzs7Dj-OjolTTi8y7fFKWazOGSHjFBny9Jjqjmgu1f4yzRrao7nlH2z7-Vu5MDHZOkagZJdTS5CZ74GBAkC6nDqfImQvwU1Qk7FOLnRJKtOW1iDM7Nq4UVJeAFAJKY`
	sender := weapp.UniformMsgSender{
		ToUser: "oIozb6u_3Mv8V4g3u5_JIUDvYdJ0", //公众号模板用公众号中用户的openid
		//UniformWeappTmpMsg: weapp.UniformWeappTmpMsg{
		//	TemplateID: "template-id",
		//	Page:       "page",
		//	FormID:     "form-id",
		//	Data: weapp.UniformMsgData{
		//		"keyword": {Value: "value"},
		//	},
		//	EmphasisKeyword: "keyword.DATA",
		//},
		UniformMpTmpMsg: weapp.UniformMpTmpMsg{
			AppID:      utils.Public_AppID,
			TemplateID: "W_bIT89e8JNzVXtV6arw8t5Fn3N6xrJjagHEWiXDSts",
			URL:        "http://weixin.qq.com/download",
			//Miniprogram: weapp.UniformMsgMiniprogram{"miniprogram-app-id", "page-path"},
			Data: weapp.UniformMsgData{
				"keyword": {"value", "#173177"},
			},
		},
	}

	res, err := sender.Send(access_token)
	if err != nil {
		// 处理一般错误信息
		log.Error("dddddddddddd: ", err)
		return
	}
	fmt.Printf("返回结果qqqq: %#v", res)
	if err := res.GetResponseError(); err != nil {
		// 处理微信返回错误信息
		log.Error("ccccccccccccc: ", err)
		return
	}

	fmt.Printf("返回结果: %#v", res)
}

四、需要注意的一些问题

在获取关注公众号的用户信息并存到本地数据库中时,要注意两者之间的同步。我的处理如下:

1、首先获取微信公众号的用户列表,得到一系列用户的openID,记为A;再从本地公众号数据库中获得之前关注的一系列用户openID,记为B

2、分别取两个集合之间的差集,进一步进行处理

1)、B与A的差集,记为Y,这些全是已取消关注微信公众号的用户(如果后面重新关注公众号,微信公众号会为这些用户重新按时间戳(秒)记录新的,因为关注公众号的用户要记录到本地,所以)

2)、A与B的差集,记为X,这些全是最新关注的用户(包括之前取消关注,再重新关注的用户)

3)、Y集合中的openID全是需要先去数据库删除的用户,X集合中的openID全是需要保存到本地的用户

3、根据自己的业务,定时去按照以上进行同步到本地

以上三步可以保证本地关注公众号的用户表是最新的。虽然效率不高,但也是想到比较好的方法了,如果有更好的想法,欢迎指点

  • 作者:fbbqt
  • 原文链接:https://blog.csdn.net/fbbqt/article/details/122167097
    更新时间:2022-07-13 14:36:38