1 changed files with 100 additions and 0 deletions
@ -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 |
||||||
|
} |
Loading…
Reference in new issue