init
This commit is contained in:
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/randomLink.iml" filepath="$PROJECT_DIR$/.idea/randomLink.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
9
.idea/randomLink.iml
generated
Normal file
9
.idea/randomLink.iml
generated
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="Go" enabled="true" />
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
16
.idea/remote-targets.xml
generated
Normal file
16
.idea/remote-targets.xml
generated
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteTargetsManager">
|
||||
<targets>
|
||||
<target name="root@192.3.55.124:22" type="ssh/sftp" uuid="caa814af-46f3-40d3-8fc3-b39c5a1ec66e">
|
||||
<config>
|
||||
<option name="projectRootOnTarget" value="/root/randomLink" />
|
||||
<option name="serverName" value="root@192.3.55.124:22 password" />
|
||||
</config>
|
||||
<ContributedStateBase type="GoLanguageRuntime">
|
||||
<config />
|
||||
</ContributedStateBase>
|
||||
</target>
|
||||
</targets>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
10
go.mod
Normal file
10
go.mod
Normal file
@ -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
|
||||
)
|
||||
8
go.sum
Normal file
8
go.sum
Normal file
@ -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=
|
||||
69
lib/redis.go
Normal file
69
lib/redis.go
Normal file
@ -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 "成功清空链接,请即使新增链接"
|
||||
}
|
||||
}
|
||||
257
lib/tg.go
Normal file
257
lib/tg.go
Normal file
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
121
main.go
Normal file
121
main.go
Normal file
@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user