From 4b3f735e15de7a94f50423cdd61f4d0cdcf7914b Mon Sep 17 00:00:00 2001 From: James Bowman Date: Fri, 1 May 2015 18:53:30 +0100 Subject: [PATCH] improved comments for godoc --- connect.go | 3 +++ connection.go | 8 ++++++-- message.go | 23 ++++++++++++++++++++--- processor.go | 33 +++++++++++++++++++++------------ 4 files changed, 50 insertions(+), 17 deletions(-) diff --git a/connect.go b/connect.go index 26a0aed..96c8cfe 100644 --- a/connect.go +++ b/connect.go @@ -10,6 +10,7 @@ import ( "net/url" ) +// Authenticate with Slack to retrieve websocket connection URL. func handshake(apiUrl string, token string) (*Config, error) { resp, err := http.PostForm(apiUrl, url.Values{"token": {token}}) @@ -39,6 +40,7 @@ func handshake(apiUrl string, token string) (*Config, error) { return &data, nil } +// Authenticate with Slack and upgrade to websocket connection func connectAndUpgrade(url string, token string) (*Config, *websocket.Conn, error) { config, err := handshake(url, token) @@ -55,6 +57,7 @@ func connectAndUpgrade(url string, token string) (*Config, *websocket.Conn, erro return config, conn, nil } +// Connect to Slack using the supplied authentication token func Connect(token string) (*Connection, error) { apiStartUrl := "https://slack.com/api/rtm.start" diff --git a/connection.go b/connection.go index 883636d..f085b4b 100644 --- a/connection.go +++ b/connection.go @@ -22,12 +22,15 @@ const ( maxMessageSize = 1024 ) +// Connection type represents the duplex websocket connection to Slack type Connection struct { // The websocket connection. ws *websocket.Conn - // Concurrency synchronisation for automatic reconnection. - wg sync.WaitGroup + // waitgroup to wait for all go routines to terminate before attempting to reconnect. + wg sync.WaitGroup + + // channel used to signal termination to socket writer go routine. finish chan struct{} // Buffered channel of outbound messages. @@ -36,6 +39,7 @@ type Connection struct { // Buffered channel of inbound messages. in chan []byte + // information about the current Slack connection and team settings. config Config } diff --git a/message.go b/message.go index 2171ef8..9fd0c49 100644 --- a/message.go +++ b/message.go @@ -1,43 +1,60 @@ package slack +// eventer interface represents a pipe along which messages can be sent type eventer interface { + // Write the message to the specified channel Write(string, string) error } +// Message type represents a message received from Slack type Message struct { + // a pipe for sending responses to this message eventStream eventer + // the strategy for sending the response - depending upon how the message was received e.g. a reply if + // addressed specifically to the bot or a send if not responseStrategy func(*Message, string) error + // the text content of the message Text string + + // the name of the user whom the message is from From string - fromId string + // id of the user the message is from + fromId string + + // channel on which the message was received channel string } -//type responder func(string) - +// Send a new message on the specified channel func (m *Message) Tell(channel string, text string) error { return m.eventStream.Write(channel, text) } +// Send a new message on the channel this message was received on func (m *Message) Send(text string) error { return m.eventStream.Write(m.channel, text) } +// Send a reply to the user who sent this message on the same channel it was received on func (m *Message) Reply(text string) error { return m.Send("<@" + m.fromId + ">: " + text) } +// Send a message in a way that matches the way in which this message was received e.g. +// if this message was addressed then send a reply back to person who sent the message. func (m *Message) Respond(text string) error { return m.responseStrategy(m, text) } +// response strategy for replying func reply(m *Message, text string) error { return m.Reply(text) } +// response strategy for sending func send(m *Message, text string) error { return m.Send(text) } diff --git a/processor.go b/processor.go index 3d9fef2..ac85a1f 100644 --- a/processor.go +++ b/processor.go @@ -7,28 +7,30 @@ import ( "regexp" ) -type eventReadWriter interface { - Write([]byte) - Read() []byte -} - -type event struct { - Id int `json:"id"` - Type string `json:"type"` - Channel string `json:"channel"` - Text string `json:"text"` -} - +// Processor type processes inbound events from Slack type Processor struct { + // Connection to Slack con *Connection + // Slack user information relating to the bot account self User + // a sequence number to uniquely identify sent messages and correlate with acks from Slack sequence int + // map of event handler functions to handle types of Slack event eventHandlers map[string]func(*Processor, map[string]interface{}) } +// event type represents an event sent to Slack e.g. messages +type event struct { + Id int `json:"id"` + Type string `json:"type"` + Channel string `json:"channel"` + Text string `json:"text"` +} + +// send Event to Slack func (p *Processor) sendEvent(eventType string, channel string, text string) error { p.sequence++ @@ -44,10 +46,12 @@ func (p *Processor) sendEvent(eventType string, channel string, text string) err return nil } +// Write the message on the specified channel to Slack func (p *Processor) Write(channel string, text string) error { return p.sendEvent("message", channel, text) } +// Start processing events from Slack func (p *Processor) Start() { for { msg := p.con.Read() @@ -92,8 +96,11 @@ func (p *Processor) Start() { } } +// type for callbacks to receive messages from Slack type messageProcessor func(*Message) +// Starts processing events on the connection from Slack and passes any messages to the hear callback and only +// messages addressed to the bot to the respond callback func EventProcessor(con *Connection, respond messageProcessor, hear messageProcessor) { p := Processor{ con: con, @@ -108,6 +115,7 @@ func EventProcessor(con *Connection, respond messageProcessor, hear messageProce p.Start() } +// finds the full name of the Slack user for the specified user ID func findUser(config Config, user string) (string, bool) { var users []User @@ -122,6 +130,7 @@ func findUser(config Config, user string) (string, bool) { return "", false } +// Invoke one of the specified callbacks for the message if appropriate func filterMessage(p *Processor, data map[string]interface{}, respond messageProcessor, hear messageProcessor) { var userFullName string var userId string