-
Notifications
You must be signed in to change notification settings - Fork 906
/
forex.go
145 lines (125 loc) · 4.02 KB
/
forex.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package forex
import (
"encoding/json"
"fmt"
"math"
"net/http"
"sort"
"strings"
"time"
"github.com/botlabs-gg/yagpdb/v2/bot/paginatedmessages"
"github.com/botlabs-gg/yagpdb/v2/commands"
"github.com/botlabs-gg/yagpdb/v2/lib/dcmd"
"github.com/botlabs-gg/yagpdb/v2/lib/discordgo"
"golang.org/x/text/language"
"golang.org/x/text/message"
)
const currenciesAPIURL = "https://api.frankfurter.app/currencies"
const currencyPerPage = 16
var Command = &commands.YAGCommand{
CmdCategory: commands.CategoryFun,
Cooldown: 5,
Name: "Forex",
Aliases: []string{"Money"},
Description: "💱 convert value from one currency to another.",
RunInDM: true,
DefaultEnabled: true,
SlashCommandEnabled: true,
RequiredArgs: 3,
Arguments: []*dcmd.ArgDef{
{Name: "Amount", Type: dcmd.Float}, {Name: "From", Type: dcmd.String}, {Name: "To", Type: dcmd.String},
},
RunFunc: func(data *dcmd.Data) (interface{}, error) {
amount := data.Args[0].Float64()
var currenciesResult Currencies
var exchangeRateResult ExchangeRate
err := requestAPI(currenciesAPIURL, ¤ciesResult)
if err != nil {
return nil, err
}
from := strings.ToUpper(data.Args[1].Str())
to := strings.ToUpper(data.Args[2].Str())
// Check if the currencies exist in the map
_, fromExist := currenciesResult[from]
_, toExist := currenciesResult[to]
// Checks the max amount of pages by the number of symbols on each page
maxPages := int(math.Ceil(float64(len(currenciesResult)) / float64(currencyPerPage)))
// If the currency isn't supported by API.
if !toExist || !fromExist {
_, err = paginatedmessages.CreatePaginatedMessage(
data.GuildData.GS.ID, data.ChannelID, 1, maxPages, func(p *paginatedmessages.PaginatedMessage, page int) (*discordgo.MessageEmbed, error) {
embed, err := errEmbed(currenciesResult, page)
if err != nil {
return nil, err
}
return embed, nil
})
if err != nil {
return nil, err
}
return nil, nil
}
err = requestAPI(fmt.Sprintf("https://api.frankfurter.app/latest?amount=%.3f&from=%s&to=%s", amount, from, to), &exchangeRateResult)
if err != nil {
return nil, err
}
p := message.NewPrinter(language.English)
embed := &discordgo.MessageEmbed{
Title: "💱Currency Exchange Rate",
Description: p.Sprintf("\n%.2f **%s** (%s) is %.3f **%s** (%s).", amount, currenciesResult[from], from, exchangeRateResult.Rates[to], currenciesResult[to], to),
Color: 0xAE27FF,
Timestamp: time.Now().UTC().Format(time.RFC3339),
}
return embed, nil
},
}
func requestAPI(query string, result interface{}) error {
req, err := http.NewRequest("GET", query, nil)
if err != nil {
return err
}
req.Header.Set("User-Agent", "YAGPDB.xyz (https://github.com/botlabs-gg/yagpdb)")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return commands.NewPublicError("Failed to convert, Please verify your input")
}
err = json.NewDecoder(resp.Body).Decode(result)
if err != nil {
return err
}
return nil
}
func errEmbed(currenciesResult Currencies, page int) (*discordgo.MessageEmbed, error) {
desc := "CODE | Description\n------------------"
codes := make([]string, 0, len(currenciesResult))
for k := range currenciesResult {
codes = append(codes, k)
}
sort.Strings(codes)
start := (page * currencyPerPage) - currencyPerPage
end := page * currencyPerPage
for i, c := range codes {
if i < end && i >= start {
desc = fmt.Sprintf("%s\n%s | %s", desc, c, currenciesResult[c])
}
}
embed := &discordgo.MessageEmbed{
Title: "Invalid currency code",
URL: currenciesAPIURL,
Color: 0xAE27FF,
Timestamp: time.Now().UTC().Format(time.RFC3339),
Description: fmt.Sprintf("Check out available codes on: %s ```\n%s```", currenciesAPIURL, desc),
}
return embed, nil
}
type ExchangeRate struct {
Amount float64
Base string
Date string
Rates map[string]float64
}
type Currencies map[string]string