@@ -4,11 +4,11 @@ import (
44 "context"
55 "errors"
66 "fmt"
7- "log"
87 "math"
98 "strings"
109
1110 finnhub "github.com/Finnhub-Stock-API/finnhub-go/v2"
11+ "github.com/rs/zerolog"
1212 "github.com/seabird-chat/seabird-go"
1313 "github.com/seabird-chat/seabird-go/pb"
1414)
@@ -42,10 +42,11 @@ type SeabirdClient struct {
4242 context.Context
4343 * seabird.Client
4444 finnhubClient * finnhub.DefaultApiService
45+ logger zerolog.Logger
4546}
4647
4748// NewSeabirdClient returns a new seabird client
48- func NewSeabirdClient (seabirdCoreURL , seabirdCoreToken , finnhubToken string ) (* SeabirdClient , error ) {
49+ func NewSeabirdClient (seabirdCoreURL , seabirdCoreToken , finnhubToken string , logger zerolog. Logger ) (* SeabirdClient , error ) {
4950 seabirdClient , err := seabird .NewClient (seabirdCoreURL , seabirdCoreToken )
5051 if err != nil {
5152 return nil , err
@@ -58,27 +59,36 @@ func NewSeabirdClient(seabirdCoreURL, seabirdCoreToken, finnhubToken string) (*S
5859 Context : context .Background (),
5960 Client : seabirdClient ,
6061 finnhubClient : finnhub .NewAPIClient (finnhubCfg ).DefaultApi ,
62+ logger : logger ,
6163 }, nil
6264}
6365
6466func (c * SeabirdClient ) close () error {
6567 return c .Client .Close ()
6668}
6769
70+ func (c * SeabirdClient ) reply (source * pb.ChannelSource , format string , args ... interface {}) {
71+ if err := c .MentionReplyf (source , format , args ... ); err != nil {
72+ c .logger .Error ().Err (err ).Str ("channel_id" , source .GetChannelId ()).Msg ("failed to send reply" )
73+ }
74+ }
75+
6876func (c * SeabirdClient ) stockCallback (event * pb.CommandEvent ) {
69- // TODO: Request debugging
70- log .Printf ("Processing event: %s %s %s" , event .Source , event .Command , event .Arg )
7177 ticker := strings .ToUpper (strings .TrimSpace (event .Arg ))
7278
79+ cmdLog := c .logger .With ().
80+ Str ("command" , event .Command ).
81+ Str ("ticker" , ticker ).
82+ Str ("channel_id" , event .Source .GetChannelId ()).
83+ Logger ()
84+
7385 profile2 , _ , err := c .finnhubClient .CompanyProfile2 (c .Context ).Symbol (ticker ).Execute ()
7486 if err != nil {
75- // TODO: What do we do with the error?
76- log . Println ( err )
87+ cmdLog . Error (). Err ( err ). Msg ( "finnhub CompanyProfile2 failed" )
88+ c . reply ( event . Source , "Unable to look up %s." , ticker )
7789 return
7890 }
7991
80- log .Printf ("profile2 is: %+v\n " , profile2 )
81-
8292 // If Finnhub fails to find ticker, we get a 200 back with empty values, so
8393 // we set a default ticker/company and only use the profile response if it
8494 // has valid values.
@@ -97,30 +107,31 @@ func (c *SeabirdClient) stockCallback(event *pb.CommandEvent) {
97107 // only consistent way to determine if a stock actually exists.
98108 if err != nil || quoteResp .ContentLength != - 1 {
99109 if err != nil {
100- log .Println (err )
110+ cmdLog .Error ().Err (err ).Msg ("finnhub Quote failed" )
111+ c .reply (event .Source , "Unable to fetch quote for %s." , ticker )
101112 return
102113 }
103- c .MentionReplyf (event .Source , "Unable to find %s." , ticker )
104- } else {
105- // TODO: Don't hardcoded USD here - currency requires premium https://finnhub.io/docs/api#company-profile
106- if event .Command == "stonk" || event .Command == "stonks" {
107- stonks := "is STONKS ↗️"
108- sign := stonkReplacements ["+" ]
109- if * quote .C <= * quote .O {
110- stonks = "is NOT STONKS ↘️"
111- sign = stonkReplacements ["-" ]
112- }
113-
114- current := stonkify (fmt .Sprintf ("$%.2f" , * quote .C ))
115- change := stonkify (fmt .Sprintf ("%.2f" , math .Abs (float64 (* quote .C )- float64 (* quote .O ))))
114+ c .reply (event .Source , "Unable to find %s." , ticker )
115+ return
116+ }
116117
117- c .MentionReplyf (event .Source , "%s %s. %s (%s%s)" , company , stonks , current , sign , change )
118- } else {
119- percentChange := ((* quote .C - * quote .O ) / * quote .O ) * 100
120- c .MentionReplyf (event .Source , "%s - Open: $%.2f, Current: $%.2f (%+.2f%%)" , company , * quote .O , * quote .C , percentChange )
118+ // TODO: Don't hardcoded USD here - currency requires premium https://finnhub.io/docs/api#company-profile
119+ if event .Command == "stonk" || event .Command == "stonks" {
120+ stonks := "is STONKS ↗️"
121+ sign := stonkReplacements ["+" ]
122+ if * quote .C <= * quote .O {
123+ stonks = "is NOT STONKS ↘️"
124+ sign = stonkReplacements ["-" ]
121125 }
122- }
123126
127+ current := stonkify (fmt .Sprintf ("$%.2f" , * quote .C ))
128+ change := stonkify (fmt .Sprintf ("%.2f" , math .Abs (float64 (* quote .C )- float64 (* quote .O ))))
129+
130+ c .reply (event .Source , "%s %s. %s (%s%s)" , company , stonks , current , sign , change )
131+ } else {
132+ percentChange := ((* quote .C - * quote .O ) / * quote .O ) * 100
133+ c .reply (event .Source , "%s - Open: $%.2f, Current: $%.2f (%+.2f%%)" , company , * quote .O , * quote .C , percentChange )
134+ }
124135}
125136
126137// Run runs
@@ -136,7 +147,8 @@ func (c *SeabirdClient) Run() error {
136147 return err
137148 }
138149
139- defer events .Close ()
150+ c .logger .Info ().Msg ("event stream open" )
151+
140152 for event := range events .C {
141153 switch v := event .GetInner ().(type ) {
142154 case * pb.Event_Command :
@@ -146,5 +158,9 @@ func (c *SeabirdClient) Run() error {
146158 }
147159 }
148160 }
149- return errors .New ("event stream closed" )
161+
162+ if closeErr := events .Close (); closeErr != nil {
163+ return fmt .Errorf ("event stream closed: %w" , closeErr )
164+ }
165+ return errors .New ("event stream closed without error" )
150166}
0 commit comments