微信小程序模板消息推送,后台主动执行。form_id的解决方案。但是不适用于做全面推广

需求:在后台开启活动后为活跃用户发送服务消息,并连接到小程序上。

          这个需求其实主要的问题点就是form_id

form_id 的生成由小程序前端表单提交场景下,为 submit 事件带上的 formId;支付场景下,为本次支付的 prepay_id

本文中的form_id 为一次性id ,且有效性是7天。

下面是前端的代码

可以在button上添加。我们是在小程序的多个常用button上添加了。

下面是前端请求代码

//生成formId
submit: function (e) {
console.log(e.detail.formId, "我是formID");
wx.request({
url: app.globalData.domain + 'saveFormId',
method: 'POST',
header: {
"content-type": "application/x-www-form-urlencoded"
},
data: {
formId: e.detail.formId,
orgId: app.globalData.orgId,
userId: wx.getStorageSync("shareId")
},
success: function (res) {
}
})
}

需要注意一点:在传参时,使用POST方法的话,必须加上下面的header。否则后台接受的都是null

header: {
"content-type": "application/x-www-form-urlencoded"
},

下面是存储到redis的代码

public void saveFormId(String userId, String formId,String orgId) {
		logger.info("开始保存formId"+formId);
		Date date = new Date();
		long longtime = 60*60*24*7;
		String createDate = DateUtil.getDatetime(date);
		List forms = (List)redisHandle.get("formId:"+orgId);
		logger.info("-----------forms-----"+forms);
		//当前机构存在数据
		int result = 0;
		if (forms!=null&&forms.size()>0){
			//遍历所有人
			for (FormIdBo formBo :forms){
				//存在当前用户
				if (userId.equals(formBo.getUserId())){
					List
forms1 = formBo.getForms(); List delForm = new ArrayList<>(); //删除失效的 if (forms1!=null&&forms1.size()>0){ for (int i = 0;i(); } //删除 for (Integer del : delForm){ forms1.remove(del); } Form form = new Form(); form.setCreateDate(createDate); form.setFormId(formId); forms1.add(form); formBo.setForms(forms1); //更新 redisHandle.set("formId:"+orgId,forms,longtime); logger.info("----------更新的保存成功:{}-----"+forms); result = 1; } } //新增加的用户 if (result==0){ FormIdBo formIdBo = new FormIdBo(); formIdBo.setUserId(userId); Form form = new Form(); form.setFormId(formId); form.setCreateDate(createDate); List formList = new ArrayList<>(); formList.add(form); formIdBo.setForms(formList); forms.add(formIdBo); redisHandle.set("formId:"+orgId,forms,longtime); logger.info("----------新增的保存成功:{}-----"+forms); } }else { //该机构不存在 List fromBoList = new ArrayList<>(); FormIdBo formIdBo = new FormIdBo(); formIdBo.setUserId(userId); Form form = new Form(); form.setFormId(formId); form.setCreateDate(createDate); List formList = new ArrayList<>(); formList.add(form); formIdBo.setForms(formList); fromBoList.add(formIdBo); redisHandle.set("formId:"+orgId,fromBoList,longtime); logger.info("----------新增机构的保存成功:{}-----"+forms); } }

数据结构:{(formId:orgId):{userId:{[formId,createdate]....}}.....}

@Data
public class FormIdBo {
    private String userId;
    private List forms;

}
@Data
public  class Form{
    private String createDate;
    private String formId;
}

发送就是利用api 了

其中template_id 获取temShortId 其实就是登陆后台到模板管理中,模板库中自己去查(或者你获取模板库自己去匹配)。我是自己找的。

   public Map getSmallTemplateId(String accessToken, String temShortId ,ArrayList keywordIdList){
        String url = "https://api.weixin.qq.com/cgi-bin/wxopen/template/library/get?access_token"+accessToken;
        Map paramMap = new HashMap<>();
        paramMap.put("id",temShortId);
        paramMap.put("keyword_id_list",keywordIdList);
        String param = JSON.toJSONString(paramMap);
        String result = PostUtils.postToUrl(param,url);
        Map resultMap = JSONObject.parseObject(result,Map.class);
        return resultMap;
    }

发送

  private String sendOpenActivityMessage(User user,String activityName,String date, String formId,String page){
        ArrayList arrayList = new ArrayList<>();
        //添加的消息模板中的关键词所在的value
        arrayList.add(21);
        arrayList.add(121);
        Response templateResult = orgWeixinTemplateService.findSmallByOrgIdAndShortId(user.getOrgId(),ModelMessageNumber.SHOP_OPEN_ACTIVITY.getCode(),arrayList);
        Response userResult= userManager.getShopAccessToken(user.getOrgId());
        if(!userResult.isSuccess()){
            log.info("--------获取accessToken失败:{}------------",userResult.getErrorMessage());
            return userResult.getErrorMessage();
        }
        String accessToken = userResult.getData();
        if(!templateResult.isSuccess()){
            log.info("------templateId获取失败:{}-----------",templateResult.getErrorMessage());
            return templateResult.getErrorMessage();
        }
        log.info("------t数据初始化成功:{}-----------");
        String templateId = templateResult.getData();
        String openId = user.getWxUnionid();
        Map data = new HashMap<>();
        Map activityNameMap = new HashMap<>();
        activityNameMap.put("value",activityName);
        Map dateMap = new HashMap<>();
        dateMap.put("value",date);
        data.put("keyword1",activityNameMap);
        data.put("keyword2",dateMap);
        Map paramMap = new HashMap<>();
        paramMap.put("touser",openId);
        paramMap.put("template_id",templateId);
        paramMap.put("form_id",formId);
        paramMap.put("data",data);
        if (StringUtils.isNotEmpty(page)){
            log.info("------跳跳跳跳跳转+++++:{}--------------",page);
            paramMap.put("page",page);
        }
        //字体变大  变大后最多七个字, 超了不显示
        paramMap.put("emphasis_keyword","keyword1.DATA");
        String param = JSON.toJSONString(paramMap);
        String result = PostUtils.postToUrl(param,"https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token="+accessToken);
        log.info("------小程序订单推送结果:{}--------------",result);
        return result;
    }

坑还是比较多的。慢慢填吧。

首先:form_id 微信限制的。跟人一一对应的,而且是一次性的有效期还是7天。(优化是增加签到功能,在每天签到的方法中加入存储form_id的方法。这样能够更有效的维护活跃用户。而且也保证了form_id 的时效性。)

再有:就是template_id 看代码的时候,那个OPEN开头的和 AT 开头的id 的出处有些蒙,但是也是很快就找到了出处。

在上面的代码中,我觉得比较low ,而且代码没有优化,一两天弄出来的。form_id 就忙了一天。还是记录一下。有不清楚的人可以给我留言。

你可能感兴趣的:(微信)