From 7c29dc664f7f75e5a92eaa6760f7f6f0e6424527 Mon Sep 17 00:00:00 2001 From: nhyland Date: Sat, 15 Oct 2016 17:40:18 -0700 Subject: [PATCH 1/4] Small code refactor, fixed possible crash --- slack.go | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/slack.go b/slack.go index 3ef645c..82b0f36 100644 --- a/slack.go +++ b/slack.go @@ -36,18 +36,15 @@ import ( "golang.org/x/net/websocket" ) -// These two structures represent the response of the Slack API rtm.start. +// responseRtmStart represent the response of the Slack API rtm.start. // Only some fields are included. The rest are ignored by json.Unmarshal. - type responseRtmStart struct { - Ok bool `json:"ok"` - Error string `json:"error"` - Url string `json:"url"` - Self responseSelf `json:"self"` -} - -type responseSelf struct { - Id string `json:"id"` + Ok bool `json:"ok"` + Error string `json:"error"` + URL string `json:"url"` + Self struct { + ID string `json:"id"` + } `json:"self"` } // slackStart does a rtm.start, and returns a websocket URL and user ID. The @@ -58,15 +55,16 @@ func slackStart(token string) (wsurl, id string, err error) { if err != nil { return } - if resp.StatusCode != 200 { + if resp.StatusCode != http.StatusOK { err = fmt.Errorf("API request failed with code %d", resp.StatusCode) return } body, err := ioutil.ReadAll(resp.Body) - resp.Body.Close() if err != nil { return } + defer resp.Body.Close() + var respObj responseRtmStart err = json.Unmarshal(body, &respObj) if err != nil { @@ -78,17 +76,16 @@ func slackStart(token string) (wsurl, id string, err error) { return } - wsurl = respObj.Url - id = respObj.Self.Id + wsurl = respObj.URL + id = respObj.Self.ID return } -// These are the messages read off and written into the websocket. Since this +// Message represents the messages read off and written into the websocket. Since this // struct serves as both read and write, we include the "Id" field which is // required only for writing. - type Message struct { - Id uint64 `json:"id"` + ID uint64 `json:"id"` Type string `json:"type"` Channel string `json:"channel"` Text string `json:"text"` @@ -102,7 +99,7 @@ func getMessage(ws *websocket.Conn) (m Message, err error) { var counter uint64 func postMessage(ws *websocket.Conn, m Message) error { - m.Id = atomic.AddUint64(&counter, 1) + m.ID = atomic.AddUint64(&counter, 1) return websocket.JSON.Send(ws, m) } From 6dea22cdf8fc8e514848515cad80ae627e028137 Mon Sep 17 00:00:00 2001 From: nhyland Date: Sat, 15 Oct 2016 18:11:00 -0700 Subject: [PATCH 2/4] moved deferred close. --- slack.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/slack.go b/slack.go index 82b0f36..9d5f359 100644 --- a/slack.go +++ b/slack.go @@ -55,6 +55,8 @@ func slackStart(token string) (wsurl, id string, err error) { if err != nil { return } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { err = fmt.Errorf("API request failed with code %d", resp.StatusCode) return @@ -63,7 +65,6 @@ func slackStart(token string) (wsurl, id string, err error) { if err != nil { return } - defer resp.Body.Close() var respObj responseRtmStart err = json.Unmarshal(body, &respObj) From 6b6a4acfa8bae72747db894a77efdf76479e49af Mon Sep 17 00:00:00 2001 From: nhyland Date: Mon, 17 Oct 2016 08:47:30 -0700 Subject: [PATCH 3/4] Added user to Message struct --- slack.go | 1 + 1 file changed, 1 insertion(+) diff --git a/slack.go b/slack.go index 9d5f359..54e2bdb 100644 --- a/slack.go +++ b/slack.go @@ -89,6 +89,7 @@ type Message struct { ID uint64 `json:"id"` Type string `json:"type"` Channel string `json:"channel"` + User string `json:"user"` Text string `json:"text"` } From 000d82fe4e9804fc8b1216d56701e11e53fd7775 Mon Sep 17 00:00:00 2001 From: nhyland Date: Mon, 17 Oct 2016 08:51:53 -0700 Subject: [PATCH 4/4] Added error handling. --- mybot.go | 6 ++++++ slack.go | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/mybot.go b/mybot.go index d59be84..172a029 100644 --- a/mybot.go +++ b/mybot.go @@ -51,6 +51,12 @@ func main() { log.Fatal(err) } + // if there is an error returned, report it and skip this loop. + if m.Type == "error" { + log.Println(fmt.Errorf("error from Slack on getMessage: code %v\t%s\n", m.Error.Code, m.Error.Message)) + continue + } + // see if we're mentioned if m.Type == "message" && strings.HasPrefix(m.Text, "<@"+id+">") { // if so try to parse if diff --git a/slack.go b/slack.go index 54e2bdb..9873173 100644 --- a/slack.go +++ b/slack.go @@ -91,6 +91,11 @@ type Message struct { Channel string `json:"channel"` User string `json:"user"` Text string `json:"text"` + Error struct { + // Error is only populated if an error is present. Check for type == "error" + Code int `json:"code"` + Message string `json:"message"` + } `json:"error"` } func getMessage(ws *websocket.Conn) (m Message, err error) {