// Response creators package main import ( "fmt" "strings" "time" "math" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api" ) func (c *Connection) AddUser(reqChat *tgbotapi.Chat) (string, error) { // Check if user already registered var userCount int64 result := c.GormDb.Model(&User{}). Where("chat_id = ?", reqChat.ID). Count(&userCount) if result.Error != nil { return "", fmt.Errorf("failed creating user: %w", result.Error) } if userCount != 0 { return "Already registered", nil } // Adding new user to database newUser := User{ChatId: reqChat.ID} result = c.GormDb.Create(newUser) if result.Error != nil { return "", fmt.Errorf("failed creating user: %w", result.Error) } LogInfo.Println("User was created:", newUser) return "Added new user to database. Now you can connect your miner wallet using command /setwallet
", nil } func (c *Connection) SetWallet(reqMsg *tgbotapi.Message) (string, error) { // Check if user already registered var userCount int64 result := c.GormDb.Model(&User{}). Where("chat_id = ?", reqMsg.Chat.ID). Count(&userCount) if result.Error != nil { return "", fmt.Errorf("failed wallet set: %w", result.Error) } if userCount == 0 { return "You are not registered! Type /start first!", nil } // *Strange* check for length of predifined eth wallet hash if len(strings.Split(reqMsg.Text, " ")[1]) > 2 { // Check if wallet hash typed with 0x // TODO Should be: starts with '0x' or in format 0x.... if strings.Contains(strings.Split(reqMsg.Text, " ")[1], "0x") { // TODO replace inefficient branching result = c.GormDb.Model(&User{}). Where("chat_id = ?", reqMsg.Chat.ID). Update("wallet", strings.Split(reqMsg.Text, " ")[1]) if result.Error != nil { return "", fmt.Errorf("failed querying user: %w", result.Error) } } else { result = c.GormDb.Model(&User{}). Where("chat_id = ?", reqMsg.Chat.ID). Update("wallet", "0x"+strings.Split(reqMsg.Text, " ")[1]) if result.Error != nil { return "", fmt.Errorf("failed querying user: %w", result.Error) } } LogInfo.Printf("Updated wallet of user %d to %s\n", reqMsg.Chat.ID, strings.Split(reqMsg.Text, " ")[1]) // TODO this is ▼▼ lame bro return fmt.Sprintf("0x%s set!", strings.Split(reqMsg.Text, " ")[1]), nil } else { return "Too short!", nil } } func (c *Connection) DeleteUser(reqChat *tgbotapi.Chat) (string, error) { // Check for user existance var userCount int64 result := c.GormDb.Model(&User{}). Where("chat_id = ?", reqChat.ID). Count(&userCount) if result.Error != nil { return "", fmt.Errorf("failed creating user: %w", result.Error) } if userCount == 0 { return "Already deleted", nil } // Taking target for deletion var user User result = c.GormDb.Take(&user, "chat_id = ?", reqChat.ID) if result.Error != nil { return "", fmt.Errorf("failed querying user: %w", result.Error) } var walletHoldersCount int64 result = c.GormDb.Model(&User{}). Where("wallet = ?", user.Wallet). Count(&walletHoldersCount) if result.Error != nil { return "", fmt.Errorf("failed querying user: %w", result.Error) } // TODO Remove code repition if walletHoldersCount > 1 { // Wallet in multiple chats result = c.GormDb.Where("chat_id = ?", reqChat.ID).Delete(User{}) if result.Error != nil { return "", fmt.Errorf("failed deleting user: %w", result.Error) } } else { // Wallet in single chat result = c.GormDb.Where("chat_id = ?", reqChat.ID).Delete(User{}) if result.Error != nil { return "", fmt.Errorf("failed deleting user: %w", result.Error) } result = c.GormDb.Where("wallet = ?", user.Wallet).Delete(Miner{}) if result.Error != nil { return "", fmt.Errorf("failed deleting miner: %w", result.Error) } LogInfo.Println("Miners deleted with wallet:", user.Wallet) result = c.GormDb.Where("wallet = ?", user.Wallet).Delete(Worker{}) if result.Error != nil { return "", fmt.Errorf("failed deleting workers: %w", result.Error) } LogInfo.Println("Workers deleted with wallet:", user.Wallet) result = c.GormDb.Where("wallet = ?", user.Wallet).Delete(Payout{}) if result.Error != nil { return "", fmt.Errorf("failed deleting payouts: %w", result.Error) } LogInfo.Println("Payouts deleted for wallet:", user.Wallet) } LogInfo.Println("User was deleted:", user) return "Done!", nil } func (c *Connection) GetActualDataFromDatabase(chatId int64) string { errMsgToUser := "An exception occurred on sending messages while executing /actual command" var wallet string result := c.GormDb.Model(&User{}). Where("chat_id = ?", chatId). Select("wallet"). Scan(&wallet) if result.Error != nil { LogError.Println(result.Error) return errMsgToUser } if wallet == "" { return "Set wallet at first! Use /setwallet" } var lastMinerRecord Miner result = c.GormDb. Where(&Miner{Wallet: wallet}). Order("time desc"). Limit(1). Find(&lastMinerRecord) if result.Error != nil { LogError.Println(result.Error) return "No miner data for now!" } var lastTime int64 result = c.GormDb.Model(&Worker{}). Where("wallet = ?", wallet). Select("MAX(time)"). Scan(&lastTime) if result.Error != nil { LogError.Println(result.Error) return errMsgToUser } var lastWorkerRecord []Worker result = c.GormDb. Where(&Worker{Wallet: wallet, Time: lastTime}). Find(&lastWorkerRecord) if result.Error != nil { LogError.Println(result.Error) return errMsgToUser } if len(lastWorkerRecord) == 0 { return "No workers data for now!" } msgText := fmt.Sprintf("Miner %s stats:\n", lastMinerRecord.Wallet) msgText += fmt.Sprintf("Updated: %s\n", time.Unix(lastMinerRecord.Time, 0).Format("Monday, January 2, 2006 3:04 PM")) msgText += fmt.Sprintf("Reported Hashrate: %.3f MH/s\n", math.Round(float64(lastMinerRecord.ReportedHashrate)/1000)/1000) msgText += fmt.Sprintf("Current Hashrate: %.3f MH/s\n", math.Round(float64(lastMinerRecord.CurrentHashrate)/1000)/1000) msgText += fmt.Sprintf("Valid Shares: %d\n", lastMinerRecord.ValidShares) msgText += fmt.Sprintf("Stale Shares: %d\n", lastMinerRecord.StaleShares) msgText += fmt.Sprintf("Workers: %d\n", lastMinerRecord.Workers) msgText += fmt.Sprintf("Unpaid Balance: %.5f ETH\n", float64(lastMinerRecord.Unpaid)/math.Pow10(18)) //TODO ETH = AppSettings.currency msg := tgbotapi.NewMessage(chatId, msgText) myBotClient.Send(msg) LogInfo.Printf("Replied with: %s", strings.ReplaceAll(msg.Text, "\n", "\\n")) for i := range lastWorkerRecord { // Per worker message time.Sleep(1 * time.Second) // Anti spam filter if i != 0 && i%20 == 0 { //TODO SOMETIHNG BETTER THAN USUAL TIMER time.Sleep(30 * time.Second) } msgText := fmt.Sprintf("Worker %s stats:\n", lastWorkerRecord[i].Worker) msgText += fmt.Sprintf("Updated: %s\n", time.Unix(lastWorkerRecord[i].Time, 0).Format("Monday, January 2, 2006 3:04 PM")) msgText += fmt.Sprintf("Reported Hashrate: %.3f MH/s\n", math.Round(float64(lastWorkerRecord[i].ReportedHashrate)/1000)/1000) msgText += fmt.Sprintf("Current Hashrate: %.3f MH/s\n", math.Round(float64(lastWorkerRecord[i].CurrentHashrate)/1000)/1000) msgText += fmt.Sprintf("Valid Shares: %d\n", lastWorkerRecord[i].ValidShares) msgText += fmt.Sprintf("Stale Shares: %d\n", lastWorkerRecord[i].StaleShares) msgText += fmt.Sprintf("Unpaid Balance: %.5f ETH\n", float64(lastWorkerRecord[i].WorkerUnpaid)/math.Pow10(18)) //TODO ETH = AppSettings.currency msg := tgbotapi.NewMessage(chatId, msgText) myBotClient.Send(msg) LogInfo.Printf("Replied with: %s", strings.ReplaceAll(msg.Text, "\n", "\\n")) } return "nice" } func (c *Connection) GetLastPayout(chatId int64) string { errMsgToUser := "An exception occurred on sending messages while executing /actual command" var wallet string result := c.GormDb.Model(&User{}). Where(User{ChatId: chatId}). Select("wallet"). Scan(&wallet) if result.Error != nil { LogError.Println(result.Error) return errMsgToUser } if wallet == "" { return "Set wallet at first! Use /setwallet" } var payoutTime int64 result = c.GormDb.Model(&Payout{}). Where(&Payout{Wallet: wallet}). Order("time desc"). Limit(1). Select("time"). Scan(&payoutTime) if result.Error != nil { LogInfo.Printf("No payouts data for %s! Time is set to 0!", wallet) LogError.Println(result.Error) payoutTime = 0 } // NOTE Pointless if previous 'if' statement occurs // Must go from the start to line 235 var dbPayoutRecords []Payout result = c.GormDb. Where(&Payout{Wallet: wallet, Time: payoutTime}). Find(&dbPayoutRecords) //Line 560 of Program.cs if len(dbPayoutRecords) == 0 { url := fmt.Sprintf("%s/miner/%s/payouts", appSettings.ApiUrl, wallet) var payouts JsonPayouts err := UnmasrshalFromUrl(url, &payouts) if err != nil { LogError.Println(err) return fmt.Sprintf("No payout data for %s", wallet) } lastPayout := payouts.Data[0] message := fmt.Sprintf("Payout date: %s\n", time.Unix(lastPayout.PaidOn, 0).Format("Monday, January 2, 2006 3:04 PM")) message += fmt.Sprintf("Amount: %.5f %s\n", float64(lastPayout.Amount)/math.Pow10(18), appSettings.Currency) message += "Data source: Ethermine API \n" return message } if result.Error != nil { LogError.Println(result.Error) return errMsgToUser } //Line 545 of Program.cs message := fmt.Sprintf("Payout date: %s\n", time.Unix(dbPayoutRecords[0].Time, 0).Format("Monday, January 2, 2006 3:04 PM")) message += fmt.Sprintf("Amount: %.5f ETH\n", float64(dbPayoutRecords[0].Amount)/math.Pow10(18)) for _, payoutRecord := range dbPayoutRecords { message += fmt.Sprintf("Worker %s paid: %.5f %s\n", //TODO ETH = AppSettings.currency payoutRecord.Worker, float64(payoutRecord.Amount)/math.Pow10(18), appSettings.Currency) } message += "Data source: Bot database \n" return message } func GetActualRate() string { url := fmt.Sprintf("%s/networkStats", appSettings.ApiUrl) var networkStats JsonNetworkStats err := UnmasrshalFromUrl(url, &networkStats) if err != nil { return fmt.Sprintf("Error with getting data from %s", appSettings.ApiUrl) } data := networkStats.Data actualRate := fmt.Sprintf("ETH: %.2f\nBTC: %.2f", data.Usd, float64(data.Usd)/float64(data.Btc)) return actualRate } func GetActualData(miner string) string { url := fmt.Sprintf("%s/miner/%s/currentStats", appSettings.ApiUrl, miner) var currentStats JsonCurrentStats err := UnmasrshalFromUrl(url, ¤tStats) if err != nil { // As in original... return "An exception occurred while executing this command." // return fmt.Sprintf("No data for specified wallet\n") } data := currentStats.Data actualData := fmt.Sprintf("Stats of miner\n%s\n", miner) actualData += fmt.Sprintf("Updated: %s\n", time.Unix(data.Time, 0).Format("Monday, January 2, 2006 3:04 PM")) actualData += fmt.Sprintf("Reported Hashrate: %.3f MH/s\n", math.Round(float64(data.ReportedHashrate)/1000)/1000) actualData += fmt.Sprintf("Current Hashrate: %.3f MH/s\n", math.Round(data.CurrentHashrate/1000)/1000) actualData += fmt.Sprintf("Valid Shares: %d\n", data.ValidShares) actualData += fmt.Sprintf("Stale Shares: %d\n", data.StaleShares) actualData += fmt.Sprintf("Workers: %d\n", data.ActiveWorkers) actualData += fmt.Sprintf("Unpaid Balance: %.5f ETH\n", float64(data.Unpaid)/math.Pow10(18)) return actualData } func GetHelp() (help string) { // TODO separate help variable help = "This is bot tracks your miner stats and calculates unpaid per worker.\n" help += "How to start:\n" help += "1) \"/start\" - it will add you to database\n" help += "2) \"/setwallet