97 lines
2.6 KiB
Go
97 lines
2.6 KiB
Go
|
// Package coingecko implements a Service which returns price info on cryptocurrencies from coingecko
|
||
|
package coingecko
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"net/http"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/matrix-org/go-neb/types"
|
||
|
mevt "maunium.net/go/mautrix/event"
|
||
|
"maunium.net/go/mautrix/id"
|
||
|
)
|
||
|
|
||
|
// ServiceType of the coingecko service
|
||
|
const ServiceType = "coingecko"
|
||
|
|
||
|
// Service represents the coingecko service. It has no Config fields.
|
||
|
type Service struct {
|
||
|
types.DefaultService
|
||
|
}
|
||
|
|
||
|
type CoinList struct {
|
||
|
Id string `json:"id"`
|
||
|
Symbol string `json:"symbol"`
|
||
|
Name string `json:"name"`
|
||
|
}
|
||
|
|
||
|
type MarketChart struct {
|
||
|
Prices [][]float32 `json:"prices"`
|
||
|
MarketCaps [][]float32 `json:"market_caps"`
|
||
|
TotalVolumes [][]float32 `json:"total_volumes"`
|
||
|
}
|
||
|
|
||
|
func getId(query string) string {
|
||
|
req, _ := http.NewRequest("GET", "https://api.coingecko.com/api/v3/coins/list", nil)
|
||
|
req.Header.Set("Accept", "application/json")
|
||
|
client := &http.Client{}
|
||
|
resp, _ := client.Do(req)
|
||
|
defer resp.Body.Close()
|
||
|
|
||
|
var coinList *[]CoinList
|
||
|
json.NewDecoder(resp.Body).Decode(&coinList)
|
||
|
for _, coin := range *coinList {
|
||
|
// get the coingecko id for the requested coin
|
||
|
if coin.Symbol == query {
|
||
|
return coin.Id
|
||
|
}
|
||
|
}
|
||
|
// fallback to bitcoin
|
||
|
return "bitcoin"
|
||
|
}
|
||
|
|
||
|
func getData(query string) string {
|
||
|
url := fmt.Sprintf("https://api.coingecko.com/api/v3/coins/%s/market_chart?vs_currency=usd&days=1", query)
|
||
|
req, _ := http.NewRequest("GET", url, nil)
|
||
|
req.Header.Set("Accept", "application/json")
|
||
|
client := &http.Client{}
|
||
|
resp, _ := client.Do(req)
|
||
|
defer resp.Body.Close()
|
||
|
|
||
|
var coin *MarketChart
|
||
|
json.NewDecoder(resp.Body).Decode(&coin)
|
||
|
|
||
|
latestPrice := coin.Prices[len(coin.Prices)-1][1]
|
||
|
marketCap := coin.MarketCaps[len(coin.MarketCaps)-1][1]
|
||
|
totalVol := coin.TotalVolumes[len(coin.TotalVolumes)-1][1]
|
||
|
return fmt.Sprintf("%s -- Price: $%f, Market Cap: $%.0f, 24hr Volume: $%.0f", query, latestPrice, marketCap, totalVol)
|
||
|
}
|
||
|
|
||
|
// Commands supported:
|
||
|
// !coingecko SYMBOL
|
||
|
// Responds with price data on the currency
|
||
|
func (e *Service) Commands(cli types.MatrixClient) []types.Command {
|
||
|
return []types.Command{
|
||
|
{
|
||
|
Path: []string{"cc"},
|
||
|
Command: func(roomID id.RoomID, userID id.UserID, args []string) (interface{}, error) {
|
||
|
coinId := getId(strings.Join(args, ""))
|
||
|
output := getData(coinId)
|
||
|
return &mevt.MessageEventContent{
|
||
|
MsgType: mevt.MsgNotice,
|
||
|
Body: output,
|
||
|
}, nil
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func init() {
|
||
|
types.RegisterService(func(serviceID string, serviceUserID id.UserID, webhookEndpointURL string) types.Service {
|
||
|
return &Service{
|
||
|
DefaultService: types.NewDefaultService(serviceID, serviceUserID, ServiceType),
|
||
|
}
|
||
|
})
|
||
|
}
|