You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.4 KiB
94 lines
2.4 KiB
package cmd |
|
|
|
import ( |
|
"encoding/json" |
|
"fmt" |
|
"io/ioutil" |
|
"net/http" |
|
"strconv" |
|
"strings" |
|
"unicode" |
|
|
|
"github.com/kf5grd/keybasebot" |
|
"github.com/teris-io/shortid" |
|
"samhofi.us/x/keybase/v2/types/chat1" |
|
) |
|
|
|
var ConvertAd = chat1.UserBotCommandInput{ |
|
Name: "convert", |
|
Usage: "<currency> to <currency>", |
|
Description: "Converts between many crypto and fiat currencies. Try !convert 50 USD to XLM", |
|
} |
|
|
|
func Convert(m chat1.MsgSummary, b *keybasebot.Bot) (bool, error) { |
|
fields := strings.Fields(strings.TrimSpace(strings.Replace(m.Content.Text.Body, "!convert", "", 1))) |
|
|
|
// first pass filters |
|
if fields == nil || len(fields) != 4 || fields[2] != "to" { |
|
return true, fmt.Errorf("@%s - Invalid Request.", m.Sender.Username) |
|
} |
|
|
|
// get the arguments |
|
lhq := fields[0] |
|
lhc := strings.ToUpper(fields[1]) |
|
rhc := strings.ToUpper(fields[3]) |
|
|
|
// validate the args |
|
leftQuantity, err := strconv.ParseFloat(lhq, 64) |
|
if err != nil { |
|
return true, fmt.Errorf("@%s - Unable to parse %s into a number", m.Sender.Username, lhq) |
|
} |
|
if !isAlpha(lhc) || !isAlpha(rhc) { |
|
return true, fmt.Errorf("@%s - Only letters are allowed in currency symbols", m.Sender.Username) |
|
} |
|
rate, err := getConversion(lhc, rhc) |
|
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 |
|
} |
|
rhq := leftQuantity * rate |
|
b.KB.ReactByConvID(m.ConvID, m.Id, fmt.Sprintf("%.4f %s", rhq, rhc)) |
|
return true, nil |
|
} |
|
|
|
func getConversion(lhc string, rhc string) (float64, error) { |
|
client := &http.Client{} |
|
target := fmt.Sprintf("https://api.cryptonator.com/api/ticker/%s-%s", lhc, rhc) |
|
req, err := http.NewRequest("GET", target, nil) |
|
if err != nil { |
|
return 0.0, err |
|
} |
|
req.Header.Set("User-Agent", "GoLang Currency Bot ssh0le/0.99") |
|
resp, err := client.Do(req) |
|
if err != nil { |
|
return 0.0, err |
|
} |
|
defer resp.Body.Close() |
|
body, err := ioutil.ReadAll(resp.Body) |
|
if err != nil { |
|
return 0.0, err |
|
} |
|
var apiResponse CryptApiResponse |
|
if err := json.Unmarshal(body, &apiResponse); err != nil { |
|
return 0.0, err |
|
} |
|
if !apiResponse.Success { |
|
return 0.0, fmt.Errorf(apiResponse.Error) |
|
} |
|
result, err := strconv.ParseFloat(apiResponse.Ticker.Price, 64) |
|
if err != nil { |
|
return 0.0, err |
|
} |
|
return result, nil |
|
} |
|
|
|
func isAlpha(s string) bool { |
|
for _, letter := range s { |
|
if !unicode.IsLetter(letter) { |
|
return false |
|
} |
|
} |
|
return true |
|
}
|
|
|