package cmd import ( "bytes" "encoding/json" "fmt" "io/ioutil" "net/http" "sort" "strings" "text/tabwriter" "github.com/kf5grd/keybasebot" "github.com/teris-io/shortid" "samhofi.us/x/keybase/v2/types/chat1" ) var PriceAd = chat1.UserBotCommandInput{ Name: "price", Usage: "", Description: "Gets lowest crypto prices", } func SendPrice(m chat1.MsgSummary, b *keybasebot.Bot) (bool, error) { fields := strings.Fields(strings.TrimSpace(strings.Replace(m.Content.Text.Body, "!price", "", 1))) // first pass filtering if fields == nil || len(fields) > 2 { return true, fmt.Errorf("Invalid Request") } // get the args currency := strings.ToUpper(fields[0]) var target string if len(fields) == 2 { target = strings.ToUpper(fields[1]) } else { target = "USD" } // validate the args if !isAlpha(currency) || !isAlpha(target) { return true, fmt.Errorf("@%s - only letters are allowed in currency symbols", m.Sender.Username) } // get all the market prices prices, err := getPrices(currency, target) if err != nil { eid := shortid.MustGenerate() b.Logger.Error("%s: %+v", eid, err) b.KB.ReactByConvID(m.ConvID, m.Id, "Error: %s", eid) return true, nil } // sort them by price sort.Slice(prices, func(i, j int) bool { return prices[i].Price < prices[j].Price }) // get the top 5 best prices var numPrices int if len(prices) > 5 { numPrices = 5 } else if len(prices) > 0 { numPrices = len(prices) } else { return true, fmt.Errorf("@%s - no exchanges list %s", m.Sender.Username, currency) } // then use a tabwriter to format the output var buf bytes.Buffer w := tabwriter.NewWriter(&buf, 0, 0, 1, ' ', tabwriter.AlignRight) fmt.Fprintf(w, "@%s - Lowest %s Prices:```\n", m.Sender.Username, currency) for _, price := range prices[:numPrices] { fmt.Fprintf(w, "%s:\t%s\t%s\t\n", price.Market, price.Price, target) } fmt.Fprintln(w, "```") w.Flush() b.KB.SendMessageByConvID(m.ConvID, buf.String()) return true, nil } func getPrices(currency string, target string) ([]CryptonatorMarket, error) { client := &http.Client{} apiTargetURL := fmt.Sprintf("https://api.cryptonator.com/api/full/%s-%s", currency, target) req, err := http.NewRequest("GET", apiTargetURL, nil) if err != nil { return nil, err } req.Header.Set("User-Agent", "GoLang Currency Bot ssh0le/0.99") resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } var apiResponse CryptApiResponse if err := json.Unmarshal(body, &apiResponse); err != nil { return nil, err } if !apiResponse.Success { return nil, fmt.Errorf(apiResponse.Error) } return apiResponse.Ticker.Markets, nil }