code
This commit is contained in:
173
app/jobs/jobs.go
173
app/jobs/jobs.go
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/bytedance/sonic"
|
||||
"go-admin/app/admin/models"
|
||||
"go-admin/app/admin/service"
|
||||
"go-admin/app/admin/service/dto"
|
||||
@ -14,6 +15,12 @@ import (
|
||||
"go-admin/pkg/utility/snowflakehelper"
|
||||
"go-admin/services/binanceservice"
|
||||
"go-admin/services/fileservice"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@ -41,6 +48,9 @@ type AutoPlaceOrder struct {
|
||||
type LimitOrderTimeoutDuration struct {
|
||||
}
|
||||
|
||||
type ListenSymbol struct {
|
||||
}
|
||||
|
||||
// 初始化合约交易对
|
||||
func (t InitFuturesSymbol) Exec(arg interface{}) error {
|
||||
str := time.Now().Format(timeFormat) + " [INFO] JobCore InitFuturesSymbol exec success"
|
||||
@ -319,3 +329,166 @@ func (t LimitOrderTimeoutDuration) ReFutOrderPlace(db *gorm.DB, order models.Lin
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (l ListenSymbol) Exec(arg interface{}) error {
|
||||
str := time.Now().Format(timeFormat) + " [INFO] JobCore ClearLogJob exec success"
|
||||
defer logger.Info(str)
|
||||
var db *gorm.DB
|
||||
|
||||
for _, item := range sdk.Runtime.GetDb() {
|
||||
db = item
|
||||
break
|
||||
}
|
||||
set, err := helper.DefaultRedis.GetAllSortSet(rediskey.ListenAveLastSymbol)
|
||||
if err != nil {
|
||||
logger.Error("获取监听交易对失败")
|
||||
return err
|
||||
}
|
||||
fmt.Println(set)
|
||||
//if len(set) == 0 {
|
||||
// return nil
|
||||
//}
|
||||
|
||||
aveToken, _ := helper.DefaultRedis.GetString(rediskey.AveRequestToken)
|
||||
if aveToken == "" {
|
||||
aveToken, err = l.GetAveRequestId()
|
||||
if err != nil {
|
||||
logger.Error("获取请求id失败err:", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
chainSlice := []string{"solana", "bsc", "eth"}
|
||||
|
||||
for _, chain := range chainSlice {
|
||||
symbols, err := l.GetAveLastSymbol(chain, aveToken)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, symbol := range symbols.Data.Data {
|
||||
if slices.Contains(set, symbol.Token0Symbol+symbol.Token1Symbol) {
|
||||
|
||||
// 清除数据
|
||||
|
||||
//发送邮箱
|
||||
l.SendEmailNotice(db, symbol.Pair, symbol.Token0Symbol+symbol.Token1Symbol, chain)
|
||||
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAveRequestId 获取请求id
|
||||
func (l ListenSymbol) GetAveRequestId() (aveToken string, err error) {
|
||||
execPath, err := os.Getwd()
|
||||
// 获取可执行文件所在的目录
|
||||
execDir := fmt.Sprintf("%s/config/ave.js", filepath.Dir(filepath.Dir(execPath)))
|
||||
_, err = os.Stat(execDir)
|
||||
if err != nil {
|
||||
logger.Error("可执行的js 文件不存在")
|
||||
return aveToken, err
|
||||
}
|
||||
command := exec.Command("node", execDir)
|
||||
output, err := command.CombinedOutput()
|
||||
if err != nil {
|
||||
logger.Error("执行出错:err", err)
|
||||
return aveToken, err
|
||||
}
|
||||
client := &http.Client{}
|
||||
|
||||
m := map[string]string{
|
||||
"request_id": string(output),
|
||||
}
|
||||
marshal, _ := sonic.Marshal(m)
|
||||
var data = strings.NewReader(string(marshal))
|
||||
req, err := http.NewRequest("POST", "https://febweb002.com/v1api/v1/captcha/requestToken", data)
|
||||
if err != nil {
|
||||
return aveToken, err
|
||||
}
|
||||
req.Header.Set("accept", "*/*")
|
||||
req.Header.Set("accept-language", "zh-CN,zh;q=0.9")
|
||||
req.Header.Set("ave-platform", "web")
|
||||
req.Header.Set("content-type", "application/json")
|
||||
req.Header.Set("origin", "https://ave.ai")
|
||||
req.Header.Set("priority", "u=1, i")
|
||||
req.Header.Set("referer", "https://ave.ai/")
|
||||
req.Header.Set("sec-ch-ua", `"Not A(Brand";v="8", "Chromium";v="132", "Google Chrome";v="132"`)
|
||||
req.Header.Set("sec-ch-ua-mobile", "?0")
|
||||
req.Header.Set("sec-ch-ua-platform", `"Windows"`)
|
||||
req.Header.Set("sec-fetch-dest", "empty")
|
||||
req.Header.Set("sec-fetch-mode", "cors")
|
||||
req.Header.Set("sec-fetch-site", "cross-site")
|
||||
req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36")
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
logger.Error("请求失败err:", err)
|
||||
return aveToken, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
bodyText, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
logger.Error("读取响应失败err:", err)
|
||||
return aveToken, err
|
||||
}
|
||||
|
||||
var res RequestId
|
||||
sonic.Unmarshal(bodyText, &res)
|
||||
|
||||
if res.Status == 1 {
|
||||
aveToken = res.Data.Id
|
||||
helper.DefaultRedis.SetStringExpire(rediskey.AveRequestToken, res.Data.Id, time.Duration(60*time.Second))
|
||||
}
|
||||
return aveToken, err
|
||||
}
|
||||
|
||||
func (l ListenSymbol) GetAveLastSymbol(chain, token string) (aveLastSymbolResp AveLastSymbolResp, err error) {
|
||||
client := &http.Client{}
|
||||
url := fmt.Sprintf("https://api.agacve.com/v1api/v4/tokens/treasure/list?chain=%s&sort=created_at&sort_dir=desc&pageNO=1&pageSize=50&category=new&refresh_total=0", chain)
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
logger.Error("获取最新交易对列表出错err:", err)
|
||||
return AveLastSymbolResp{}, err
|
||||
}
|
||||
req.Header.Set("accept", "application/json, text/plain, */*")
|
||||
req.Header.Set("accept-language", "zh-CN,zh;q=0.9")
|
||||
req.Header.Set("ave-udid", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36--1739784205001--97086a46-bce0-4ca9-8e0e-78f5075be306")
|
||||
req.Header.Set("cache-control", "no-cache")
|
||||
req.Header.Set("lang", "en")
|
||||
req.Header.Set("origin", "https://ave.ai")
|
||||
req.Header.Set("pragma", "no-cache")
|
||||
req.Header.Set("priority", "u=1, i")
|
||||
req.Header.Set("referer", "https://ave.ai/")
|
||||
req.Header.Set("sec-ch-ua", `"Not A(Brand";v="8", "Chromium";v="132", "Google Chrome";v="132"`)
|
||||
req.Header.Set("sec-ch-ua-mobile", "?0")
|
||||
req.Header.Set("sec-ch-ua-platform", `"Windows"`)
|
||||
req.Header.Set("sec-fetch-dest", "empty")
|
||||
req.Header.Set("sec-fetch-mode", "cors")
|
||||
req.Header.Set("sec-fetch-site", "cross-site")
|
||||
req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36")
|
||||
req.Header.Set("x-auth", token)
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
logger.Error("获取最新交易对列表出错1err:", err)
|
||||
return AveLastSymbolResp{}, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
bodyText, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
logger.Error("获取最新交易对列表出错2err:", err)
|
||||
return AveLastSymbolResp{}, err
|
||||
}
|
||||
var res AveLastSymbolResp
|
||||
sonic.Unmarshal(bodyText, &res)
|
||||
return res, nil
|
||||
|
||||
}
|
||||
|
||||
// SendEmailNotice 发送邮箱通知
|
||||
// pair 合约地址
|
||||
// symbol 完整交易对
|
||||
// chain 链
|
||||
func (l ListenSymbol) SendEmailNotice(db *gorm.DB, pair string, symbol string, chain string) {
|
||||
|
||||
}
|
||||
|
||||
190
app/jobs/type.go
190
app/jobs/type.go
@ -1,6 +1,9 @@
|
||||
package jobs
|
||||
|
||||
import "github.com/robfig/cron/v3"
|
||||
import (
|
||||
"github.com/robfig/cron/v3"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Job interface {
|
||||
Run()
|
||||
@ -14,3 +17,188 @@ type JobExec interface {
|
||||
func CallExec(e JobExec, arg interface{}) error {
|
||||
return e.Exec(arg)
|
||||
}
|
||||
|
||||
type RequestId struct {
|
||||
Status int `json:"status"`
|
||||
Msg string `json:"msg"`
|
||||
Data struct {
|
||||
Id string `json:"id"`
|
||||
Image string `json:"image"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
// AveLastSymbolResp 最新交易对列表
|
||||
type AveLastSymbolResp struct {
|
||||
Status int `json:"status"`
|
||||
Msg string `json:"msg"`
|
||||
Data struct {
|
||||
Total int `json:"total"`
|
||||
PageNO int `json:"pageNO"`
|
||||
PageSize int `json:"pageSize"`
|
||||
Data []struct {
|
||||
Pair string `json:"pair"`
|
||||
Chain string `json:"chain"`
|
||||
Amm string `json:"amm"`
|
||||
TargetToken string `json:"target_token"`
|
||||
Token0Address string `json:"token0_address"`
|
||||
Token0Symbol string `json:"token0_symbol"`
|
||||
Reserve0 float64 `json:"reserve0"`
|
||||
Token0LogoUrl string `json:"token0_logo_url"`
|
||||
Token1Address string `json:"token1_address"`
|
||||
Token1Symbol string `json:"token1_symbol"`
|
||||
Reserve1 float64 `json:"reserve1"`
|
||||
Token1LogoUrl string `json:"token1_logo_url"`
|
||||
InitReserve0 float64 `json:"init_reserve0"`
|
||||
InitReserve1 float64 `json:"init_reserve1"`
|
||||
Tvl float64 `json:"tvl"`
|
||||
InitTvl float64 `json:"init_tvl"`
|
||||
TvlRatio float64 `json:"tvl_ratio"`
|
||||
CurrentPriceUsd float64 `json:"current_price_usd"`
|
||||
LpHolders int `json:"lp_holders"`
|
||||
LpLockedPercent int `json:"lp_locked_percent"`
|
||||
LpLockedTo time.Time `json:"lp_locked_to"`
|
||||
LpLockPlatform string `json:"lp_lock_platform"`
|
||||
PriceChange1M float64 `json:"price_change_1m"`
|
||||
PriceChange5M float64 `json:"price_change_5m"`
|
||||
PriceChange15M float64 `json:"price_change_15m"`
|
||||
PriceChange30M float64 `json:"price_change_30m"`
|
||||
PriceChange1H float64 `json:"price_change_1h"`
|
||||
PriceChange4H float64 `json:"price_change_4h"`
|
||||
PriceChange24H float64 `json:"price_change_24h"`
|
||||
Tx1MCount int `json:"tx_1m_count"`
|
||||
Tx5MCount int `json:"tx_5m_count"`
|
||||
Tx15MCount int `json:"tx_15m_count"`
|
||||
Tx30MCount int `json:"tx_30m_count"`
|
||||
Tx1HCount int `json:"tx_1h_count"`
|
||||
Tx4HCount int `json:"tx_4h_count"`
|
||||
Tx24HCount int `json:"tx_24h_count"`
|
||||
BuysTx1MCount int `json:"buys_tx_1m_count"`
|
||||
BuysTx5MCount int `json:"buys_tx_5m_count"`
|
||||
BuysTx15MCount int `json:"buys_tx_15m_count"`
|
||||
BuysTx30MCount int `json:"buys_tx_30m_count"`
|
||||
BuysTx1HCount int `json:"buys_tx_1h_count"`
|
||||
BuysTx4HCount int `json:"buys_tx_4h_count"`
|
||||
BuysTx24HCount int `json:"buys_tx_24h_count"`
|
||||
SellsTx1MCount int `json:"sells_tx_1m_count"`
|
||||
SellsTx5MCount int `json:"sells_tx_5m_count"`
|
||||
SellsTx15MCount int `json:"sells_tx_15m_count"`
|
||||
SellsTx30MCount int `json:"sells_tx_30m_count"`
|
||||
SellsTx1HCount int `json:"sells_tx_1h_count"`
|
||||
SellsTx4HCount int `json:"sells_tx_4h_count"`
|
||||
SellsTx24HCount int `json:"sells_tx_24h_count"`
|
||||
VolumeU1M float64 `json:"volume_u_1m"`
|
||||
VolumeU5M float64 `json:"volume_u_5m"`
|
||||
VolumeU15M float64 `json:"volume_u_15m"`
|
||||
VolumeU30M float64 `json:"volume_u_30m"`
|
||||
VolumeU1H float64 `json:"volume_u_1h"`
|
||||
VolumeU4H float64 `json:"volume_u_4h"`
|
||||
VolumeU24H float64 `json:"volume_u_24h"`
|
||||
BuyVolumeU1M float64 `json:"buy_volume_u_1m"`
|
||||
BuyVolumeU5M float64 `json:"buy_volume_u_5m"`
|
||||
BuyVolumeU15M float64 `json:"buy_volume_u_15m"`
|
||||
BuyVolumeU30M float64 `json:"buy_volume_u_30m"`
|
||||
BuyVolumeU1H float64 `json:"buy_volume_u_1h"`
|
||||
BuyVolumeU4H float64 `json:"buy_volume_u_4h"`
|
||||
BuyVolumeU24H float64 `json:"buy_volume_u_24h"`
|
||||
SellVolumeU1M float64 `json:"sell_volume_u_1m"`
|
||||
SellVolumeU5M float64 `json:"sell_volume_u_5m"`
|
||||
SellVolumeU15M float64 `json:"sell_volume_u_15m"`
|
||||
SellVolumeU30M float64 `json:"sell_volume_u_30m"`
|
||||
SellVolumeU1H float64 `json:"sell_volume_u_1h"`
|
||||
SellVolumeU4H float64 `json:"sell_volume_u_4h"`
|
||||
SellVolumeU24H float64 `json:"sell_volume_u_24h"`
|
||||
Makers1M int `json:"makers_1m"`
|
||||
Makers5M int `json:"makers_5m"`
|
||||
Makers15M int `json:"makers_15m"`
|
||||
Makers30M int `json:"makers_30m"`
|
||||
Makers1H int `json:"makers_1h"`
|
||||
Makers4H int `json:"makers_4h"`
|
||||
Makers24H int `json:"makers_24h"`
|
||||
Buyers1M int `json:"buyers_1m"`
|
||||
Buyers5M int `json:"buyers_5m"`
|
||||
Buyers15M int `json:"buyers_15m"`
|
||||
Buyers30M int `json:"buyers_30m"`
|
||||
Buyers1H int `json:"buyers_1h"`
|
||||
Buyers4H int `json:"buyers_4h"`
|
||||
Buyers24H int `json:"buyers_24h"`
|
||||
Sellers1M int `json:"sellers_1m"`
|
||||
Sellers5M int `json:"sellers_5m"`
|
||||
Sellers15M int `json:"sellers_15m"`
|
||||
Sellers30M int `json:"sellers_30m"`
|
||||
Sellers1H int `json:"sellers_1h"`
|
||||
Sellers4H int `json:"sellers_4h"`
|
||||
Sellers24H int `json:"sellers_24h"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
SniperTxCount int `json:"sniper_tx_count"`
|
||||
RusherTxCount int `json:"rusher_tx_count"`
|
||||
LastTradeAt time.Time `json:"last_trade_at"`
|
||||
DynamicTag string `json:"dynamic_tag"`
|
||||
Tag string `json:"tag"`
|
||||
MarketCap float64 `json:"market_cap"`
|
||||
MarketCapDiff int `json:"market_cap_diff"`
|
||||
Holders int `json:"holders"`
|
||||
HoldersDiff int `json:"holders_diff"`
|
||||
RiskScore int `json:"risk_score"`
|
||||
RiskLevel int `json:"risk_level"`
|
||||
Appendix string `json:"appendix"`
|
||||
SmartMoneyBuyCount24H int `json:"smart_money_buy_count_24h"`
|
||||
SmartMoneySellCount24H int `json:"smart_money_sell_count_24h"`
|
||||
SmartMoneyBuyVolume24H float64 `json:"smart_money_buy_volume_24h"`
|
||||
SmartMoneySellVolume24H float64 `json:"smart_money_sell_volume_24h"`
|
||||
SmartMoneyBuyCount4H int `json:"smart_money_buy_count_4h"`
|
||||
SmartMoneySellCount4H int `json:"smart_money_sell_count_4h"`
|
||||
SmartMoneyBuyVolume4H float64 `json:"smart_money_buy_volume_4h"`
|
||||
SmartMoneySellVolume4H float64 `json:"smart_money_sell_volume_4h"`
|
||||
SmartMoneyBuyCount1H int `json:"smart_money_buy_count_1h"`
|
||||
SmartMoneySellCount1H int `json:"smart_money_sell_count_1h"`
|
||||
SmartMoneyBuyVolume1H float64 `json:"smart_money_buy_volume_1h"`
|
||||
SmartMoneySellVolume1H float64 `json:"smart_money_sell_volume_1h"`
|
||||
SmartMoneyBuyCount15M int `json:"smart_money_buy_count_15m"`
|
||||
SmartMoneySellCount15M int `json:"smart_money_sell_count_15m"`
|
||||
SmartMoneyBuyVolume15M float64 `json:"smart_money_buy_volume_15m"`
|
||||
SmartMoneySellVolume15M float64 `json:"smart_money_sell_volume_15m"`
|
||||
SmartMoneyBuyCount5M int `json:"smart_money_buy_count_5m"`
|
||||
SmartMoneySellCount5M int `json:"smart_money_sell_count_5m"`
|
||||
SmartMoneyBuyVolume5M float64 `json:"smart_money_buy_volume_5m"`
|
||||
SmartMoneySellVolume5M float64 `json:"smart_money_sell_volume_5m"`
|
||||
HoldersTop10Ratio float64 `json:"holders_top10_ratio"`
|
||||
DevBalanceRatioCur float64 `json:"dev_balance_ratio_cur"`
|
||||
InsiderBalanceRatioCur float64 `json:"insider_balance_ratio_cur"`
|
||||
SniperBalanceRatioCur int `json:"sniper_balance_ratio_cur"`
|
||||
CtoFlag int `json:"cto_flag"`
|
||||
ReplyCount int `json:"reply_count"`
|
||||
Progress int `json:"progress"`
|
||||
FirstHalfElapsedTime int `json:"first_half_elapsed_time"`
|
||||
SecondHalfElapsedTime int `json:"second_half_elapsed_time"`
|
||||
WinnerCount int `json:"winner_count"`
|
||||
WinnerRatio int `json:"winner_ratio"`
|
||||
UpCount7D int `json:"up_count_7d"`
|
||||
UpCount14D int `json:"up_count_14d"`
|
||||
UpSeq string `json:"up_seq"`
|
||||
BigorderCnt1H int `json:"bigorder_cnt_1h"`
|
||||
BigorderBuyCnt1H int `json:"bigorder_buy_cnt_1h"`
|
||||
BigorderSellCnt1H int `json:"bigorder_sell_cnt_1h"`
|
||||
HasBrokenIssuePrice bool `json:"has_broken_issue_price"`
|
||||
ListingAt int `json:"listing_at"`
|
||||
Holders1440 int `json:"holders_1440"`
|
||||
BuyCount24H int `json:"buy_count_24h"`
|
||||
HotRank int `json:"hot_rank"`
|
||||
FrontShowIndex int `json:"front_show_index"`
|
||||
PiPriceChange1M float64 `json:"pi_price_change_1m"`
|
||||
PiPriceChange5M float64 `json:"pi_price_change_5m"`
|
||||
PiPriceChange15M float64 `json:"pi_price_change_15m"`
|
||||
PiPriceChange30M float64 `json:"pi_price_change_30m"`
|
||||
PiPriceChange1H float64 `json:"pi_price_change_1h"`
|
||||
PiPriceChange4H float64 `json:"pi_price_change_4h"`
|
||||
PiPriceChange24H float64 `json:"pi_price_change_24h"`
|
||||
RatRate float64 `json:"rat_rate"`
|
||||
PhishingRate float64 `json:"phishing_rate"`
|
||||
ClusterRate float64 `json:"cluster_rate"`
|
||||
BoulderRate float64 `json:"boulder_rate"`
|
||||
AllTagRate float64 `json:"all_tag_rate"`
|
||||
Rugged int `json:"rugged"`
|
||||
Total int `json:"total"`
|
||||
RugRate float64 `json:"rug_rate"`
|
||||
} `json:"data"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
@ -52,4 +52,7 @@ const (
|
||||
//需要清理键值---------END-----------------
|
||||
|
||||
JobReOrderTrigger = "job_re_order_trigger" //定时取消限价并下市价锁
|
||||
|
||||
ListenAveLastSymbol = "listen_ave_last_symbol" // 监听最新交易对
|
||||
AveRequestToken = "ave_request_token" // AVE请求token
|
||||
)
|
||||
|
||||
418
config/ave.js
Normal file
418
config/ave.js
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user