掘金自动签到抽奖加钉钉消息通知 他来了(附源码也可帮定时自动抽)

背景

自从掘金的签到抽奖让小海尝到点甜头后(实际上是没有什么鸟用的桌垫加徽章),小海便加入了每日攒矿石的抽奖大队,结果一个月前连续签到二十天断了,又回到解放前的100→200矿石的日子,于是乎痛定思痛决定把事情交给程序来做,javaer就该拿程序说话 image.png

开始行动

首先我们新建一个springboot项目,为什么要用springbooot呢?因为小海是一年经验的java后端,技术栈就是ctrl c,v +springboot。好了然后我们加上@EnableScheduling 开启定时任务,每天执行我们的抽奖代码。再加上@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class}) 取消默认的datasource配置,因为我们并不需要数据库支持,这样我们的架子就搭好了,开始写业务。

/**
 * @author lizhihai
 * @date 2021/09/11
 * 开启定时任务,取消springdatasource加载
 */
@EnableScheduling
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
public class MyTestProApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyTestProApplication.class, args);
    }

}
复制代码

签到抽奖请求

掘金的签到抽奖这几个请求都是https协议的,有证书的请求,所以我们多的不说,用HttpURLConnection写个通用的发送https请求的方法,和获取返回值的方法,这里参考www.jianshu.com/p/848911df8…

/**
 * 通用https请求方法 掘金是https协议有证书请求
 *
 * @param url
 * @param method
 * @return
 * @throws Exception
 */
public String commnoReuqest(String url, String method,Cookies cookie) throws Exception {
    URL serverUrl = new URL(url);
    HttpURLConnection conn = (HttpURLConnection) serverUrl.openConnection();
    conn.setRequestMethod(method);
    conn.setRequestProperty("Content-type", "application/json");
    conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36");
    conn.setRequestProperty("Cookie", cookie.getValue());
    //必须设置false,否则会自动redirect到重定向后的地址
    conn.setInstanceFollowRedirects(false);
    conn.connect();
    String result = getReturn(conn);
    return result;
}

/*请求url获取返回的内容*/
public static String getReturn(HttpURLConnection connection) throws IOException {
    StringBuffer buffer = new StringBuffer();
    //将返回的输入流转换成字符串
    try (InputStream inputStream = connection.getInputStream();
         InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
         BufferedReader bufferedReader = new BufferedReader(inputStreamReader);) {
        String str = null;
        while ((str = bufferedReader.readLine()) != null) {
            buffer.append(str);
        }
        String result = buffer.toString();
        return result;
    }
}
复制代码

掘金api

然后我们就打开熟悉的F12看看掘金签到抽奖的请求是咋样的,搜索api,根据url猜猜各个请求都是干啥的,下面我们把整理好的api都写到常量类里面,并且把cookie 复制下来,根据各个url和通用请求方法,封装好签到,抽奖,查询矿石的方法。拿到cookie,拿到url,现在我们已经可以在程序里去执行签到抽奖的操作了,写个test试一下, 请求得到结果{"err_no":15001,"err_msg":"您今日已完成签到,请勿重复签到","data":null} ,ok 测试结果成功get√

image.png

public class Constans {

    public static final String POST = "POST";
    public static final String GET = "GET";

    //URL
    //签到
    public static final String CHECK_IN = "https://api.juejin.cn/growth_api/v1/check_in";
    //抽奖
    public static final String DRAW = "https://api.juejin.cn/growth_api/v1/lottery/draw";
    //查询剩余矿石
    public static final String GET_CUR_POINT = "https://api.juejin.cn/growth_api/v1/get_cur_point";

}
复制代码
/**
 * 签到
 *
 * @throws Exception
 */
public boolean checkIn(Cookies cookie) throws Exception {
    String response = commnoReuqest(Constans.CHECK_IN, Constans.POST,cookie);
    logger.info("{}{}",cookie.getName(),response);
    boolean hasSign=!response.contains("err_no":0");
    if(hasSign){
        sendHttps.sendToDingDing(cookie.getName()+response);
    }
    return hasSign;
}

/**
 * 抽奖
 *
 * @throws Exception
 */
public void draw(Cookies cookie) throws Exception {
    String response = commnoReuqest(Constans.DRAW, Constans.POST,cookie);
    DrawResponce data= JSON.parseObject(response,new TypeReference<DrawResponce>(){});
    String prizeName=data.getData().getLotteryName();
    if(!"66矿石".equals(prizeName)&&!prizeName.contains("Bug")){
        log.error("{}抽到好东西了{}!!!!!!,cookie.getName()+"抽到"+prizeName");
    }
    logger.info(response);
}
复制代码

扩展性

这里小海拉了开了个小号并且拉了个小伙伴加入抽奖大队,所以需要完成批量抽奖操作,并且考虑到有的小伙伴希望每天使用免费抽奖,攒着矿石,有的希望每天梭哈抽奖,所以我们定义一个枚举类,属性有name,value,allin,分别代表小伙伴的名字,小伙伴的掘金cookie,小伙伴是否希望梭哈抽奖。这样我们就能以遍历枚举值的方式去批量抽奖了

//cookie 掘金的cookie据说有一个月有效期,挂了就再拷一个过来
public enum Cookies {
    HAI1(true,"小海183","_ga=GA1.2.1296772436.1629686778; passport_csrf_token_default=f933ed7f9d24bfb06894114528a64af6; passport_csrf_token=f933ed7f9d24bfb06894114528a64af6; MONITOR_WEB_ID=aa936331-59e1-4607-8edf-84657bbc22cd; _gid=GA1.2.1269321208.1630996120; odin_tt=1bb7f242d137177d63dd9302d566ca5eac4c9fcb56b1dde948623c0efaf17cbecade967d875212a51b1c0e85f5643f2b08907c58b7b23435c0f866d83a18cf6e; passport_auth_status=0481add371299d2704126689380b9849%2C703a60ebb0e24b3a72db9bdc379e399d; passport_auth_status_ss=0481add371299d2704126689380b9849%2C703a60ebb0e24b3a72db9bdc379e399d; sid_guard=a6220a3e86f808bb214cbbe6d482a529%7C1631266482%7C5184000%7CTue%2C+09-Nov-2021+09%3A34%3A42+GMT; uid_tt=ccb35b269c8a75cb1dbd63c6d37a8a53; uid_tt_ss=ccb35b269c8a75cb1dbd63c6d37a8a53; sid_tt=a6220a3e86f808bb214cbbe6d482a529; sessionid=a6220a3e86f808bb214cbbe6d482a529; sessionid_ss=a6220a3e86f808bb214cbbe6d482a529; sid_ucp_v1=1.0.0-KDZkMGY3MDVmMzIyODI0MzU3Y2IyOWRjNGFmOGUxYTQwMGIwNTA3MWMKFwi93KCx4o2gBRCyzeyJBhiwFDgCQPEHGgJsZiIgYTYyMjBhM2U4NmY4MDhiYjIxNGNiYmU2ZDQ4MmE1Mjk; ssid_ucp_v1=1.0.0-KDZkMGY3MDVmMzIyODI0MzU3Y2IyOWRjNGFmOGUxYTQwMGIwNTA3MWMKFwi93KCx4o2gBRCyzeyJBhiwFDgCQPEHGgJsZiIgYTYyMjBhM2U4NmY4MDhiYjIxNGNiYmU2ZDQ4MmE1Mjk; n_mh=KF_8KclpLr_zR7cAEjb3RtZNBW4-HCCsXj4xdrmiLXE"),
    HAI2(true,"小海176","MONITOR_WEB_ID=46e596ce-9ecc-4a89-992a-7c6a6e0c3481; _ga=GA1.2.1129485207.1631332210; _gid=GA1.2.1280463638.1631332210; passport_csrf_token_default=79180cb48bf4906a01362c777619a03e; passport_csrf_token=79180cb48bf4906a01362c777619a03e; passport_auth_status=26b44631a00ffda2ca525997e425471b%2C; passport_auth_status_ss=26b44631a00ffda2ca525997e425471b%2C; sid_guard=da5b5f8fa2be84a74656f9ed8f0f58de%7C1631332246%7C5184000%7CWed%2C+10-Nov-2021+03%3A50%3A46+GMT; uid_tt=369af9b9a6bd0a458166702eb1a9eb76; uid_tt_ss=369af9b9a6bd0a458166702eb1a9eb76; sid_tt=da5b5f8fa2be84a74656f9ed8f0f58de; sessionid=da5b5f8fa2be84a74656f9ed8f0f58de; sessionid_ss=da5b5f8fa2be84a74656f9ed8f0f58de; sid_ucp_v1=1.0.0-KDA2ODRmYTJmODZiOThjYjBjNDhjYjZjYzMwZjY0NzNhNzM1ODdhYmIKFwjnkrCFu4yWAxCWz_CJBhiwFDgCQPEHGgJsZiIgZGE1YjVmOGZhMmJlODRhNzQ2NTZmOWVkOGYwZjU4ZGU; ssid_ucp_v1=1.0.0-KDA2ODRmYTJmODZiOThjYjBjNDhjYjZjYzMwZjY0NzNhNzM1ODdhYmIKFwjnkrCFu4yWAxCWz_CJBhiwFDgCQPEHGgJsZiIgZGE1YjVmOGZhMmJlODRhNzQ2NTZmOWVkOGYwZjU4ZGU; n_mh=gY-EUdc0-atNYE3DFtWTsH7CHt0JMgKQkRnBimbpdn8; _gat=1"),
    WU(true,"小吴","MONITOR_WEB_ID=da85199d-f4d8-434b-a709-6470a7f2ae08; _ga=GA1.2.1545343137.1631330098; _gid=GA1.2.1996029296.1631330098; passport_csrf_token_default=c95cd45eb0563c42a850d971f8f8d670; passport_csrf_token=c95cd45eb0563c42a850d971f8f8d670; passport_auth_status=46573bcc67d38f6c4202117b42f9b248%2C; passport_auth_status_ss=46573bcc67d38f6c4202117b42f9b248%2C; sid_guard=ed395050035826d1ea12953bd5728b05%7C1631330346%7C5184000%7CWed%2C+10-Nov-2021+03%3A19%3A06+GMT; uid_tt=4f23e928a63e23958189356b7349ddc1; uid_tt_ss=4f23e928a63e23958189356b7349ddc1; sid_tt=ed395050035826d1ea12953bd5728b05; sessionid=ed395050035826d1ea12953bd5728b05; sessionid_ss=ed395050035826d1ea12953bd5728b05; sid_ucp_v1=1.0.0-KDAzNjEzZDNkM2FmODRhNDIxY2E3ODQ4YzJkYjY4MDI5MzczNmFjZDYKFwjnr4CNvIyqBRCqwPCJBhiwFDgCQPEHGgJsZiIgZWQzOTUwNTAwMzU4MjZkMWVhMTI5NTNiZDU3MjhiMDU; ssid_ucp_v1=1.0.0-KDAzNjEzZDNkM2FmODRhNDIxY2E3ODQ4YzJkYjY4MDI5MzczNmFjZDYKFwjnr4CNvIyqBRCqwPCJBhiwFDgCQPEHGgJsZiIgZWQzOTUwNTAwMzU4MjZkMWVhMTI5NTNiZDU3MjhiMDU; n_mh=fCN8FMn4hIUuqN_fJo4Lf9qCwiFWUh01_NgRv1iwdfQ");
    private String name;//名字
    private String value;//cookie,自己上浏览器粘贴过来
    private boolean isAllIn;//是否梭哈
    Cookies(boolean isAllIn,String name, String value) {
        this.isAllIn=isAllIn;
        this.name = name;
        this.value = value;
    }

    public String getName() {
        return name;
    }

    public boolean isAllIn() {
        return isAllIn;
    }

    public String getValue() {
        return value;
    }
}
复制代码

定时任务

重点来了,最后一步抽奖定时任务,大家看代码吧,到这里我们就可以不用担心周末断签,从而解放双手卸载掘金app了。。嘿嘿嘿

    @Scheduled(cron = "0 1 0 * * ?")
    public void excute() throws Exception {
        logger.info("定时任务开始");
        for(Cookies cookie:Cookies.values()){
            boolean hasSign=checkIn(cookie);
            if(hasSign) {continue;}
            // 第一次免费抽奖
            draw(cookie);
            //还能抽就继续干
            while(cookie.isAllIn()&&getCurPoint(cookie)>=200){
                draw(cookie);
            }
        }
        logger.info("执行结束");
    }
复制代码

顺带一提

这里掘金api的返回一层包一层,使用maputils十分繁琐,给大家推荐一款idea插件 gsonformat 直接把请求返回的字符串拷贝下来一键生成我们的抽奖结果响应类,美滋滋。

@NoArgsConstructor
@Data
public class DrawResponce {

    @JsonProperty("err_no")
    private Integer errNo;
    @JsonProperty("err_msg")
    private String errMsg;
    @JsonProperty("data")
    private DataDTO data;

    @NoArgsConstructor
    @Data
    public static class DataDTO {
        @JsonProperty("id")
        private Integer id;
        @JsonProperty("lottery_id")
        private String lotteryId;
        @JsonProperty("lottery_name")
        private String lotteryName;
        @JsonProperty("lottery_type")
        private Integer lotteryType;
        @JsonProperty("lottery_image")
        private String lotteryImage;
        @JsonProperty("history_id")
        private String historyId;
    }
}
复制代码

钉钉机器人

到这里有小伙伴就问了,我想知道我抽到啥怎么办,难不成跑到你公司看你的控制台搜log.info?于是我参考(ctrl c+v)这两篇文章www.jb51.cc/java/526453…www.cnblogs.com/fugitive/p/… 对接钉钉,代码就不贴了,挺多的,对接我自己的钉钉群机器人(ip验证的方式) 然后我每天十二点都能收到若干条钉钉消息:小海抽到66矿石。就挺突然的,哭了

image.png

最后

最后:这是菜鸡小java小海第一次写文章,有很多祖传的ctrl c v操作,大佬们看个乐就行。源码已经上传到github,github.com/NicholasZhi… 嫌麻烦想白嫖抽奖的可以评论区按格式发送你的 name,allin,cookie。例如(尼古拉斯小海,梭哈/不梭哈,"nicholas")我拉你进群加入抽奖大队哦

猜你喜欢

转载自juejin.im/post/7007242693268996104