stock checker

This commit is contained in:
skiesel 2019-06-07 14:32:20 -04:00
parent 50dfc71269
commit d372541735
3 changed files with 141 additions and 0 deletions

View File

@ -37,6 +37,7 @@ import (
"github.com/velour/catbase/plugins/rpgORdie"
"github.com/velour/catbase/plugins/rss"
"github.com/velour/catbase/plugins/sisyphus"
"github.com/velour/catbase/plugins/stock"
"github.com/velour/catbase/plugins/talker"
"github.com/velour/catbase/plugins/tell"
"github.com/velour/catbase/plugins/tldr"
@ -122,6 +123,7 @@ func main() {
b.AddPlugin(couldashouldawoulda.New(b))
b.AddPlugin(nerdepedia.New(b))
b.AddPlugin(tldr.New(b))
b.AddPlugin(stock.New(b))
b.AddPlugin(cli.New(b))
// catches anything left, will always return true
b.AddPlugin(fact.New(b))

94
plugins/stock/stock.go Normal file
View File

@ -0,0 +1,94 @@
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 ...interface{}) 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]
cleaned := strings.ReplaceAll(string(body), " ", "")
regex := regexp.MustCompile("[0-9][0-9]\\.")
cleaned = regex.ReplaceAllString(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 ...interface{}) bool {
p.bot.Send(c, bot.Message, message.Channel, "try '!stock-price SYMBOL'")
return true
}

View File

@ -0,0 +1,45 @@
package stock
import (
"github.com/velour/catbase/plugins/cli"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/velour/catbase/bot"
"github.com/velour/catbase/bot/msg"
"github.com/velour/catbase/bot/user"
)
func makeMessage(payload string) (bot.Connector, bot.Kind, msg.Message) {
isCmd := strings.HasPrefix(payload, "!")
if isCmd {
payload = payload[1:]
}
return &cli.CliPlugin{}, bot.Message, msg.Message{
User: &user.User{Name: "tester"},
Channel: "test",
Body: payload,
Command: isCmd,
}
}
func TestValid(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
res := c.message(makeMessage("!stock-price TWTR"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "TWTR : $")
}
func TestInvalid(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
res := c.message(makeMessage("!stock-price NOTREAL"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "Failed to retrieve data for stock symbol: NOTREAL")
}