From 0878cef03b34ef304a57be91ef566d4330f1358b Mon Sep 17 00:00:00 2001 From: clear Date: Fri, 12 Sep 2025 16:42:10 +0800 Subject: [PATCH] init --- .idea/.gitignore | 8 ++ .idea/modules.xml | 8 ++ .idea/randomLink.iml | 9 ++ .idea/remote-targets.xml | 16 +++ .idea/vcs.xml | 6 + go.mod | 10 ++ go.sum | 8 ++ lib/redis.go | 69 +++++++++++ lib/tg.go | 257 +++++++++++++++++++++++++++++++++++++++ main.go | 121 ++++++++++++++++++ 10 files changed, 512 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/modules.xml create mode 100644 .idea/randomLink.iml create mode 100644 .idea/remote-targets.xml create mode 100644 .idea/vcs.xml create mode 100644 go.mod create mode 100644 go.sum create mode 100644 lib/redis.go create mode 100644 lib/tg.go create mode 100644 main.go diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..a7cdac7 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..54247bd --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/randomLink.iml b/.idea/randomLink.iml new file mode 100644 index 0000000..338a266 --- /dev/null +++ b/.idea/randomLink.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/remote-targets.xml b/.idea/remote-targets.xml new file mode 100644 index 0000000..077caad --- /dev/null +++ b/.idea/remote-targets.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..c18c536 --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module randomLink + +go 1.21 + +require ( + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/go-redis/redis/v8 v8.11.5 // indirect + github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..f5671a3 --- /dev/null +++ b/go.sum @@ -0,0 +1,8 @@ +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= +github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc= +github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8= diff --git a/lib/redis.go b/lib/redis.go new file mode 100644 index 0000000..6e522f7 --- /dev/null +++ b/lib/redis.go @@ -0,0 +1,69 @@ +package lib + +import ( + "context" + "fmt" + "github.com/go-redis/redis/v8" + "sync/atomic" +) + +var ( + rdb *redis.Client + ctx = context.Background() + counter uint64 +) + +// 初始化 Redis 客户端 +func init() { + rdb = redis.NewClient(&redis.Options{ + Addr: "127.0.0.1:6379", + Password: "WKJXXmPchENCYK7x", + DB: 2, + }) +} + +func GetAllLinks() ([]string, error) { + // 使用 LRange 获取整个列表,范围为 0 到 -1(表示获取所有元素) + links, err := rdb.LRange(ctx, "links", 0, -1).Result() + if err != nil { + return nil, err + } + return links, nil +} + +// 添加链接到 Redis List +func AddLink(link string) error { + return rdb.LPush(ctx, "links", link).Err() +} + +// 删除指定的链接 +func DeleteLink(link string) error { + // LREM count 参数为 0 表示删除所有匹配的元素 + return rdb.LRem(ctx, "links", 0, link).Err() +} + +// 修改指定索引位置的链接 +func UpdateLink(index int64, newLink string) error { + return rdb.LSet(ctx, "links", index, newLink).Err() +} + +func GetLink() (string, error) { + length, err := rdb.LLen(ctx, "links").Result() + if err != nil || length == 0 { + return "", fmt.Errorf("no available links") + } + index := atomic.AddUint64(&counter, 1) % uint64(length) + return rdb.LIndex(ctx, "links", int64(index)).Result() +} + +func ClearRedis() string { + // 清空当前数据库中的所有数据 + err := rdb.FlushDB(ctx).Err() + if err != nil { + mes := fmt.Sprintf("无法清空链接: %v", err) + return mes + } else { + + return "成功清空链接,请即使新增链接" + } +} diff --git a/lib/tg.go b/lib/tg.go new file mode 100644 index 0000000..c568d87 --- /dev/null +++ b/lib/tg.go @@ -0,0 +1,257 @@ +package lib + +import ( + "fmt" + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "log" + "math/rand" + "net/url" + "strconv" + "time" +) + +var ( + bot *tgbotapi.BotAPI + err error +) +var userState = make(map[string]int) +var linkState = make(map[int]string) + +func init() { + // 7632434434:AAG-Ac9RlLTKHnGtOSUe8_SUD8j_nDWz_AU + // bot, err = tgbotapi.NewBotAPI("7322066653:AAG3qYWH5jzAW8ZtdFEWg0Fjy0Il5FLOsg8") + bot, err = tgbotapi.NewBotAPI("7455883553:AAEwoqr6EAUZehhpJUWkhPiu4r3W-fngelE") + if err != nil { + log.Panic(err) + } + bot.Debug = true + log.Printf("Authorized on account %s", bot.Self.UserName) + //db.Test() +} + +func number1() int { + rand.Seed(time.Now().UnixNano()) + + // 生成一个0到100之间的随机整数 + randomNumber := rand.Intn(100) // 生成一个 [0, 100) 范围内的随机数 + return randomNumber +} +func number2() int { + rand.Seed(time.Now().UnixNano()) + + // 生成一个0到100之间的随机整数 + randomNumber := rand.Intn(10) // 生成一个 [0, 10) 范围内的随机数 + return randomNumber +} + +func Start() { + u := tgbotapi.NewUpdate(0) + u.Timeout = 60 + updates := bot.GetUpdatesChan(u) + + for update := range updates { + if update.Message != nil { // If we got a message7227826365 + //if update.Message + if update.Message.Chat.ID == 6918349523 || update.Message.Chat.ID == 7227826365 { + //if update.Message.Chat.ID == 6918349523 { + chatID := update.Message.Chat.ID + userInput := update.Message.Text + chatIDString := strconv.FormatInt(chatID, 10) + + // 定义底部菜单 + menu := tgbotapi.NewReplyKeyboard( + tgbotapi.NewKeyboardButtonRow( + tgbotapi.NewKeyboardButton("链接列表"), + tgbotapi.NewKeyboardButton("增加链接"), + ), + tgbotapi.NewKeyboardButtonRow( + tgbotapi.NewKeyboardButton("删除链接"), + tgbotapi.NewKeyboardButton("清空链接"), + ), + ) + + var responseText string + switch userInput { + case "链接列表": + linkList, _ := GetAllLinks() + if len(linkList) == 0 { + responseText = "No links available" + + } else { + for v, link := range linkList { + vs := strconv.Itoa(v + 1) + responseText += "链接" + vs + ":\t" + link + "\n" + } + + } + + case "增加链接": + responseText = "请输入你要增加的链接(例: https://google.com),如果需要取消,请发送任意数字" + str := strconv.FormatInt(chatID, 10) + userState[str] = 60224466 + userState[str+"_a"] = 0 + userState[str+"_b"] = 0 + // 隐藏键盘 + removeKeyboard := tgbotapi.NewRemoveKeyboard(true) + msg := tgbotapi.NewMessage(update.Message.Chat.ID, responseText) + msg.ReplyMarkup = removeKeyboard + if _, err := bot.Send(msg); err != nil { + log.Println("Error sending message:", err) + } + continue + + case "删除链接": + + linkList, _ := GetAllLinks() + if len(linkList) == 0 { + + responseText = "No links available" + } else { + responseText = "请发送你要删除链接的序号,如果需要取消,请发送任意数字\t()\n" + for v, link := range linkList { + vs := strconv.Itoa(v) + responseText += vs + ".\t" + link + "\n" + linkState[v] = link + } + + } + + str := strconv.FormatInt(chatID, 10) + userState[str] = 60224467 + userState[str+"_a"] = 0 + userState[str+"_b"] = 0 + + case "清空链接": + a := number1() + b := number2() + msgLink := fmt.Sprintf("为了您的安全输入验证: %d+%d=?", a, b) + responseText = msgLink + str := strconv.FormatInt(chatID, 10) + userState[str] = 60224465 + userState[str+"_a"] = a + userState[str+"_b"] = b + + default: + responseText = "请选择接下来的操作" + } + + // 发送响应消息 + msg := tgbotapi.NewMessage(update.Message.Chat.ID, responseText) + + msg.ReplyMarkup = menu // 保持底部菜单 + if _, err := bot.Send(msg); err != nil { + log.Println("Error sending message:", err) + } + + // 检查用户状态 + if state, exists := userState[chatIDString]; exists && state == 60224465 { + a := userState[chatIDString+"_a"] // 获取存储的 a 和 b + b := userState[chatIDString+"_b"] + + // 验证用户输入 + expectedAnswer := a + b + userAnswer, err := strconv.Atoi(userInput) + if err != nil { + msg := tgbotapi.NewMessage(chatID, "请输入计算结果") + inlineKeyboard := tgbotapi.NewInlineKeyboardMarkup( + tgbotapi.NewInlineKeyboardRow( + tgbotapi.NewInlineKeyboardButtonData("取消清空", "Cancel"), + ), + ) + msg.ReplyMarkup = inlineKeyboard + bot.Send(msg) + continue + } + + if userAnswer == expectedAnswer { + msg := tgbotapi.NewMessage(chatID, "验证通过!开始删除操作...") + bot.Send(msg) + msgs := tgbotapi.NewMessage(chatID, ClearRedis()) + bot.Send(msgs) + delete(userState, chatIDString) // 删除状态 + delete(userState, chatIDString+"_a") + delete(userState, chatIDString+"_b") + } else { + delete(userState, chatIDString) // 删除状态 + delete(userState, chatIDString+"_a") + delete(userState, chatIDString+"_b") + } + } else if state, exists := userState[chatIDString]; exists && state == 60224466 { + // 增加链接 + if _, err := url.ParseRequestURI(userInput); err != nil { + delete(userState, chatIDString) // 删除状态 + delete(userState, chatIDString+"_a") + delete(userState, chatIDString+"_b") + } else { + AddLink(userInput) + msg := tgbotapi.NewMessage(chatID, "链接增加成功") + bot.Send(msg) + delete(userState, chatIDString) // 删除状态 + delete(userState, chatIDString+"_a") + delete(userState, chatIDString+"_b") + } + + } else if state, exists := userState[chatIDString]; exists && state == 60224467 { + //删除链接 + num, err := strconv.Atoi(userInput) + fmt.Println(len(linkState)) + if err != nil { + //msg := tgbotapi.NewMessage(chatID, "请输入序号") + //inlineKeyboard := tgbotapi.NewInlineKeyboardMarkup( + // tgbotapi.NewInlineKeyboardRow( + // tgbotapi.NewInlineKeyboardButtonData("取消删除", "Cancel"), + // ), + //) + //msg.ReplyMarkup = inlineKeyboard + //bot.Send(msg) + } else { + if len(linkState) > num && num >= 0 { + DeleteLink(linkState[num]) + delete(userState, chatIDString) // 删除状态 + delete(userState, chatIDString+"_a") + delete(userState, chatIDString+"_b") + for key := range linkState { + delete(linkState, key) + } + msg := tgbotapi.NewMessage(chatID, "删除成功") + bot.Send(msg) + + } else { + delete(userState, chatIDString) // 删除状态 + delete(userState, chatIDString+"_a") + delete(userState, chatIDString+"_b") + for key := range linkState { + delete(linkState, key) + } + } + } + + } else { + //Menus(&update, "请选择你要操作的内容") + } + + } + + } else if update.CallbackQuery != nil { // 按钮点击事件 + callback := update.CallbackQuery + log.Printf("Button clicked: %s", callback.Data) + switch callback.Data { + case "Cancel": + str := strconv.FormatInt(callback.Message.Chat.ID, 10) + delete(userState, str) // 删除状态 + delete(userState, str+"_a") + delete(userState, str+"_b") + if len(linkState) > 0 { + for key := range linkState { + delete(linkState, key) + } + } + msg := tgbotapi.NewMessage(update.CallbackQuery.Message.Chat.ID, "已取消") + if _, err := bot.Send(msg); err != nil { + log.Println("Failed to send message:", err) + } + } + + } + } +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..9826798 --- /dev/null +++ b/main.go @@ -0,0 +1,121 @@ +package main + +import ( + "fmt" + "net/http" + "randomLink/lib" +) + +//type RequestData struct { +// ClientIP string `json:"clientIp"` +// UserAgent string `json:"userAgent"` +// VisitUrl string `json:"visitUrl"` +// ClientLanguage string `json:"clientLanguage"` +// Referer string `json:"referer"` +// Timestamp int64 `json:"timestamp"` +// Sign string `json:"sign"` +//} + +//type Response struct { +// Code int `json:"code"` +// Message string `json:"message"` +// Data struct { +// Status bool `json:"status"` +// Message string `json:"message"` +// Jump string `json:"jump"` +// ErrorCode string `json:"errorCode"` +// Custom struct { +// WebId int `json:"webId"` +// Name string `json:"name"` +// } `json:"custom"` +// } `json:"data"` +// Success bool `json:"success"` +//} + +//func getRealIP(r *http.Request) string { +// // 优先从 X-Forwarded-For 获取 +// xff := r.Header.Get("X-Forwarded-For") +// if xff != "" { +// // X-Forwarded-For 可能包含多个 IP,取第一个 +// ips := strings.Split(xff, ",") +// return strings.TrimSpace(ips[0]) +// } +// +// // 尝试从 X-Real-IP 获取 +// xri := r.Header.Get("X-Real-IP") +// if xri != "" { +// return xri +// } +// +// // 最后回退到 RemoteAddr +// host, _, err := net.SplitHostPort(r.RemoteAddr) +// if err != nil { +// return r.RemoteAddr // 返回原始 RemoteAddr +// } +// return host +//} + +// HTTP 跳转处理器 +func redirectHandler(w http.ResponseWriter, r *http.Request) { + + //data := RequestData{ + // ClientIP: getRealIP(r), + // UserAgent: r.UserAgent(), + // VisitUrl: "https://app.autostock.tech" + r.URL.String(), + // ClientLanguage: r.Header.Get("Accept-Language"), + // Timestamp: time.Now().Unix(), + // Referer: r.Referer(), + // Sign: "R0QtsCttYCltUlaUYXSzj", + //} + //// 将数据编码为 JSON + //jsonData, err := json.Marshal(data) + //if err != nil { + // fmt.Println("Error marshaling JSON:", err) + // return + //} + + //resp, err := http.Post("https://api-visitor.fangyu.io/check/2168/BFqEzXbIQYao3w3j5B", "application/json", bytes.NewBuffer(jsonData)) + //if err != nil { + // fmt.Println("Error sending POST request:", err) + // return + //} + //defer resp.Body.Close() + + //// 输出响应状态码 + //fmt.Println("Response Status:", resp.Status) + //body, err := ioutil.ReadAll(resp.Body) + //fmt.Println("Response Body:", string(body)) + //var response Response + //if err := json.Unmarshal([]byte(body), &response); err != nil { + // fmt.Println("Error unmarshaling JSON:", err) + //} + //fmt.Printf("Response: %+v\n", response) + //if response.Data.Status { + // link, err := lib.GetLink() + // if err != nil { + // http.Error(w, "No available links", http.StatusInternalServerError) + // return + // } + // http.Redirect(w, r, link, http.StatusFound) + // + //} else { + // http.Redirect(w, r, "https://#", http.StatusFound) + //} + link, err := lib.GetLink() + if err != nil { + http.Error(w, "No available links", http.StatusInternalServerError) + return + } + http.Redirect(w, r, link, http.StatusFound) + +} + +func main() { + go lib.Start() + // 启动 HTTP 服务器 + http.HandleFunc("/", redirectHandler) + fmt.Println("Server is running on :8083") + if err := http.ListenAndServe(":8083", nil); err != nil { + fmt.Println("Server error:", err) + } +}