price command
This commit is contained in:
100
cmd/price.go
Normal file
100
cmd/price.go
Normal file
@ -0,0 +1,100 @@
|
||||
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: "<cryptocurrency>",
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user