检测微信和企业微信api的ip变动

        如果服务器对进出的ip有限制,则需要将相应的ip添加到白名单中。调用公众号或小程序(对应域名是api.weixin.qq.com)、微信支付(对应域名是api.mch.weixin.qq.com)、企业微信(对应域名是qyapi.weixin.qq.com)的api时就需要检测ip可能发生变动之后发送通知。

        本示例是发送通知到企业微信群聊天机器人。当然也可以使用发送公众号模板消息、短信等。

pom文件
<!-- https://mvnrepository.com/artifact/com.github.binarywang/wx-java -->
        <dependency>
            <groupId>com.github.binarywang</groupId>
            <artifactId>weixin-java-mp</artifactId>
            <version>4.5.0</version>
        </dependency>
        <dependency>
            <groupId>com.github.binarywang</groupId>
            <artifactId>weixin-java-cp</artifactId>
            <version>4.5.0</version>
        </dependency>
        <dependency>
            <groupId>com.github.binarywang</groupId>
            <artifactId>weixin-java-miniapp</artifactId>
            <version>4.5.0</version>
        </dependency>
        <!--https://github.com/redisson/redisson-->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.14.0</version>
        </dependency>
定义微信和企业微信bean
@Bean("wxService")
@ConditionalOnClass(RedissonClient.class)
public WxMaService newWxService(RedissonClient redissonClient) {
    String keyPrefix = ""; // 缓存的前缀
    String appid = ""; // 微信app id
    String appSecret = ""; // 微信app secret

    WxMaDefaultConfigImpl wxMaDefaultConfig = new WxMaRedissonConfigImpl(redissonClient, keyPrefix);
    wxMaDefaultConfig.setAppid(appid);
    wxMaDefaultConfig.setSecret(appSecret);
    WxMaService wxMaService = new WxMaServiceImpl();
    wxMaService.setWxMaConfig(wxMaDefaultConfig);
    return wxMaService;
}

@Bean("wxCpService")
@ConditionalOnClass(RedissonClient.class)
public WxCpService newWxCpService(RedissonClient redissonClient) {
    String keyPrefix = ""; // 缓存的前缀
    String corpId = ""; // 企业微信id
    Integer agentId = 0; // 企业微信应用id
    String agentSecret = ""; // 企业微信应用密钥

    WxCpDefaultConfigImpl wxCpDefaultConfig = new WxCpRedissonConfigImpl(redissonClient, keyPrefix);
    wxCpDefaultConfig.setCorpId(corpId);
    wxCpDefaultConfig.setAgentId(agentId);
    wxCpDefaultConfig.setCorpSecret(agentSecret);
    WxCpService wxCpService = new WxCpServiceImpl();
    wxCpService.setWxCpConfigStorage(wxCpDefaultConfig);
    return wxCpService;
}
定时任务

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpService;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.stream.Collectors;

@Component
public class WechatTask {
    protected static Logger logger = LoggerFactory.getLogger(WechatTask.class);

    @Qualifier("wxService")
    @Autowired
    private WxMaService wxMaService;

    @Qualifier("wxCpService")
    @Autowired
    private WxCpService wxCpService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 定时检查微信服务器的ip是否有变动,有变动则发送通知
     */
    @Scheduled(cron = "0 0 18 * * ?")
    public void getWechatIp() throws WxErrorException {
        // 获取微信API接口 IP地址
        // 参考:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_the_WeChat_server_IP_address.html
        String s = wxMaService.get("https://api.weixin.qq.com/cgi-bin/get_api_domain_ip", "");
        Map map = JSONObject.parseObject(s, Map.class);
        JSONArray ipListArr = (JSONArray) map.get("ip_list");
        List<String> ipList = ipListArr.toJavaList(String.class)
                .stream().sorted().collect(Collectors.toList());
        String ipStr = String.join(",", ipList);
        // 读取保存的ip地址
        String redisKey = "wechat_api_ip_list";
        String ipStrInDB = redisTemplate.opsForValue().get(redisKey);
        if (!ipStr.equals(ipStrInDB)) {
            // 企业微信群聊发送消息
            sendCpMsg("微信接口的ip地址有变动:\n" + ipStr);

            // 保存ip地址
            redisTemplate.opsForValue().set(redisKey, ipStr);
        }


        // 获取微信callback IP地址
        // 参考:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_the_WeChat_server_IP_address.html
        s = wxMaService.get("https://api.weixin.qq.com/cgi-bin/getcallbackip", "");
        map = JSONObject.parseObject(s, Map.class);
        ipListArr = (JSONArray) map.get("ip_list");
        ipList = ipListArr.toJavaList(String.class)
                .stream().sorted().collect(Collectors.toList());
        ipStr = String.join(",", ipList);
        // 读取保存的ip地址
        redisKey = "wechat_api_callback_ip_list";
        ipStrInDB = redisTemplate.opsForValue().get(redisKey);
        if (!ipStr.equals(ipStrInDB)) {
            // 企业微信群聊发送消息
            sendCpMsg("微信接口的回调ip地址有变动:\n" + ipStr);

            // 保存ip地址
            redisTemplate.opsForValue().set(redisKey, ipStr);
        }


        // 获取企业微信接口IP段
        // 参考:https://developer.work.weixin.qq.com/document/path/92520
        s = wxCpService.get("https://qyapi.weixin.qq.com/cgi-bin/get_api_domain_ip", "");
        map = JSONObject.parseObject(s, Map.class);
        ipListArr = (JSONArray) map.get("ip_list");
        ipList = ipListArr.toJavaList(String.class)
                .stream().sorted().collect(Collectors.toList());
        ipStr = String.join(",", ipList);
        // 读取保存的ip地址
        redisKey = "wechat_qyapi_ip_list";
        ipStrInDB = redisTemplate.opsForValue().get(redisKey);
        if (!ipStr.equals(ipStrInDB)) {
            // 企业微信群聊发送消息
            sendCpMsg("企业微信接口的ip地址有变动:\n" + ipStr);

            // 保存ip地址
            redisTemplate.opsForValue().set(redisKey, ipStr);
        }


        // 获取企业微信回调接口IP段
        // 参考:https://developer.work.weixin.qq.com/document/path/92521
        final String[] callbackIp = wxCpService.getCallbackIp();
        Arrays.sort(callbackIp);
        ipStr = String.join(",", callbackIp);
        // 读取保存的ip地址
        redisKey = "wechat_qyapi_callback_ip_list";
        ipStrInDB = redisTemplate.opsForValue().get(redisKey);
        if (!ipStr.equals(ipStrInDB)) {
            // 企业微信群聊发送消息
            sendCpMsg("企业微信接口的回调ip地址有变动:\n" + ipStr);

            // 保存ip地址
            redisTemplate.opsForValue().set(redisKey, ipStr);
        }


        // 微信支付服务器ip没有接口可以查询,只能通过微信支付公告查看
    }

    /**
     * 发送微信群聊天机器人消息
     *
     * @param msg 消息
     */
    private void sendCpMsg(String msg) {
        // 群聊机器人webhook
        // 需要注意:是由内部群聊才能设置群聊机器人
        // 参考:http://open-work-weixin-qq-com-443.webvpn.sxu.edu.cn/help2/pc/14931?person_id=1
        String webhook = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=0fa57ab3-f3f4-404d-8206-c2b03337469e";
        Map<String, Object> params = new HashMap<>();
        params.put("msgtype", "text");
        Map<String, Object> text = new HashMap<>();
        text.put("content", msg);
        text.put("mentioned_list", new String[]{"@all"}); // 提醒所有人
        params.put("text", text);
        final Map sendMsgResult = restTemplate.postForObject(webhook, params, Map.class);
        final Object errcode = sendMsgResult.get("errcode");
        if (errcode != null && Integer.parseInt(errcode.toString()) == 0) {
            logger.info("企业微信群聊发送消息成功");
        } else {
            logger.error("企业微信群聊发送消息失败,errcode:{}", errcode);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值