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 }