package newbond import ( "database/sql" "encoding/json" "fmt" "io" "net/http" "time" "git.lxtend.com/qqbot/action" "git.lxtend.com/qqbot/model" "git.lxtend.com/qqbot/sqlite3" ) func init() { createNewBondListenGroupTableSQL := ` CREATE TABLE IF NOT EXISTS new_bond_listen_group ( group_id INT PRIMARY KEY ); ` createNewBondInfoTableSQL := `CREATE TABLE BondData ( SecurityCode VARCHAR(10) NOT NULL, SecuCode VARCHAR(15) NOT NULL, TradeMarket VARCHAR(10) NOT NULL, SecurityNameAbbr VARCHAR(50) NOT NULL, PRIMARY KEY (SecurityCode) ); ` sqlite3.TryCreateTable(createNewBondListenGroupTableSQL) sqlite3.TryCreateTable(createNewBondInfoTableSQL) go RoundCheckNewBond() } func GetBondsData() ([]BondData, error) { url := "https://datacenter-web.eastmoney.com/api/data/v1/get?sortColumns=PUBLIC_START_DATE%2CSECURITY_CODE&sortTypes=-1%2C-1&pageSize=50&pageNumber=1&reportName=RPT_BOND_CB_LIST&columns=ALL"eColumns=f2~01~CONVERT_STOCK_CODE~CONVERT_STOCK_PRICE%2Cf235~10~SECURITY_CODE~TRANSFER_PRICE%2Cf236~10~SECURITY_CODE~TRANSFER_VALUE%2Cf2~10~SECURITY_CODE~CURRENT_BOND_PRICE%2Cf237~10~SECURITY_CODE~TRANSFER_PREMIUM_RATIO%2Cf239~10~SECURITY_CODE~RESALE_TRIG_PRICE%2Cf240~10~SECURITY_CODE~REDEEM_TRIG_PRICE%2Cf23~01~CONVERT_STOCK_CODE~PBV_RATIO"eType=0&source=WEB&client=WEB" resp, err := http.Get(url) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("status code %d", resp.StatusCode) } body, err := io.ReadAll(resp.Body) if err != nil { return nil, err } var apiResponse BondResponse err = json.Unmarshal(body, &apiResponse) if err != nil { return nil, err } return apiResponse.Result.Data, nil } func AddGroupListen(groupID int) error { tx, err := sqlite3.GetTran() if err != nil { return err } defer tx.Rollback() tx.Exec("INSERT INTO new_bond_listen_group (group_id) VALUES (?)", groupID) if err := tx.Commit(); err != nil { return err } return nil } func RemoveGroupListen(groupID int) error { tx, err := sqlite3.GetTran() if err != nil { return err } defer tx.Rollback() tx.Exec("DELETE FROM new_bond_listen_group WHERE group_id = ?", groupID) if err := tx.Commit(); err != nil { return err } return nil } func BondDataExists(securityCode string) (bool, error) { db := sqlite3.GetDB() var count int if err := db.Get(&count, "SELECT COUNT(*) FROM BondData WHERE SecurityCode = ?", securityCode); err != nil { return false, err } return count > 0, nil } func AddBondData(data BondData) error { tx, err := sqlite3.GetTran() if err != nil { return err } defer tx.Rollback() query := `INSERT INTO BondData ( SecurityCode, SecuCode, TradeMarket, SecurityNameAbbr ) VALUES ( :SecurityCode, :SecuCode, :TradeMarket, :SecurityNameAbbr )` _, err = tx.NamedExec(query, data) if err != nil { return err } if err := tx.Commit(); err != nil { return err } return nil } func GetGroupListens() ([]int, error) { db := sqlite3.GetDB() var groupIDs []int if err := db.Select(&groupIDs, "SELECT group_id FROM new_bond_listen_group"); err != nil && err != sql.ErrNoRows { return nil, err } return groupIDs, nil } func RoundCheckNewBond() { time.Sleep(5 * time.Second) for !action.ActionManager.Started() { time.Sleep(5 * time.Second) } // once := true for { // if !once { time.Sleep(5 * time.Minute) // } bonds, err := GetBondsData() if bonds == nil || err != nil { fmt.Println("Error getting bonds data:", err) continue } groups, err := GetGroupListens() if err != nil { fmt.Println("Error getting group listens:", err) continue } for _, bond := range bonds { exists, err := BondDataExists(bond.SecurityCode) if err != nil { fmt.Println("Error checking bond data exists:", err) continue } if !exists { for _, group := range groups { msg := model.Reply{ ReplyMsg: fmt.Sprintf("号外号外,%s开始申购了", bond.SecurityNameAbbr), ReferOriginMsg: false, FromMsg: model.Message{ GroupInfo: model.GroupInfo{ GroupId: int64(group), }, }, } action.ActionManager.SendMsg(msg) } } AddBondData(bond) } // once = false } }