catbase/plugins/stock/stock.go

95 lines
2.3 KiB
Go

package stock
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"regexp"
"strings"
"github.com/rs/zerolog/log"
"github.com/velour/catbase/bot"
"github.com/velour/catbase/bot/msg"
)
type StockPlugin struct {
bot bot.Bot
apiKey string
}
func New(b bot.Bot) *StockPlugin {
s := &StockPlugin{
bot: b,
apiKey: b.Config().GetString("Stock.API_KEY", "0E1DP61SJ7GF81IE"),
}
b.Register(s, bot.Message, s.message)
b.Register(s, bot.Help, s.help)
return s
}
type GlobalQuote struct {
Info StockInfo `json:"GlobalQuote"`
}
type StockInfo struct {
Symbol string `json:"symbol"`
Open string `json:"open"`
High string `json:"high"`
Low string `json:"low"`
Price string `json:"price"`
Volume string `json:"volume"`
LatestTradingDay string `json:"latesttradingday"`
PreviousClose string `json:"previousclose"`
Change string `json:"change"`
ChangePercent string `json:"changepercent"`
}
func (p *StockPlugin) message(c bot.Connector, kind bot.Kind, message msg.Message, args ...any) bool {
if !message.Command {
return false
}
tokens := strings.Fields(message.Body)
numTokens := len(tokens)
if numTokens == 2 && strings.ToLower(tokens[0]) == "stock-price" {
query := fmt.Sprintf("https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=%s&apikey=%s", tokens[1], p.apiKey)
resp, err := http.Get(query)
if err != nil {
log.Fatal().Err(err).Msg("Failed to get stock info")
}
body, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
log.Fatal().Err(err).Msg("Error stock info body")
}
response := "Failed to retrieve data for stock symbol: " + tokens[1]
regex := regexp.MustCompile("[0-9][0-9]\\. ")
cleaned := regex.ReplaceAllString(string(body), "")
cleaned = strings.ReplaceAll(cleaned, " ", "")
var info GlobalQuote
err = json.Unmarshal([]byte(cleaned), &info)
if err == nil && strings.EqualFold(tokens[1], info.Info.Symbol) {
response = fmt.Sprintf("%s : $%s (%s)", tokens[1], info.Info.Price, info.Info.ChangePercent)
}
p.bot.Send(c, bot.Message, message.Channel, response)
return true
}
return false
}
func (p *StockPlugin) help(c bot.Connector, kind bot.Kind, message msg.Message, args ...any) bool {
p.bot.Send(c, bot.Message, message.Channel, "try '!stock-price SYMBOL'")
return true
}