糯麦 NurMai

400-158-5662

糯麦科技

/

新闻资讯

/

技术讨论

/

小程序统一发送消息

小程序统一发送消息

原创 新闻资讯

于 2023-09-20 13:14:36 发布

17650 浏览

下发统一消息

用于通过服务号模板消息下发小程序和公众号统一的服务消息,接口文档地址:


https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-message-management/uniform-message/sendUniformMessage.html


开通模板功能:

登录公众号后台,在“新的功能/广告与服务”中开通模板消息。


access_token 获取:

调用 uniform_send 发送消息需要 access_token,获取 access_token 方法有两种:使用 getAccessToken 或者 authorizer_access_token,这里使用的是 getAccessToken 方式。

getAccessToken:有效期目前为 7200 秒,并且是有上限次数的(具体上限次数在公众号后台的接口权限中查看),需做缓存处理,防止超过次数导致失效。


编码

package com.demo.util;

import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;

import java.time.Duration;
import java.time.Instant;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName: WxapiUtil.java
 * @ClassPath: com.demo.util.WxapiUtil.java
 * @Description: 微信工具
 * @Author: tanyp
 * @Date: 2023/9/18 10:07
 **/
@Slf4j
public class WxapiUtil {

    /**
     * @MonthName: getToken
     * @Description: 获取token
     * @Author: tanyp
     * @Date: 2023/9/18 11:07
     * @Param: [appid, secret]
     * @return: java.lang.String
     **/
    public synchronized static String getToken(String appid, String secret) {
        JSONObject obj = accessTokenMap.get(appid);
        if (Objects.isNull(obj) || Duration.between((Instant) obj.get("time"), Instant.now()).getSeconds() > 7100) {
            String token = getAccessToken(appid, secret);
            accessTokenMap.put(appid, JSONObject.of("token", token, "time", Instant.now()));
            log.info("========获取 AccessToken======:{}", accessTokenMap.get(appid));
            return token;
        } else {
            log.info("========缓存取 AccessToken======:{}", obj);
            return obj.getString("token");
        }
    }

    public static String getAccessToken(String appid, String secret) {
        String AccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret;
        HttpClient client = null;
        String accessToken = null;
        try {
            client = new DefaultHttpClient();
            HttpGet httpget = new HttpGet(AccessTokenUrl);
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            String response = client.execute(httpget, responseHandler);
            JSONObject OpenidJSON = JSONObject.parseObject(response);
            accessToken = String.valueOf(OpenidJSON.get("access_token"));
        } catch (Exception e) {
            log.error("获取token异常:", e);
        } finally {
            client.getConnectionManager().shutdown();
        }
        return accessToken;
    }

    /**
     * @MonthName: uniformSend
     * @Description: 下发统一消息
     * @Author: tanyp
     * @Date: 2023/9/18 10:10
     * @return: java.lang.String
     **/
    public static String uniformSend(String appid, String secret, String openId, String pagepath, String mpAppId, String url, String templateId, JSONObject data) {
        HttpClient client = null;
        try {
            client = HttpClients.createDefault();

            // 获取 access_token
            String token = getToken(appid, secret);
            if (Objects.isNull(token) && Objects.equals("", token)) {
                log.error("获取AccessToken异常");
                return "获取 AccessToken 异常";
            }

            // 发送消息
            String messageUrl = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=";
            HttpPost httpPost = new HttpPost(messageUrl + token);
            JSONObject params = new JSONObject();
            params.put("touser", openId); // 接收者openid

            // 公众号模板消息相关的信息
            JSONObject mp_template_msg = new JSONObject();
            mp_template_msg.put("appid", mpAppId);
            mp_template_msg.put("template_id", templateId);
            // 模板跳转链接
            mp_template_msg.put("url", url);

            // 跳小程序所需数据,不需跳小程序可不用传该数据
            JSONObject miniprogram = new JSONObject();
            miniprogram.put("appid", appid);
            miniprogram.put("pagepath", pagepath);
            mp_template_msg.put("miniprogram", miniprogram);

            // 模板数据
            mp_template_msg.put("data", data);

            params.put("mp_template_msg", mp_template_msg);

            httpPost.setEntity(new StringEntity(params.toString(), "UTF-8"));
            String res = client.execute(httpPost, new BasicResponseHandler());
            if (Objects.nonNull(res) && !Objects.equals("", res)) {
                JSONObject obj = JSONObject.parseObject(res);
                if (Objects.equals("0", obj.getString("errcode"))) {
                    return "发送消息成功!";
                }
                return obj.getString("errmsg");
            }
        } catch (Exception e) {
            log.error("发送模板消息异常:{}", e);
        } finally {
            client.getConnectionManager().shutdown();
        }

        return "发送消息失败!";
    }

}


uniformSend 参数:

• appid:小程序 appid

• secret:小程序 secret

• openId:用户 openid (以是小程序的 openid,也可以是 mp_template_msg.app

• pagepath:小程序跳转地址,如:pages/home/home

• mpAppId:公众号 appid,要求与小程序有绑定且同主体

• url:公众号模板消息所要跳转的url(可以为空)

• templateId:公众号模板id

• data:公众号模板消息的数据,如:{"thing1":{"value":"测试"}}


注意事项

1、access_token 是用小程序的 appid 和 secret 获取的。

2、接受用的 openid 为小程序端的。

3、mp_template_msg.appid 为公众号的 appid。

4、mp_template_msg.url 不能为空,那么怕写个 xxx。

5、如果要小程序,则 miniprogram 下填充小程序的 appid 和 page。

6、统一服务消息的发送位置为公众号。

7、公众号的小程序一定要关联以下哦(不需要开放平台关联)。


小程序消息,小程序开发,小程序制作

阅读排行

  • 1. 几行代码就能实现Html大转盘抽奖

    大转盘抽奖是网络互动营销的一种常见形式,其通过简单易懂的界面设计,让用户在游戏中体验到乐趣,同时也能增加商家与用户之间的互动。本文将详细介绍如何使用HTML,CSS和JavaScript来实现大转盘抽奖的功能。

    查看详情
  • 2. 浙江省同区域公司地址变更详细流程

    提前准备好所有需要的资料,包含:房屋租赁合同、房产证、营业执照正副本、代理人身份证正反面、承诺书(由于我们公司其中一区域已有注册另外一公司,所以必须需要承诺书)

    查看详情
  • 3. 微信支付商户申请接入流程

    微信支付,是微信向有出售物品/提供服务需求的商家提供推广销售、支付收款、经营分析的整套解决方案,包括多种支付方式,如JSAPI支付、小程序支付、APP支付H5支付等支付方式接入。

    查看详情
  • 4. 阿里云域名ICP网络备案流程

    根据《互联网信息服务管理办法》以及《非经营性互联网信息服务备案管理办法》,国家对非经营性互联网信息服务实行备案制度,对经营性互联网信息服务实行许可制度。

    查看详情
  • 5. 微信小程序申请注册流程

    微信小程序注册流程与微信公众号较为相似,同时微信小程序支持通过已认证的微信公众号进行注册申请,无需进行单独认证即可使用,同一个已认证微信公众号可同时绑定注册多个小程序。

    查看详情