2022-07-04 23:46:12 +00:00
|
|
|
// 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"`
|
|
|
|
}
|
|
|
|
|
2022-07-05 01:44:47 +00:00
|
|
|
type Market struct {
|
|
|
|
Id string `json:"id"`
|
|
|
|
Symbol string `json:"symbol"`
|
|
|
|
Name string `json:"name"`
|
|
|
|
Image string `json:"image"`
|
|
|
|
CurrentPrice float64 `json:"current_price"`
|
|
|
|
MarketCap float64 `json:"market_cap"`
|
|
|
|
MarketCapRank int16 `json:"market_cap_rank"`
|
|
|
|
FullyDilutedValuation string `json:"fully_diluted_valuation"`
|
|
|
|
TotalVolume float64 `json:"total_volume"`
|
|
|
|
High24 float64 `json:"high_24h"`
|
|
|
|
Low24 float64 `json:"low_24h"`
|
|
|
|
PriceChange24h float64 `json:"price_change_24h"`
|
|
|
|
PriceChangePercentage24h float64 `json:"price_change_percentage_24h"`
|
|
|
|
MarketCapChange24h float64 `json:"market_cap_change_24h"`
|
|
|
|
MarketCapChangePercentage24h float64 `json:"market_cap_change_percentage_24h"`
|
|
|
|
CirculatingSupply float64 `json:"circulating_supply"`
|
|
|
|
TotalSupply float64 `json:"total_supply"`
|
|
|
|
MaxSupply float64 `json:"max_supply"`
|
|
|
|
ATH float64 `json:"ath"`
|
|
|
|
ATHChangePercentage float64 `json:"ath_change_percentage"`
|
|
|
|
ATHDate string `json:"ath_date"`
|
|
|
|
ATL float64 `json:"atl"`
|
|
|
|
ATLChangePercentage float64 `json:"atl_change_percentage"`
|
|
|
|
ATLDate string `json:"atl_date"`
|
|
|
|
LastUpdated string `json:"last_updated"`
|
2022-07-04 23:46:12 +00:00
|
|
|
}
|
|
|
|
|
2022-07-05 01:44:47 +00:00
|
|
|
func getIds(query string) []string {
|
2022-07-04 23:46:12 +00:00
|
|
|
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)
|
2022-07-05 01:44:47 +00:00
|
|
|
var returnList []string
|
2022-07-04 23:46:12 +00:00
|
|
|
for _, coin := range *coinList {
|
2022-07-05 01:44:47 +00:00
|
|
|
// get the coingecko ids for the requested coin
|
2022-07-04 23:46:12 +00:00
|
|
|
if coin.Symbol == query {
|
2022-07-05 01:44:47 +00:00
|
|
|
returnList = append(returnList, coin.Id)
|
2022-07-04 23:46:12 +00:00
|
|
|
}
|
|
|
|
}
|
2022-07-05 01:44:47 +00:00
|
|
|
if len(returnList) > 0 {
|
|
|
|
return returnList
|
|
|
|
} else {
|
|
|
|
// fallback to bitcoin
|
|
|
|
returnList = append(returnList, "bitcoin")
|
|
|
|
return returnList
|
|
|
|
}
|
2022-07-04 23:46:12 +00:00
|
|
|
}
|
|
|
|
|
2022-07-05 01:44:47 +00:00
|
|
|
func getData(query []string) string {
|
|
|
|
symbol := strings.Join(query, ",")
|
|
|
|
url := fmt.Sprintf("https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=%s&order=market_cap_desc&per_page=1&page=1&sparkline=false", symbol)
|
2022-07-04 23:46:12 +00:00
|
|
|
req, _ := http.NewRequest("GET", url, nil)
|
|
|
|
req.Header.Set("Accept", "application/json")
|
|
|
|
client := &http.Client{}
|
|
|
|
resp, _ := client.Do(req)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
2022-07-05 01:44:47 +00:00
|
|
|
var coin []*Market
|
2022-07-04 23:46:12 +00:00
|
|
|
json.NewDecoder(resp.Body).Decode(&coin)
|
2022-07-05 01:44:47 +00:00
|
|
|
c := coin[0]
|
|
|
|
const output = `%s (%s)
|
2022-07-05 02:00:44 +00:00
|
|
|
Current Price: $%.4f
|
2022-07-05 01:44:47 +00:00
|
|
|
Market Ca: $%.0f
|
|
|
|
24 Hour Volume: $%.0f
|
2022-07-05 02:00:44 +00:00
|
|
|
24 Hour High: $%.4f
|
|
|
|
24 Hour Low: $%.4f
|
|
|
|
All Time High: $%.4f
|
|
|
|
All Time Low: $%.4f`
|
2022-07-05 01:44:47 +00:00
|
|
|
return fmt.Sprintf(output, c.Id, c.Symbol, c.CurrentPrice, c.MarketCap, c.TotalVolume, c.High24, c.Low24, c.ATH, c.ATL)
|
2022-07-04 23:46:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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) {
|
2022-07-05 01:44:47 +00:00
|
|
|
coinIds := getIds(strings.Join(args, ""))
|
|
|
|
output := getData(coinIds)
|
2022-07-04 23:46:12 +00:00
|
|
|
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),
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|