go实现自动签到和免费抽奖

698 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

看了@嗳掘金嗳萝莉 大佬用nodejs实现自动签到和抽奖,本人正在学golang,所以用golang实现了一遍当练手了。

  1. 直接在云服务器crontab定时任务运行,代码如下:
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

const (
	baseUrl          = "https://api.juejin.cn"
	getTodayStatus   = "/growth_api/v1/get_today_status"
	checkInApi       = "/growth_api/v1/check_in"
	getLotteryConfig = "/growth_api/v1/lottery_config/get"
	drawLottery      = "/growth_api/v1/lottery/draw"
	cookie           = "这里粘贴juejin.com header里的cookie的值"
)

type Err struct {
	Err_no  int
	Err_msg string
}

type Resp struct {
	Err
	Data bool
}

type Lottery struct {
	Lottery    interface{}
	Free_count int
	point_cost int
}

type RespLottery struct {
	Err
	Data Lottery
}

type RespDraw struct {
	Err
	Data DrawResult
}

type DrawResult struct {
	Lottery_name      string
	Total_lucky_value int
	Draw_lucky_value  int
}

func sendRequest(method string, url string) (result string, err error) {
	var req *http.Request
	if method == "get" {
		req, _ = http.NewRequest("GET", url, nil)
	} else {
		req, _ = http.NewRequest("POST", url, nil)
	}

	req.Header.Set("Cookie", cookie)
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return
	}
	return string(body), nil
}

//签到
func checkIn() {
	ok := getTodayCheckStatus()
	if ok == true {
		fmt.Println("今日已签到,请勿重复签到")
		return
	}
	result, err := sendRequest("post", baseUrl+checkInApi)
	if err != nil {
		fmt.Println("签到失败:", err)
	}
	var r Resp
	json.Unmarshal([]byte(result), &r)
	if r.Err_no > 0 {
		fmt.Println("签到失败:", r.Err_msg)
	} else {
		fmt.Print("签到成功")
	}
}

//查询今日是否已经签到
func getTodayCheckStatus() bool {
	result, err := sendRequest("get", baseUrl+getTodayStatus)
	if err != nil {
		fmt.Println("查询签到失败:", err)
	}
	var r Resp
	json.Unmarshal([]byte(result), &r)
	if r.Err_no == 0 && r.Data == true {
		return true
	} else {
		return false
	}
}

//抽奖
func draw() {
	ok := getTodayDrawStatus()
	if ok == false {
		fmt.Println("免费抽奖次数已用完")
		return
	}
	result, err := sendRequest("post", baseUrl+drawLottery)
	if err != nil {
		fmt.Println("免费抽奖失败:", err)
	}
	var r RespDraw
	json.Unmarshal([]byte(result), &r)
	if r.Err_no > 0 {
		fmt.Println("免费抽奖失败:", r.Err_msg)
	} else {
		fmt.Printf("免费抽奖成功,奖品:%v,增加幸运值:%v,总幸运值:%v", r.Data.Lottery_name, r.Data.Draw_lucky_value, r.Data.Total_lucky_value)
	}
}

//获取今日免费抽奖次数
func getTodayDrawStatus() bool {
	result, err := sendRequest("get", baseUrl+getLotteryConfig)
	if err != nil {
		fmt.Println("查询免费抽奖次数失败:", err)
	}
	var r RespLottery
	json.Unmarshal([]byte(result), &r)
	if r.Err_no == 0 && r.Data.Free_count > 0 {
		return true
	} else {
		return false
	}
}

func main() {
	checkIn()
	draw()
}

  1. 腾讯云云函数运行,上代码:
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"

	"github.com/tencentyun/scf-go-lib/cloudfunction"
)

const (
	baseUrl          = "https://api.juejin.cn"
	getTodayStatus   = "/growth_api/v1/get_today_status"
	checkInApi       = "/growth_api/v1/check_in"
	getLotteryConfig = "/growth_api/v1/lottery_config/get"
	drawLottery      = "/growth_api/v1/lottery/draw"
)

var cookie string

type DefineEvent struct {
	// test event define
	Message string `json:"Message"`
}

type Err struct {
	Err_no  int
	Err_msg string
}

type Resp struct {
	Err
	Data bool
}

type Lottery struct {
	Lottery    interface{}
	Free_count int
	point_cost int
}

type RespLottery struct {
	Err
	Data Lottery
}

type RespDraw struct {
	Err
	Data DrawResult
}

type DrawResult struct {
	Lottery_name      string
	Total_lucky_value int
	Draw_lucky_value  int
}

func sendRequest(method string, url string) (result string, err error) {
	var req *http.Request
	if method == "get" {
		req, _ = http.NewRequest("GET", url, nil)
	} else {
		req, _ = http.NewRequest("POST", url, nil)
	}

	req.Header.Set("Cookie", cookie)
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return
	}
	return string(body), nil
}

//签到
func checkIn() {
	ok := getTodayCheckStatus()
	if ok == true {
		fmt.Println("今日已签到,请勿重复签到")
		return
	}
	result, err := sendRequest("post", baseUrl+checkInApi)
	if err != nil {
		fmt.Println("签到失败:", err)
	}
	var r Resp
	json.Unmarshal([]byte(result), &r)
	if r.Err_no > 0 {
		fmt.Println("签到失败:", r.Err_msg)
	} else {
		fmt.Print("签到成功")
	}
}

//查询今日是否已经签到
func getTodayCheckStatus() bool {
	result, err := sendRequest("get", baseUrl+getTodayStatus)
	if err != nil {
		fmt.Println("查询签到失败:", err)
	}
	var r Resp
	json.Unmarshal([]byte(result), &r)
	if r.Err_no == 0 && r.Data == true {
		return true
	} else {
		return false
	}
}

//抽奖
func draw() {
	ok := getTodayDrawStatus()
	if ok == false {
		fmt.Println("免费抽奖次数已用完")
		return
	}
	result, err := sendRequest("post", baseUrl+drawLottery)
	if err != nil {
		fmt.Println("免费抽奖失败:", err)
	}
	var r RespDraw
	json.Unmarshal([]byte(result), &r)
	if r.Err_no > 0 {
		fmt.Println("免费抽奖失败:", r.Err_msg)
	} else {
		fmt.Printf("免费抽奖成功,奖品:%v,增加幸运值:%v,总幸运值:%v", r.Data.Lottery_name, r.Data.Draw_lucky_value, r.Data.Total_lucky_value)
	}
}

//获取今日免费抽奖次数
func getTodayDrawStatus() bool {
	result, err := sendRequest("get", baseUrl+getLotteryConfig)
	if err != nil {
		fmt.Println("查询免费抽奖次数失败:", err)
	}
	var r RespLottery
	json.Unmarshal([]byte(result), &r)
	if r.Err_no == 0 && r.Data.Free_count > 0 {
		return true
	} else {
		return false
	}
}

func juejin(ctx context.Context, event DefineEvent) (err error) {
	cookie = event.Message
	checkIn()
	draw()
	return nil
}

func main() {
	cloudfunction.Start(juejin)
}

2.1 打包并压缩代码

  • 首先新建目录,例如:juejin
  • 新建main.go并粘贴上面的代码,
  • 新建文件go.mod,内容如下:
module juejin

go 1.13

require github.com/tencentyun/scf-go-lib v0.0.0-20211123032342-f972dcd16ff6 // indirect

  • 运行 GOOS=linux GOARCH=amd64 go build -o main main.go
  • 压缩main二进制到main.zip

2.2 创建云函数

image.png

2.3 上传代码包

  • 上传main.zip
  • 测试事件选择timer
  • Message的内容为juejin.com header里的cookie的值 image.png

2.3 创建触发器

  • cron: 0 0 1 * * * * 为每天1点运行
  • 附加信息粘贴cookie(不用json格式) image.png