企业微信如何简单实现定时发送文件到群:企业微信群机器人操作(Java代码实现)

  • Post author:
  • Post category:java

前言

不知道小伙伴们的公司组织架构通勤用的啥软件,我公司用的企业微信。然后业务销售部那边需要每天统计销售数据报表然后发在群里(我是开发,我不配在群里)。知道这个背景以后,产品给我们的需求是:直接统计数据按照业务那边的报表模板直接生成销售报表,然后定时每天晚上10点发送到各个门店的相关群(企业微信群)里。

效果

实现

第一步:肯定要先去看企业微信的开发文档啊

1、开发文档

群机器人配置说明 – 企业微信API

 2、稍微说一下我看文档后的理解

  • 群机器人作用:
  • 企业微信群机器人怎么发送消息:

 这里的意思是说:

        往群组推送文本消息,首先要知道这个群组的地址,而这个地址用在该群里的机器人webhook地址。地址知道以后,我们就能够访问它并向他发送消息。

怎么发送简单的文本消息:

根据文档提供的实例,我们知道这是一个post请求,参数为

{
    "msgtype": "text",
    "text": {
        "content": "hello world"
    }
}

msgtype: 消息类型 ;text: 文本 ;content: 内容

  • 接下来理解一下群机器人的webhook地址

https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa

看url能看得出来,怎么区分不同的群机器人,用url的参数key,key不同代表群机器人不同,只要在各个群组里添加对应的机器人,拿到key,我们就能根据key,发送文件到不同的企业微信群里了。

3、发送文件

根据前面的分析我们知道,有参数 msgtype 代表着消息类型,所以开发文档往下滑,找到文件类型

 发送文件参数:

{
    "msgtype": "file",
    "file": {
         "media_id": "3a8asd892asd8asd"
    }
}

media_id:文件id,通过文件上传接口获取

4、文件上传接口

参数file里的media_id,只能通过企业微信提供的文件上传接口获取

第二步:Java代码实现

 文档看完以后,我们就开始写代码,其实很简单,就post请求访问两个url,根据访问的顺序:

这里推荐 hutool工具,使用其封装的post方法,不用自己写啦

hutool: 🍬小而全的Java工具类库,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。​​​​​

public class QywxMessageConstant {

    /** 企业微信群上传文件url */
    public static final String UPLOAD_FILE_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media";
    /** 发送群消息url */
    public static final String SEND_MESSAGE_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send";

}
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * description 上传文件并推送到企业微信群
 */
public void sendFileToWeChatGroup(File file, String groupKey) throws ServiceException {
    // 上传文件
    String urlString = QywxMessageConstant.UPLOAD_FILE_URL + "?key=" + groupKey + "&type=file";
    HashMap<String, Object> sendMap = new HashMap<>();
    sendMap.put("file", file);
    String result = cn.hutool.http.HttpUtil.post(urlString, sendMap);
    JSONObject jsonObject = JSON.parseObject(result);
    Integer errcode = Integer.valueOf(jsonObject.get("errcode").toString());
    if (errcode.equals(0)) {
        // 推送消息
        String mediaid = (String) jsonObject.get("media_id");
        String sendUrl = QywxMessageConstant.SEND_MESSAGE_URL + "?key=" + groupKey;
        Map<String,Object> mediaMap = new HashMap<>();
        mediaMap.put("media_id",mediaid);
        Map<String,Object> msgMap = new HashMap<>();
        msgMap.put("msgtype","file");
        msgMap.put("file",mediaMap);
        cn.hutool.http.HttpUtil.post(sendUrl, JSON.toJSONString(msgMap));
    } else {
        throw new ServiceException("企业微信群上传文件失败");
    }
}

定时任务(springboot 注解实现)

/**
 * 定时任务
 *
 * @author Administrator
 */
@Component
@Slf4j
@ConditionalOnProperty(prefix = "spring.profiles", name = "active", havingValue = "prod")
public class StatisticsTask {
    @Autowired
    private SalesStatisticsService salesStatisticsService;

    /**
     * 每天22点发送每日销售的数据
     *
     * @throws Exception
     */
    @Scheduled(cron = "0 0 22 * * ? ")
    public void send() throws Exception {
        try {
            log.info("开始执行:发送每日销售任务");
            salesStatisticsService.exportExcel();
            log.info("执行完成:每日销售任务");
        } catch (Exception e) {
            log.error("执行异常:每日销售任务");
            e.printStackTrace();
        }
    }

}

补充: EasyExcel 生成文件 File

TestExportController 

package com.xxx.crm.controller;

import cn.hutool.core.date.DateUtil;
import com.XX.XX.base.util.DateTimeUtils;
import com.XX.XX.service.export.TestExportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Date;

/**
 * 导出报表测试
 */
@RestController
@RequestMapping("/exportTest")
public class TestExportController {

    @Autowired
    TestExportService testExportService;

    // 给管理后台的导出
    @RequestMapping("/exportTest2")
    @ResponseBody
    public void exportTest2(HttpServletRequest request, HttpServletResponse response){

        try {
            // 中文文件名必须使用此句话
            String filename = new String(String.format("%s 测试报表.xlsx", "2022-05-06").getBytes(), StandardCharsets.ISO_8859_1);
            response.setContentType("application/json;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + filename);
            OutputStream out = new BufferedOutputStream(response.getOutputStream());
            // 导出文件
            testExportService.export(out,filename);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    // 发送到企业微信群的导出
    @RequestMapping("/exportTest3")
    @ResponseBody
    public void exportTest3(HttpServletRequest request, HttpServletResponse response){

        try {
            String formatTDate = DateUtil.format(new Date(), DateTimeUtils.y4M2d2);
            // 表数据
            String fileName = "测试报表_" + formatTDate + "_每日销售数据" + ".xlsx";
            OutputStream out = new ByteArrayOutputStream();
            testExportService.exportToQYWX(testExportService.exportByCustom(out,fileName),fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

TestExportServiceImpl:

    // 调用接口即可获取文件
    @Override
    public OutputStream export(OutputStream outputStream, String fileName) throws Exception {
        try {
            // 示例数据
            List<String> datalist= ListUtils.newArrayList();
            for (int i = 0; i < 10; i++) {
                String data = "ceshi" + i;
                datalist.add(data);
            }
            // 把数据写入流里
            EasyExcel.write(outputStream)
                    .sheet(fileName.split("\\.")[0])
                    .doWrite(datalist);
            outputStream.close();
            return outputStream;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    // 把文件暂时存在本地,然后发送到企业微信群
    @Override
    public void exportToQYWX(OutputStream outputStream, String fileName) throws Exception {
        try {
            // 输出流转输入流 outputStream = new ByteArrayOutputStream();
            ByteArrayInputStream swapStream = new ByteArrayInputStream(((ByteArrayOutputStream)outputStream).toByteArray());
            InputStream inputStream = new BufferedInputStream(swapStream);
            // 将流转成成文件
            File file = weChatConfig.inputStreamToFile(inputStream, fileName);
            // 企业微信发送报表
            sendFileToWeChatGroup(file, 'groupKey');
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;

import java.io.File;

/**
     * description 将流转换保存成文件
     */
    public File inputStreamToFile(InputStream inputStream, String filename) {
        String uploadFileSavePath = "/tmp/exportData/";
        String savePath = uploadFileSavePath + DateUtil.format(new Date(), "yyyyMMdd") + "/";
        File savePathFile = new File(savePath);
        if (!savePathFile.exists()) {
            savePathFile.mkdirs();
        }
        return FileUtil.writeFromStream(inputStream, savePath + filename);
    }


版权声明:本文为weixin_43991241原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。