公众号开发

公众号开发

公众号配置:微信公众平台

开发文档:微信官方文档 | 微信开放文档

设置服务器AppId、Secret、白名单

菜单:开发-基本配置获得公众号的AppId和AppSecret

 服务器配置

网页授权

如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。

  • 以snsapi_base为scope的网页授权。即静默授权。

  • 以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。

用户第一次授权时用snsapi_userinfo拿用户的基本信息,后续用静默授权即可。

菜单配置

公众号接口调试工具:

微信公众平台接口调试工具

菜单增删改查接口文档:

微信开放文档

API

@RequestMapping("/wxapi")
@Controller
public class WxApiController {

    @Autowired
    private GzhMessageService messageService;

    @Autowired
    private WxApiService weiXinService;

    @Autowired
    private RedisService redisService;

    /**
     * GET请求:进行URL、Tocken 认证;
     * 1. 将token、timestamp、nonce三个参数进行字典序排序
     * 2. 将三个参数字符串拼接成一个字符串进行sha1加密
     * 3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
     */
    @RequestMapping(value = "/wx/receive",  method = RequestMethod.GET)
    public void doGet(HttpServletRequest request,HttpServletResponse response) {
        //如果是多账号,根据url中的account参数获取对应的MpAccount处理即可

        Set<String> keySet = request.getParameterMap().keySet();
        Iterator<String> iterator = keySet.iterator();
        while(iterator.hasNext()){
            //如果存在,则调用next实现迭代
            String key=iterator.next();
            System.out.println("key: " + key + " value: " + request.getParameterMap().get(key)+"");
        }
        String accessToken = redisService.getAccessToken();
        PrintWriter out = null;
        try {
            out = response.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(StringUtils.isNotEmpty(accessToken)){
            String signature = request.getParameter("signature");// 微信加密签名
            String timestamp = request.getParameter("timestamp");// 时间戳
            String nonce = request.getParameter("nonce");// 随机数
            String echostr = request.getParameter("echostr");// 随机字符串

            // 校验成功返回  echostr,成功成为开发者;否则返回error,接入失败
            if (SignUtil.validSign(signature, accessToken, timestamp, nonce)) {
                System.out.println("返回数据:"+echostr);
                out.print(echostr);
            }
        }

        out.close();
        out = null;
    }

    @RequestMapping(value = "/wx/receive", method = RequestMethod.POST)
    public void doPost(HttpServletRequest request,HttpServletResponse response) {
        //处理用户和微信公众账号交互消息
        try {
            MsgRequest msgRequest = MsgXmlUtil.parseXml(request);
            PrintWriter out = response.getWriter();
            out.print(weiXinService.processMsg(msgRequest));
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @PostMapping("gzhMessagePush")
    @ApiOperation("公众号推送")
    public Result gzhMessagePush(TemplateDTO template){
        return messageService.messagePush(template);

    }

}

  

@Component
public class WxApiServiceImpl implements WxApiService {

    @Override
    public String processMsg(MsgRequest msgRequest)  throws Exception {
        String msgtype = msgRequest.getMsgType();// 接收到的消息类型
        String respXml = null;// 返回的内容;
        if (msgtype.equals("text")) {
            //文本消息,一般公众号接收到的都是此类型消息

        } else if (msgtype.equals("event")) {// 事件消息

            //用户订阅公众账号、点击菜单按钮的时候,会触发事件消息
            respXml = this.processEventMsg(msgRequest);

            // 其他消息类型,开发者自行处理
        } else if (msgtype.equals("image")) {// 图片消息

        } else if (msgtype.equals("location")) {// 地理位置消息

        }

        // 如果没有对应的消息,默认返回订阅消息;
        if (StringUtils.isEmpty(respXml)) {
            
            MsgText text = new MsgText();
            text.setContent("欢迎关注XXXX");
            return MsgXmlUtil.textToXml(WxMessageBuilder.getMsgResponseText(msgRequest, text));
        }
        return respXml;
    }

    // 处理事件消息
    @Override
    public String processEventMsg(MsgRequest msgRequest){
        try {
            String openId = msgRequest.getFromUserName();
            System.out.println("event:"+msgRequest.getEvent());
            if ("subscribe".equals(msgRequest.getEvent())) {// 关注
				/*====自己的业务====*/
                
                //发送消息
                MsgText text = new MsgText();
                text.setContent("欢迎关注XXXX");
                return MsgXmlUtil.textToXml(WxMessageBuilder.getMsgResponseText(msgRequest, text));
            }
            else if ("unsubscribe".equals(msgRequest.getEvent())) {// 取消关注
                msgResponseText.setContent("取消关注成功");
                return MsgXmlUtil.textToXml(msgResponseText);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

}
 

消息推送

  • 配置消息模板,获得模板id

  • 代码实现

@Service
@Slf4j
public class GzhMessageServiceImpl implements GzhMessageService {

    @Value("${gzh.wechat.appsecret}")
    private String secret;

    @Value("${gzh.wechat.appid}")
    private String appId;

    @Autowired
    private RedisService redisService;

    @Override
    public Result messagePush(TemplateDTO template) {

        //封装请求体
//        TemplateDTO template = new TemplateDTO("oHHSbxPyZ9qo8AmFV5CMHA5zoLpA","KSSsdMPEw-hySt17P-Qs1vjLlBmXxyXHxCgKKTbRKxw",null,
//                null,"您好,运行监测报告如下","延安医院机房5号服务器","2015-8-30 12:32:33","运行统计",
//                "今天总共传输医学影像603份,其中,成功601份,失败2份。","谢谢您及时跟踪系统的运行。");

        String errmsg = pull(template.toJSON());
        if("ok".equals(errmsg)){
            log.info("推送成功");
            return Result.ok();
        }else {
            log.error("推送失败");
            return Result.error("推送失败");
        }
    }

    @Override
    public String pull(String template){
        String token = redisService.getAccessToken();
        log.info("获取的token为:{}",token);
        if(StringUtils.isBlank(token)){
            log.error("推送公众号消息token为空:{}",template);
            return "fail";
        }

        String TEMPLATE_URL = String.format(WechatAPI.TEMPLATE_URL,token);
        log.info("获取的TEMPLATE_URL为:{}",TEMPLATE_URL);
        String resJson = HttpClientUtil.doTemplateMsgPost(TEMPLATE_URL, template);
        log.info("推送公众号消息结果:{}",resJson);
        JSONObject jsonObject = JSONObject.parseObject(resJson);
        String errmsg = jsonObject.getString("errmsg");
        return errmsg;
    }

}

TemplateDTO封装消息体

@Data
public class TemplateDTO {

    private TemplateDTO(){}

    /**
     *
     * @param toUser           消息接收人的公众号openId
     * @param templateId       发送的模板id
     * @param url              消息详情
     * @param miniprogramDTO   跳转到小程序设置
     * @param first            消息模板第一个参数
     * @param keyword1         消息模板keyword1
     * @param keyword2         消息模板keyword2
     * @param keyword3         消息模板keyword3
     * @param keyword4         消息模板keyword4
     * @param remark           消息模板备注
     */
    public TemplateDTO(String toUser, String templateId, String url, MiniprogramDTO miniprogramDTO,
                       String first,String keyword1,String keyword2,String keyword3,String keyword4,String remark){
        this.toUser = toUser;
        this.templateId = templateId;
        this.url = url;
        //this.topColor = topColor;
        this.miniprogramDTO = miniprogramDTO;
        List<TemplateParamDTO> templateParamList = new ArrayList<>();
        if(StringUtils.isNoneBlank(first)){
            TemplateParamDTO firstDTO = new TemplateParamDTO("first", first + "\\r\\n", "#DB1A1B");
            templateParamList.add(firstDTO);
        }
        if(StringUtils.isNoneBlank(keyword1)){
            TemplateParamDTO keyword1DTO = new TemplateParamDTO("keyword1", keyword1 + "\\r\\n", "#DB1A1B");
            templateParamList.add(keyword1DTO);
        }
        if(StringUtils.isNoneBlank(keyword2)){
            TemplateParamDTO keyword2DTO = new TemplateParamDTO("keyword2", keyword2 + "", "#DB1A1B");
            templateParamList.add(keyword2DTO);
        }
        if(StringUtils.isNoneBlank(keyword3)){
            TemplateParamDTO keyword3DTO = new TemplateParamDTO("keyword3", keyword3, "#DB1A1B");
            templateParamList.add(keyword3DTO);
        }
        if(StringUtils.isNoneBlank(keyword4)){
            TemplateParamDTO keyword4DTO = new TemplateParamDTO("keyword4", keyword4, "#DB1A1B");
            templateParamList.add(keyword4DTO);
        }
        if(StringUtils.isNoneBlank()){
            TemplateParamDTO remarkDTO = new TemplateParamDTO("remark", remark, "#DB1A1B");
            templateParamList.add(remarkDTO);
        }
        this.templateParamList = templateParamList;
    }

    // 消息接收方
    private String toUser;
    // 模板id
    private String templateId;
    // 模板消息详情链接
    private String url;
    // 消息顶部的颜色
    private String topColor;
    // 参数列表
    private List<TemplateParamDTO> templateParamList;
    //跳转小程序参数
    private MiniprogramDTO miniprogramDTO;

    public String toJSON() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("{");
        buffer.append(String.format("\"touser\":\"%s\"", this.toUser)).append(",");
        buffer.append(String.format("\"template_id\":\"%s\"", this.templateId)).append(",");
        if(StringUtils.isNoneBlank(this.url)){
            buffer.append(String.format("\"url\":\"%s\"", this.url)).append(",");
        }
        if(StringUtils.isNoneBlank(this.topColor)){
            buffer.append(String.format("\"topcolor\":\"%s\"", this.topColor)).append(",");
        }
        //拼接小程序的参数
        if(miniprogramDTO !=null){
            buffer.append("\"miniprogram\":{");
            buffer.append("\"appid\":\"");
            buffer.append(miniprogramDTO.getAppid()+"\",");
            buffer.append("\"path\":\"");
            buffer.append(miniprogramDTO.getPagepath());
            buffer.append("\"},");
        }
        buffer.append("\"data\":{");
        TemplateParamDTO param = null;
        for (int i = 0; i < this.templateParamList.size(); i++) {
            param = templateParamList.get(i);
            // 判断是否追加逗号
            if (i < this.templateParamList.size() - 1) {

                buffer.append(String.format("\"%s\": {\"value\":\"%s\",\"color\":\"%s\"},", param.getName(), param.getValue(), param.getColor()));
            } else {
                buffer.append(String.format("\"%s\": {\"value\":\"%s\",\"color\":\"%s\"}", param.getName(), param.getValue(), param.getColor()));
            }

        }
        buffer.append("}");
        buffer.append("}");
        return buffer.toString();
    }

}

  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值