企业微信图文消息推送,详细且附上代码,和常见的错误提示,not allow to access from your ip,this app has not bind any miniprogram

12月份接到一个年度总结的项目。要求总结报告通过企业微信推送给用户,这时候就要用到企业微信的接口了,这时候就要注意了,

1,首先确认Corpid和Corpsecret,AgentId,

企业微信测试要认证,我这边是用户提供的所以不方便透露

2,消息推送有很多种,我接触到的有三种,图文推送,文本推送,其中图文推送有点击图文直接进入页面的,还有一种是点击图片有一篇你可以自定义的文章,文章下有阅读原文才是你程序的页面链接

这个是点击就能进去的图文消息模式

{
   "touser" : "UserID1|UserID2|UserID3",
   "toparty" : "PartyID1 | PartyID2",
   "totag" : "TagID1 | TagID2",
   "msgtype" : "news",
   "agentid" : 1,
   "news" : {
       "articles" : [
           {
               "title" : "中秋节礼品领取",
               "description" : "今年中秋节公司有豪礼相送",
               "url" : "URL",
               "picurl" : "http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png", 
               "appid": "",
               "pagepath": ""
           }
        ]
   },
   "enable_id_trans": 0,
   "enable_duplicate_check": 0,
   "duplicate_check_interval": 1800
}

这些是传入参数,url可以直接填写程序的入口,appid可以不填写,图片路径我之前使用本地路径是不可以的,选择网络路径或者项目路径都行,应该是外网要能访问的,至于外网如何访问你的,你可以用内网穿透natapp来测试

注意注意注意  !!!!看官方文档时仔细了,touser要认真填,我当时填的是@all,结果所有人都能收到,没几分钟就挨叼了

3,消息推送 代码展示
public static String sendQyAppMessage(String content, List<String> empCodes, String imageUrl, String media_id) {
        //获取企业微信的access_token
        String token = getQyAccessToken(false);
//        String token = TOKEN;
        System.out.println(token);
        StringBuilder stringBuilder = new StringBuilder();
        //遍历empCodes,拼接字符串
        for (String empCode : empCodes) {
            stringBuilder.append(empCode).append("|");
        }
        //删除最后一个|
        stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        String toUser = stringBuilder.toString();

        //TODO 推送消息的内容
        String requestBody = "{ \"touser\": \"%s\"," +
                " \"toparty\": \"\", " +
                "\"totag\": \"\", " +
                "\"msgtype\": \"news\", " +
                "\"agentid\": %s, " +
                "\"news\": { " +
                "\"articles\":[ " +
                "{ \"title\": \"年度工作数字报告\"," +
                " \"description\": \"用数字报告解锁你的独家故事\"," +
                " \"url\": \"https://nb.sugh.net/toindex\", " +
                "\"picurl\": \"%s\", " +
                "\"appid\": \"\", " +
                "\"pagepath\": \"\" } ] }," +
                "\"enable_id_trans\": 0," +
                " \"enable_duplicate_check\": 0," +
                " \"duplicate_check_interval\": 1800 }";
        requestBody = String.format(requestBody, toUser, ConfKit.entAgentId, imageUrl);
        System.out.println(requestBody);

        String url = SEND_APP_MESSAGE_URL.replace("ACCESS_TOKEN", token);
        // 要发送的 JSON 请求体
        try {
            HttpClient httpClient = HttpClients.createDefault();

            // 创建 POST 请求
            HttpPost httpPost = new HttpPost(url);

            // 设置请求头部信息
            httpPost.setHeader("Content-Type", "application/json");

            // 设置请求体
            StringEntity stringEntity = new StringEntity(requestBody, StandardCharsets.UTF_8);
            httpPost.setEntity(stringEntity);

            // 发送请求并获取响应
            HttpResponse response = httpClient.execute(httpPost);

            // 处理响应
            HttpEntity responseEntity = response.getEntity();
            BufferedReader reader = new BufferedReader(new InputStreamReader(responseEntity.getContent()));
            String line;
            StringBuilder responseBuilder = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                responseBuilder.append(line);
            }
            // 输出响应结果
            System.out.println("Response: " + responseBuilder.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return "success";
    }

这里我的推送对象不固定,所以传入的要自己用|来分割,各位可以根据业务需求可自己改动

这代码中需要的有access_token ,agentId, 前者需要获取,后者可直接用

获取token的代码为下:

  public static String getQyAccessToken(boolean forceGetNew) {
        //强制获取新的AccessToken
        if (forceGetNew) {
            if (qyAccessTokenEntity == null || qyAccessTokenEntity.getAccessToken() == null) {
                qyAccessTokenEntity = new AccessTokenEntity();
                getQyAccessTokenFromWXServer(qyAccessTokenEntity);
            } else {
                getQyAccessTokenFromWXServer(qyAccessTokenEntity);
            }
            return qyAccessTokenEntity.getAccessToken();
        }

        if (qyAccessTokenEntity == null || qyAccessTokenEntity.getAccessToken() == null) {
//            LogUtils.audit("qyAccessTokenEntity is null ||accessToken is null 重新获取");
            qyAccessTokenEntity = new AccessTokenEntity();
            getQyAccessTokenFromWXServer(qyAccessTokenEntity);
        } else {
            if (qyAccessTokenEntity.isEnabled()) {
//                LogUtils.audit("企业accessToken:存活时间:" + qyAccessTokenEntity.getLeaveTime() + "。最大生命值:" + qyAccessTokenEntity.getExpiresIn());
                return qyAccessTokenEntity.getAccessToken();
            } else {
//                LogUtils.audit("企业accessToken:过期重新获取");
                getQyAccessTokenFromWXServer(qyAccessTokenEntity);
            }
        }
        return qyAccessTokenEntity.getAccessToken();
    }

4,消息推送(mpnews) 

{
   "touser" : "UserID1|UserID2|UserID3",
   "toparty" : "PartyID1 | PartyID2",
   "totag": "TagID1 | TagID2",
   "msgtype" : "mpnews",
   "agentid" : 1,
   "mpnews" : {
       "articles":[
           {
               "title": "Title", 
               "thumb_media_id": "MEDIA_ID",
               "author": "Author",
               "content_source_url": "URL",
               "content": "Content",
               "digest": "Digest description"
            }
       ]
   },
   "safe":0,
   "enable_id_trans": 0,
   "enable_duplicate_check": 0,
   "duplicate_check_interval": 1800
}
 

这是传入参数, thumb_media_id需要临时获取,每个thumb_media_id都只能用三天,所以我当时用一次就推送一次

   public static String uploadPic(String filePath, String type) throws Exception {
        //获得你的access_token
        String redisToken = getQyAccessToken(false);
        //地址https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
        String urlStr = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";
        String replaceUrl = urlStr.replace("ACCESS_TOKEN", redisToken).replace("TYPE", type);
        //返回结果
        String result = null;
        File file = new File(filePath);
        if (!file.exists() || !file.isFile()) {
            throw new IOException("文件不存在");
        }
        URL url = new URL(replaceUrl);
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.setRequestMethod("POST");//以POST方式提交表单
        conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setUseCaches(false);//POST方式不能使用缓存
        //设置请求头信息
        conn.setRequestProperty("Connection", "Keep-Alive");
        conn.setRequestProperty("Charset", "UTF-8");
        //设置边界
        String BOUNDARY = "----------" + System.currentTimeMillis();
        conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
        //请求正文信息
        //第一部分
        StringBuilder sb = new StringBuilder();
        sb.append("--");//必须多两条道
        sb.append(BOUNDARY);
        sb.append("\r\n");
        sb.append("Content-Disposition: form-data;name=\"media\"; filename=\"" + file.getName() + "\"\r\n");
        sb.append("Content-Type:application/octet-stream\r\n\r\n");
        System.out.println("sb:" + sb);

        //获得输出流
        OutputStream out = new DataOutputStream(conn.getOutputStream());
        //输出表头
        out.write(sb.toString().getBytes("UTF-8"));
        //文件正文部分
        //把文件以流的方式 推送道URL中
        DataInputStream din = new DataInputStream(new FileInputStream(file));
        int bytes = 0;
        byte[] buffer = new byte[1024];
        while ((bytes = din.read(buffer)) != -1) {
            out.write(buffer, 0, bytes);
        }
        din.close();
        //结尾部分
        byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("UTF-8");//定义数据最后分割线
        out.write(foot);
        out.flush();
        out.close();
        if (HttpsURLConnection.HTTP_OK == conn.getResponseCode()) {

            StringBuffer strbuffer = null;
            BufferedReader reader = null;
            try {
                strbuffer = new StringBuffer();
                reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String lineString = null;
                while ((lineString = reader.readLine()) != null) {
                    strbuffer.append(lineString);

                }
                if (result == null) {
                    result = strbuffer.toString();
                    log.debug("result:" + result);
                }
            } catch (IOException e) {
                System.err.println("发送POST请求出现异常!" + e);
            } finally {
                if (reader != null) {
                    reader.close();
                }
            }
        }
        return result;
    }

同样需要token和上传的文件类型,如果是图片就填image就行了,图片路径各位根据情况自己填写

这样就会返回 

 Map<String, String> map = JSONUtil.toBean(image, Map.class);
 media_id = map.get("media_id");

来接收,随后传入

public static String sendQyAppMessage1(String content, List<String> empCodes, String media_id) {
        String token = getQyAccessToken(false);
//        String token = TOKEN;
        System.out.println(token);
        StringBuilder stringBuilder = new StringBuilder();
        for (String empCode : empCodes) {
            stringBuilder.append(empCode).append("|");
        }
        //删除最后一个|
        stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        String toUser = stringBuilder.toString();

        //TODO 推送消息的内容
        String requestBody = "{ \"touser\": \"%s\"," +
                " \"toparty\": \"\", " +
                "\"totag\": \"\", " +
                "\"msgtype\": \"mpnews\", " +
                "\"agentid\": %s, " +
                "\"mpnews\": { " +
                "\"articles\":[ " +
                "{ \"title\": \"年度工作数字报告\"," +
                " \"thumb_media_id\": \"%s\"," +
                " \"author\": \"sihai\", " +
                "\"content_source_url\": \"https://nb.sugh.net/toindex\", " +
                "\"content\": \"Content\", " +
                "\"digest\": \"用数字报告解锁你的独家故事!\" } ] }," +
                " \"safe\": 2, " +
                "\"enable_id_trans\": 0," +
                " \"enable_duplicate_check\": 0," +
                " \"duplicate_check_interval\": 1800 }";
        requestBody = String.format(requestBody, toUser, ConfKit.entAgentId, media_id);
        System.out.println(requestBody);

        String url = SEND_APP_MESSAGE_URL.replace("ACCESS_TOKEN", token);
/*
        String result = HttpKit.post(url, format);
        System.out.println(result);
        return result;

        String url = "http://example.com/api/endpoint"; // 替换为你的目标 URL
*/
        // 要发送的 JSON 请求体
        try {
            HttpClient httpClient = HttpClients.createDefault();

            // 创建 POST 请求
            HttpPost httpPost = new HttpPost(url);

            // 设置请求头部信息
            httpPost.setHeader("Content-Type", "application/json");

            // 设置请求体
            StringEntity stringEntity = new StringEntity(requestBody, StandardCharsets.UTF_8);
            httpPost.setEntity(stringEntity);

            // 发送请求并获取响应
            HttpResponse response = httpClient.execute(httpPost);

            // 处理响应
            HttpEntity responseEntity = response.getEntity();
            BufferedReader reader = new BufferedReader(new InputStreamReader(responseEntity.getContent()));
            String line;
            StringBuilder responseBuilder = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                responseBuilder.append(line);
            }
            // 输出响应结果
            System.out.println("Response: " + responseBuilder.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return "success";
    }

接下展示效果

5.常见错误 

检擦获取的access_token是否是你这个应用的,检查

entCorpID

和entSecret

这个是我推送消息时填写了appid,我去掉后就行了

查看微信配置的可信域ip和你发送这个请求的ip是否一致 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值