Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions mybot.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
40 changes: 22 additions & 18 deletions slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -58,15 +55,17 @@ func slackStart(token string) (wsurl, id string, err error) {
if err != nil {
return
}
if resp.StatusCode != 200 {
defer resp.Body.Close()

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
}

var respObj responseRtmStart
err = json.Unmarshal(body, &respObj)
if err != nil {
Expand All @@ -78,20 +77,25 @@ 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"`
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) {
Expand All @@ -102,7 +106,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)
}

Expand Down