Last active
June 17, 2016 10:55
-
-
Save nojima/abe58cb445621b4d5ead to your computer and use it in GitHub Desktop.
Slack のロガー。Real Time Messaging API で流れてきた JSON をそのまま標準出力に吐き出す。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// slack-logger/main.go | |
package main | |
import ( | |
"encoding/json" | |
"flag" | |
"fmt" | |
"io" | |
"io/ioutil" | |
"log" | |
"net/http" | |
"net/url" | |
"os" | |
"time" | |
"golang.org/x/net/websocket" | |
) | |
type Config struct { | |
PingInterval int | |
} | |
const ( | |
apiRtmStart = "https://slack.com/api/rtm.start" | |
webSocketOrigin = "https://slack.com" | |
) | |
var ( | |
config Config | |
) | |
func startRtm(token string) (string, error) { | |
resp, err := http.Get(apiRtmStart + "?token=" + url.QueryEscape(token)) | |
if err != nil { | |
return "", err | |
} | |
defer resp.Body.Close() | |
if resp.StatusCode != 200 { | |
return "", fmt.Errorf("rtm.start API failed: %v", resp.Status) | |
} | |
body, err := ioutil.ReadAll(resp.Body) | |
if err != nil { | |
return "", fmt.Errorf("failed to read body of rtm.start: %v", err) | |
} | |
type Result struct { | |
Ok bool | |
Url string | |
} | |
var result Result | |
err = json.Unmarshal(body, &result) | |
if err != nil { | |
return "", fmt.Errorf("failed to unmarshal the body: %v", string(body)) | |
} | |
if !result.Ok { | |
return "", fmt.Errorf("rtm.start API failed: %v", body) | |
} | |
return result.Url, nil | |
} | |
func receiveMessages(ws *websocket.Conn, ch chan<- error) { | |
for { | |
var message string | |
err := websocket.Message.Receive(ws, &message) | |
if err == io.EOF { | |
ch <- nil | |
return | |
} | |
if err != nil { | |
ch <- err | |
return | |
} | |
// Filter "pong" out | |
type Record struct{ Type string } | |
var record Record | |
if err = json.Unmarshal([]byte(message), &record); err == nil { | |
if record.Type == "pong" { | |
continue | |
} | |
} | |
fmt.Println(message) | |
} | |
} | |
func ping(ws *websocket.Conn, ch chan<- error) { | |
for id := 0; ; id++ { | |
message := fmt.Sprintf(`{"id":%v, "type": "ping"}`, id) | |
err := websocket.Message.Send(ws, message) | |
if err != nil { | |
ch <- err | |
return | |
} | |
time.Sleep(time.Duration(config.PingInterval) * time.Second) | |
} | |
} | |
func interact(ws *websocket.Conn) error { | |
ch1 := make(chan error) | |
ch2 := make(chan error) | |
go receiveMessages(ws, ch1) | |
go ping(ws, ch2) | |
select { | |
case err1 := <-ch1: | |
return err1 | |
case err2 := <-ch2: | |
return err2 | |
} | |
} | |
func run(token string) error { | |
url, err := startRtm(token) | |
if err != nil { | |
return err | |
} | |
ws, err := websocket.Dial(url, "", webSocketOrigin) | |
if err != nil { | |
return err | |
} | |
defer ws.Close() | |
log.Println("Connected") | |
return interact(ws) | |
} | |
func main() { | |
flag.IntVar(&config.PingInterval, "ping-interval", 5, "interval between successive pings in seconds") | |
flag.Parse() | |
if flag.NArg() != 1 { | |
fmt.Fprintf(os.Stderr, "Usage: slack-logger [options] TOKEN\n") | |
fmt.Fprintf(os.Stderr, "Options:\n") | |
flag.PrintDefaults() | |
os.Exit(1) | |
} | |
token := flag.Arg(0) | |
err := run(token) | |
if err == nil { | |
log.Fatal(err) | |
} | |
log.Println("Exit") | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# /etc/init/slack-logger.conf | |
# Sample Upstart configuration file. (only in Ubuntu) | |
# You need to create /var/log/slack owned by www-data in advance. | |
description "Slack Logger" | |
author "Yusuke Nojima" | |
start on runlevel [2345] | |
stop on runlevel [!2345] | |
setuid www-data | |
setgid www-data | |
chdir / | |
respawn | |
respawn limit 5 60 | |
exec /home/nojima/go/bin/slack-logger xoxb-XXXXXX-XXXXXXXXXXXXXXXXXXXXXX | rotatelogs /var/log/slack/%Y-%m-%d.log 86400 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment