微信公众平台--客服接口(发送消息)

目录

 

前言:

步骤:

讲解部分

代码部分

(1) 控制层

(2) 业务逻辑层

(3) 发送文本消息

 (4) 图片消息

(5) 菜单消息 

 (6)上传文件素材的代码

 (7) 微信公众平台参数类

(8)发送POST请求的代码

(8)效果图


前言:

 小伙伴们如果有什么问题,欢迎评论区留言。

步骤:

讲解部分

(1) 我今天要做的是调用微信公众平台-客服接口发送消息(文本消息,菜单消息,图片消息),其他的读者可以在此基础上自行发挥。:官方文档地址

(2)一些参数。

  1.    AppId  和AppSecret用来获取AccessToken   地址
  2.   需要一个OpenId   (在微信公众平台中每个用户的唯一标识)。之所以用到这个是因为我们要告诉微信公众平台我们需  要  将该消息发送给哪个用户

代码部分

  • (1) 控制层

 @ApiOperation(value = "1.7 客服接口-发送消息")
    @GetMapping(value = "/sendCustomerProviderNews")
    public void sendCustomerProviderNews() {
        //1.客服接口-发送文本消息
//        customerProviderService.sendCustomerProviderNews("1");
        //2.发送图片消息
        customerProviderService.sendCustomerProviderNews("2");
        //7.发送菜单消息
//        customerProviderService.sendCustomerProviderNews("7");


    }
  • (2) 业务逻辑层

package com.bos.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.bos.common.ResultData;
import com.bos.data.model.weixin.ServiceProvider.*;
import com.bos.service.CustomerProviderService;
import com.bos.util.QiYeWeiUtil;
import com.bos.util.SendRequest;
import com.bos.util.WeiXinParamesUtil;
import com.google.gson.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author tanghh
 * @Date 2020/2/14 10:32
 */
@Service
public class CustomerProviderServiceImpl implements CustomerProviderService {
    private Logger logger = LoggerFactory.getLogger(CustomerProviderServiceImpl.class);

    /**
     * 客户接口-发送消息
     * https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Service_Center_messages.html#7
     * @param type
     * @return
     */
    @Override
    public void sendCustomerProviderNews(String type) {
        try{
            String toUser ="用户OpenID";
            String accessToken = WeiXinParamesUtil.getAccessToken2("weixin");
            String url = WeiXinParamesUtil.sendCustomerMsgUrl;
            url = url.replace("ACCESS_TOKEN",accessToken);
            //普通的文本消息
            if(type.equals("1")){
              ServiceTextMessage serviceTextMessage = new ServiceTextMessage();
              serviceTextMessage.setTouser(toUser);

              ServiceText text = new ServiceText();
              text.setContent("中国加油");
              serviceTextMessage.setText(text);

              String jsonStr = JSONObject.toJSONString(serviceTextMessage);
              JSONObject jsonObject = SendRequest.sendPost(url,jsonStr);
            }else if(type.equals("2")){
                //发送图片消息

                //获取图片的media_id
                //上传到微信公众平台服务器上
                //1.创建本地文件
                File file = new File("C://uploadFile/QiWeiFiles/bf9d099ace3cbfe8ce37d7c02687c986_7740.png");
                //2.拼接请求url
                String uploadMaterialToWeiUrl = WeiXinParamesUtil.uploadMaterialToWeiUrl.replace("ACCESS_TOKEN", accessToken)
                        .replace("TYPE", "image");
                //3.调用接口,发送请求,上传文件到微信服务器
                String result = QiYeWeiUtil.httpRequest(uploadMaterialToWeiUrl, file);
                //4.json字符串转对象:解析返回值,json反序列化
                result = result.replaceAll("[\\\\]", "");
                JSONObject resultJSON = JSONObject.parseObject(result);

                String media_id = (String) resultJSON.get("media_id");

                ServiceImageMessage serviceImageMessage = new ServiceImageMessage();
                serviceImageMessage.setTouser(toUser);

                ServiceImage serviceImage = new ServiceImage();
                serviceImage.setMedia_id(media_id);

                serviceImageMessage.setImage(serviceImage);

                String jsonStr = JSONObject.toJSONString(serviceImageMessage);
              JSONObject jsonObject = SendRequest.sendPost(url,jsonStr);
            }else if(type.equals("3")){
                //发送语言消息

            }else if(type.equals("4")){
                //发送视频消息

            }else if(type.equals("5")){
                //发送音乐消息
            }else if(type.equals("6")){
                //发送图文消息

            }else if(type.equals("7")){
                //发送菜单消息
                ServiceMenuMessage serviceMenuMessage = new ServiceMenuMessage();
                serviceMenuMessage.setTouser(toUser);

                ServiceMenu serviceMenu = new ServiceMenu();
                serviceMenu.setHead_content("您对本次服务是否满意呢?");

                List<ServiceMenuContent>  list = new ArrayList<>();
                ServiceMenuContent content1 = new ServiceMenuContent();
                content1.setId(101);
                content1.setContent("满意");
                ServiceMenuContent content2 = new ServiceMenuContent();
                content2.setId(101);
                content2.setContent("不满意");
                list.add(content1);
                list.add(content2);
                serviceMenu.setList(list);
                serviceMenu.setTail_content("欢迎再次光临");

                serviceMenuMessage.setMsgmenu(serviceMenu);

                String jsonStr = JSONObject.toJSONString(serviceMenuMessage);
                JSONObject jsonObject = SendRequest.sendPost(url,jsonStr);
            }else if(type.equals("8")){
              
            }
        }catch (Exception e){
         logger.error("客户接口发送消息失败",e);
        }
    }
}
  • (3) 发送文本消息

ServiceTextMessage

package com.bos.data.model.weixin.ServiceProvider;

import lombok.Data;

/**
 * @Author tanghh
 * @Date 2020/2/14 10:39
 */
@Data
public class ServiceTextMessage {
    /**
     * 发送方用户名
     */
    private String touser;
    /**
     * 发送消息类型
     */
    private String msgtype="text";
    /**
     * 文本
     */
    private ServiceText text;

}

ServiceText

 

package com.bos.data.model.weixin.ServiceProvider;

import lombok.Data;

/**
 * @Author tanghh
 * @Date 2020/2/14 10:41
 */
@Data
public class ServiceText {
    /**
     * 发送消息内容
     */
    private String content;
}

 

  •  (4) 图片消息

ServiceImageMessage

package com.bos.data.model.weixin.ServiceProvider;

import lombok.Data;

/**
 * @Author tanghh
 * @Date 2020/2/14 16:03
 */
@Data
public class ServiceImageMessage {
    private String touser;
    private String msgtype="image";
    private ServiceImage image;
}

ServiceImage

package com.bos.data.model.weixin.ServiceProvider;

import lombok.Data;

/**
 * @Author tanghh
 * @Date 2020/2/14 16:04
 */
@Data
public class ServiceImage {
    private String media_id;
}

 

  • (5) 菜单消息 

ServiceMenuMessage

package com.bos.data.model.weixin.ServiceProvider;

import lombok.Data;

/**
 * @Author tanghh
 * @Date 2020/2/14 11:45
 */
@Data
public class ServiceMenuMessage {
    private String touser;
    private String msgtype="msgmenu";
    private ServiceMenu msgmenu;
}

 

ServiceMenu

package com.bos.data.model.weixin.ServiceProvider;

import lombok.Data;

import java.util.List;

/**
 * @Author tanghh
 * @Date 2020/2/14 11:46
 */
@Data
public class ServiceMenu {
    private String head_content;
    private List<ServiceMenuContent> list;
    private String tail_content;
}

 ServiceMenuContent

package com.bos.data.model.weixin.ServiceProvider;

import lombok.Data;

/**
 * @Author tanghh
 * @Date 2020/2/14 11:47
 */
@Data
public class ServiceMenuContent {
    private Integer id;
    private String content;
}
  •  (6)上传文件素材的代码

package com.bos.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bos.data.model.weixin.send.SendBaseMessage;
import com.bos.qiWechat.AesException;
import com.bos.qiWechat.WXBizMsgCrypt;
import com.bos.wechat.MyX509TrustManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * @author tanghh
 * @Date: 2019/4/17
 */
public class QiYeWeiUtil {
    private static  Logger  logger= LoggerFactory.getLogger(QiYeWeiUtil.class);
    // 微信加密签名
    private  String msg_signature;
    // 时间戳
    private  String timestamp;
    // 随机数
    private  String nonce;
    /**
     * 1.企业微信上传素材的请求方法
     * @param
     * @return
     */
    public static String httpRequest(String requestUrl, File file) {
        StringBuffer buffer = new StringBuffer();

        try{
            //1.建立连接
            URL url = new URL(requestUrl);
            //打开链接
            HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();

            //1.1输入输出设置
            httpUrlConn.setDoInput(true);
            httpUrlConn.setDoOutput(true);
            // post方式不能使用缓存
            httpUrlConn.setUseCaches(false);
            //1.2设置请求头信息
            httpUrlConn.setRequestProperty("Connection", "Keep-Alive");
            httpUrlConn.setRequestProperty("Charset", "UTF-8");
            //1.3设置边界
            String BOUNDARY = "----------" + System.currentTimeMillis();
            httpUrlConn.setRequestProperty("Content-Type","multipart/form-data; boundary="+ BOUNDARY);

            // 请求正文信息
            // 第一部分:
            //2.将文件头输出到微信服务器
            StringBuilder sb = new StringBuilder();
            // 必须多两道线
            sb.append("--");
            sb.append(BOUNDARY);
            sb.append("\r\n");
            sb.append("Content-Disposition: form-data;name=\"media\";filelength=\"" + file.length()
                    + "\";filename=\""+ file.getName() + "\"\r\n");
            sb.append("Content-Type:application/octet-stream\r\n\r\n");
            byte[] head = sb.toString().getBytes("utf-8");
            // 获得输出流
            OutputStream outputStream = new DataOutputStream(httpUrlConn.getOutputStream());
            // 将表头写入输出流中:输出表头
            outputStream.write(head);

            //3.将文件正文部分输出到微信服务器
            // 把文件以流文件的方式 写入到微信服务器中
            DataInputStream in = new DataInputStream(new FileInputStream(file));
            int bytes = 0;
            byte[] bufferOut = new byte[1024];
            while ((bytes = in.read(bufferOut)) != -1) {
                outputStream.write(bufferOut, 0, bytes);
            }
            in.close();
            //4.将结尾部分输出到微信服务器
            // 定义最后数据分隔线
            byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");
            outputStream.write(foot);
            outputStream.flush();
            outputStream.close();


            //5.将微信服务器返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }

            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();


        } catch (IOException e) {
            System.out.println("发送POST请求出现异常!" + e);
            e.printStackTrace();
        }
        return buffer.toString();
    }

    /**
     * 2.发送https请求之获取临时素材
     * @param requestUrl
     * @param savePath  文件的保存路径,此时还缺一个扩展名
     * @return
     * @throws Exception
     */
    public static File getFile(String requestUrl,String savePath) throws Exception {
        //String path=System.getProperty("user.dir")+"/img//1.png";
        // 创建SSLContext对象,并使用我们指定的信任管理器初始化
        TrustManager[] tm = { new MyX509TrustManager() };
        SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
        sslContext.init(null, tm, new java.security.SecureRandom());
        // 从上述SSLContext对象中得到SSLSocketFactory对象
        SSLSocketFactory ssf = sslContext.getSocketFactory();

        URL url = new URL(requestUrl);
        HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
        httpUrlConn.setSSLSocketFactory(ssf);

        httpUrlConn.setDoOutput(true);
        httpUrlConn.setDoInput(true);
        httpUrlConn.setUseCaches(false);
        // 设置请求方式(GET/POST)
        httpUrlConn.setRequestMethod("GET");

        httpUrlConn.connect();

        //获取文件扩展名
        String ext=getExt(httpUrlConn.getContentType());
        savePath=savePath+ext;
        System.out.println("savePath"+savePath);
        //下载文件到f文件
        File file = new File(savePath);


        // 获取微信返回的输入流
        InputStream in = httpUrlConn.getInputStream();

        //输出流,将微信返回的输入流内容写到文件中
        FileOutputStream out = new FileOutputStream(file);

        int length=100*1024;
        //存储文件内容
        byte[] byteBuffer = new byte[length];

        int byteread =0;
        int bytesum=0;
        //字节数 文件大小
        while (( byteread=in.read(byteBuffer)) != -1) {
            bytesum += byteread;
            out.write(byteBuffer,0,byteread);

        }
        System.out.println("bytesum: "+bytesum);

        in.close();
        // 释放资源
        out.close();
        in = null;
        out=null;

        httpUrlConn.disconnect();


        return file;
    }

    private static String getExt(String contentType){
        if("image/jpeg".equals(contentType)){
            return ".jpg";
        }else if("image/png".equals(contentType)){
            return ".png";
        }else if("image/gif".equals(contentType)){
            return ".gif";
        }

        return null;
    }

    /**
     * @param accessToken
     * @param message     void
     * @desc :0.公共方法:发送消息给企业微信
     */
    public static void sendMessage(String accessToken, SendBaseMessage message) {
        //1.获取请求的url
        String sendMessage_url = QiWeiXinParamesUtil.sendMessage_url.replace("ACCESS_TOKEN", accessToken);
        String json = JSON.toJSONString(message);
        //2.发送消息:调用业务类,发送消息
        JSONObject jsonObject = SendRequest.sendPost(sendMessage_url, json);
        //4.错误消息处理
        if (null != jsonObject) {
            if (0 != jsonObject.getIntValue("errcode")) {
                logger.error("发送消息失败 errcode:{} errmsg:{}", jsonObject.getIntValue("errcode"), jsonObject.getString("errmsg"));
            }
        }
    }


    /**
     * @param request
     * @return String   消息明文
     * @desc :2.从request中获取消息明文
     */
    public String getDecryptMsg(HttpServletRequest request) throws IOException {
        // 密文,对应POST请求的数据
        String postData = "";
        // 明文,解密之后的结果
        String result = "";
        // 微信加密签名
        this.msg_signature = request.getParameter("msg_signature");
        // 时间戳
        this.timestamp = request.getParameter("timestamp");
        // 随机数
        this.nonce = request.getParameter("nonce");

        try {
            //1.获取加密的请求消息:使用输入流获得加密请求消息postData
            ServletInputStream in = request.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            //作为输出字符串的临时串,用于判断是否读取完毕
            String tempStr = "";
            while (null != (tempStr = reader.readLine())) {
                postData += tempStr;
            }

            //2.获取消息明文:对加密的请求消息进行解密获得明文
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(QiWeiXinParamesUtil.token, QiWeiXinParamesUtil.encodingAESKey, QiWeiXinParamesUtil.corpId);
            result = wxcpt.DecryptMsg(msg_signature, timestamp, nonce, postData);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (AesException e) {
            e.printStackTrace();
        }

        return result;
    }

}
  •  (7) 微信公众平台参数类

package com.bos.util;

import com.alibaba.fastjson.JSONObject;
import com.bos.common.CommenUtil;
import com.bos.data.model.WeiUserInfoModel;

/**
 * 微信公众平台的参数
 * @param
 * @return
 */
public class WeiXinParamesUtil {
    /**
     * 获取微信公众平台accessToken
     * @param
     * @return
     */
    public static String getWeiAccessToken ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";

    public static String getUserInfoList = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
    public static String getUserList = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID";
    public static String updateUserRemark = "https://api.weixin.qq.com/cgi-bin/user/info/updateremark?access_token=ACCESS_TOKEN";
    public static String open_access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={appid}&secret={secret}&code={code}&grant_type=authorization_code";
    /**
     * 客户接口发送消息
     * @param
     * @return
     */
    public static String sendCustomerMsgUrl="https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN";
    /**
     * 上传临时文件素材到微信服务器上
     * @param
     * @return
     */
    public static String uploadMaterialToWeiUrl="https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";

    /**
     * 从微信服务器上下载临时文件素材
     * @param
     * @return
     */
    public static String downloadMaterialFromWeiUrl="https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";

    /**
     * 获取access_token的接口地址(GET) 限200(次/天)
     * @param
     * @return
     */
    public static String access_token_url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpId}&corpsecret={corpsecret}";



    public static String open_id = "gh_b920df4d06d0";
    /**
     * 微信扫码之后获取用户基本信息的地址
     * @param
     * @return
     */
    public static String getuserinfo_url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
    /**
     * 发送消息给微信公众平台的url
     * @param
     * @return
     */
    public static  String sendMessageToWei_url="https://api.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN";

    /**
     * 消息管理模块的成员类型
     * @param
     * @return
     */
    public static String QI_OUT_LINKMAN="企业微信外部联系人";
    public static String QI_INE_MEMBER="企业微信成员";
    public static String WEI_MEMBER="微信公众号";


//------------微信公众平台的参数
    /**
     * appId
     * @param
     * @return
     */
    public static String APPID;
    /**
     * secret
     * @param
     * @return
     */
    public static String SECRET;

    //----------------微信开放平台的参数
    /**
     * openAppid
     * @param
     * @return
     */
    public static String OPENAPPID;
    /**
     * appSecret
     * @param
     * @return
     */
    public static String OPENSECRET;


    /**
     * 回调地址  redirect_uri
     * @param
     * @return
     */
    public static String REDIRECT_URI;
    /**
     * scope
     * @param
     * @return
     */
    public static String SCOPE;
    /**
     * 模板id
     * @param
     * @return
     */
    public static String TEMPLATEID;





    static {
       
            //正式的服务号参数

            APPID = "你的APPID";
            SECRET = "你的APPSecret";
            SCOPE = "snsapi_userinfo";
            REDIRECT_URI = "snsapi_userinfo";
        
    }

    /**
     * 获取微信公众平台的access_token
     * @param type
     * @return
     */
    public static String getAccessToken(String type) {
        String url = "";
        if ("users".equals(type)) {
            url = getWeiAccessToken.replace("APPID", WeiXinParamesUtil.APPID).replace("APPSECRET", WeiXinParamesUtil.SECRET);
//            url = getWeiAccessToken.replace("APPID", "wxd842e30025df0f97").replace("APPSECRET", "349459f58dbf19a71f7f58c67f2eea3d");
        }else if("customerService".equals(type)){
            url = getWeiAccessToken.replace("APPID", WeiXinParamesUtil.APPID).replace("APPSECRET", WeiXinParamesUtil.SECRET);
        }
        JSONObject departmentJson = SendRequest.sendGet2(url);
        return departmentJson.getString("access_token");
    }

    /**
     * 获取微信公众平台的access_token
     * @param type
     * @return
     */
    public static String getAccessToken2(String type) {
        String url = "";
        if ("weixin".equals(type)) {
            url = getWeiAccessToken.replace("APPID", WeiXinParamesUtil.APPID).replace("APPSECRET", WeiXinParamesUtil.SECRET);
        }
        JSONObject departmentJson = SendRequest.sendGet2(url);
        return departmentJson.getString("access_token");
    }

}
  • (8)发送POST请求的代码

// 发送post请求(返回json)
    public static JSONObject sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        JSONObject jsonObject = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
//            conn.addRequestProperty("Cookie", "stay_login=1 smid=DumpWzWQSaLmKlFY1PgAtURdV_u3W3beoei96zsXkdSABwjVCRrnnNBsnH1wGWI0-VIflgvMaZAfli9H2NGtJg id=EtEWf1XZRLIwk1770NZN047804");//设置获取的cookie
            // 获取URLConnection对象对应的输出流(设置请求编码为UTF-8)
            out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "UTF-8"));
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 获取请求返回数据(设置返回数据编码为UTF-8)
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
            jsonObject = JSONObject.parseObject(result);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        return jsonObject;
    }

 

  • (8)效果图

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值