Skip to content

Instantly share code, notes, and snippets.

@goldeneggg
Created August 3, 2015 12:29
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save goldeneggg/30715aaa922467598ab3 to your computer and use it in GitHub Desktop.
Save goldeneggg/30715aaa922467598ab3 to your computer and use it in GitHub Desktop.
WebSocket message receiver client for Slack
package main
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
"os/signal"
"syscall"
"golang.org/x/net/websocket"
)
const (
Version = "0.1.0"
URLRTMStart = "https://slack.com/api/rtm.start"
originURL = "http://localhost/"
)
var (
token = flag.String("t", "", "token")
help = flag.Bool("h", false, "Show help message")
args = flag.Args
)
func main() {
var sts int
defer func() { os.Exit(sts) }()
flag.Parse()
if *help {
printHelp()
return
}
// slack websocket URL by API token for your bot
websocketURL, err := getWebSocketURL(*token)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to getWebSocketURL: %+v\n", err)
sts = 1
return
}
// connect websocket
ws, err := websocket.Dial(websocketURL, "", originURL)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to websocket.Dial: %+v\n", err)
sts = 1
return
}
defer ws.Close()
// start redeiver of Slack Real Time Message
chWsRecv := make(chan string)
defer close(chWsRecv)
go receiver(ws, chWsRecv)
chSig := make(chan os.Signal)
defer close(chSig)
signal.Notify(chSig, os.Interrupt, syscall.SIGTERM)
// wait received message
for {
select {
case <-chSig:
fmt.Fprintln(os.Stderr, "CTRL-C; exiting by SIGTERM")
sts = 1
return
case msg, ok := <-chWsRecv:
if !ok {
fmt.Fprintf(os.Stderr, "Message receive returned false: %v", msg)
sts = 1
return
}
// TODO write process using receive message
fmt.Printf("[RECEIVE] msg: %s\n", msg)
}
}
}
func getWebSocketURL(token string) (string, error) {
values := url.Values{}
values.Add("token", token)
resp, err := http.PostForm(URLRTMStart, values)
if err != nil {
return "", err
}
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
var v interface{}
err = json.Unmarshal(b, &v)
if err != nil {
return "", err
}
m, ok := v.(map[string]interface{})
if !ok {
return "", fmt.Errorf("API response is not map type\n")
}
u, ok := m["url"]
if !ok {
return "", fmt.Errorf("API response does not have websocket url param\n")
}
return u.(string), nil
}
func receiver(ws *websocket.Conn, chWsRecv chan string) {
for {
var recvMsg string
websocket.Message.Receive(ws, &recvMsg)
chWsRecv <- recvMsg
}
}
func printHelp() {
h := `
Usage:
slackrtm [OTHER OPTIONS]
Application Options:
-t Your API token
Help Options:
-h, --help Show this help message
`
os.Stderr.Write([]byte(h))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment