added currency conversions
This commit is contained in:
94
cmd/convert.go
Normal file
94
cmd/convert.go
Normal file
@ -0,0 +1,94 @@
|
||||
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
|
||||
}
|
||||
24
cmd/types.go
Normal file
24
cmd/types.go
Normal file
@ -0,0 +1,24 @@
|
||||
package cmd
|
||||
|
||||
// CryptApiResponse hold a response for currency conversions, used in !convert
|
||||
type CryptApiResponse struct {
|
||||
Ticker CryptonatorRate `json:"ticker"`
|
||||
Timestamp int `json:"timestamp"`
|
||||
Success bool `json:"success"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
type CryptonatorRate struct {
|
||||
Base string `json:"base"`
|
||||
Target string `json:"target"`
|
||||
Price string `json:"price"`
|
||||
Volume string `json:"volume"`
|
||||
Change string `json:"change"`
|
||||
Markets []CryptonatorMarket `json:"markets,omitempty"`
|
||||
}
|
||||
|
||||
type CryptonatorMarket struct {
|
||||
Market string `json:"market"`
|
||||
Price string `json:"price"`
|
||||
Volume float64 `json:"volume"`
|
||||
}
|
||||
Reference in New Issue
Block a user