Skip to content

Instantly share code, notes, and snippets.

@aki017
Last active October 24, 2016 11:26
Show Gist options
  • Save aki017/c16763788ab92e99fba3dbcbd21d98af to your computer and use it in GitHub Desktop.
Save aki017/c16763788ab92e99fba3dbcbd21d98af to your computer and use it in GitHub Desktop.
Slacktee
package main
import (
"flag"
"fmt"
"io"
"os"
"time"
"github.com/nlopes/slack"
)
type Config struct {
Delimiter byte
Line int
Token string
Channel string
Title string
Interval int
}
func main() {
receiver, finish := readWorker()
str := make([]byte, 1024)
config := getConfig()
backlog := make([]string, config.Line, config.Line)
backlogIndex := 0
api := slack.New(config.Token)
messageTs := ""
interval := time.Tick(time.Duration(config.Interval) * time.Second)
message := "=== " + config.Title + " - Starting ===\n"
postSlackMessage(api, message, &messageTs, config, false)
for {
select {
case <-interval:
message := "=== " + config.Title + " - Working ===\n"
for i := max(0, backlogIndex-config.Line); i <= backlogIndex-1; i++ {
message += fmt.Sprintf("%d: %s\n", i, backlog[i%config.Line])
}
go postSlackMessage(api, message, &messageTs, config, false)
case receive := <-receiver:
if receive == config.Delimiter {
backlog[backlogIndex%config.Line] = string(str)
backlogIndex++
str = make([]byte, 1024)
} else {
str = append(str, receive)
}
case <-finish:
message := "=== " + config.Title + " - Finished ===\n"
if len(str) == 0 {
backlogIndex--
}
for i := max(0, backlogIndex-config.Line+1); i <= backlogIndex; i++ {
message += fmt.Sprintf("%d: %s\n", i, backlog[i%config.Line])
}
postSlackMessage(api, message, &messageTs, config, true)
return
}
}
}
func readWorker() (chan byte, chan bool) {
receiver := make(chan byte)
finish := make(chan bool)
go func() {
reader := io.TeeReader(os.Stdin, os.Stdout)
b := make([]byte, 1, 1)
for {
i, err := reader.Read(b)
if i != 0 {
receiver <- b[0]
}
if err == io.EOF {
finish <- true
break
}
}
}()
return receiver, finish
}
func postSlackMessage(api *slack.Client, message string, messageTs *string, config *Config, finish bool) {
params := slack.NewPostMessageParameters()
params.AsUser = true
var err error
if finish {
api.DeleteMessage(config.Channel, *messageTs)
*messageTs = ""
params.AsUser = false
}
if *messageTs == "" {
config.Channel, *messageTs, err = api.PostMessage(config.Channel, message, params)
} else {
_, _, _, err = api.UpdateMessage(config.Channel, *messageTs, message)
}
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
func getConfig() (config *Config) {
z := flag.Bool("z", false, "Input items are terminated by a null character")
d := flag.String("d", "\n", "Input items are terminated by the specified character")
l := flag.Int("l", 5, "Buffer the specified lines")
token := flag.String("token", os.Getenv("SLACK_TOKEN"), "Slack authentication token")
c := flag.String("c", "", "Slack channel")
hostname, _ := os.Hostname()
t := flag.String("t", fmt.Sprintf("%s.%d", hostname, os.Getpid()), "Title")
interval := flag.Int("i", 3, "Slack refresh interval")
flag.Parse()
if *z && *d != "\n" {
panic("z or d")
}
config = &Config{}
if *z {
config.Delimiter = 0
} else {
config.Delimiter = ([]byte)(*d)[0]
}
config.Line = *l
config.Token = *token
config.Channel = *c
config.Title = *t
config.Interval = *interval
return
}
func max(x, y int) int {
if x > y {
return x
}
return y
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment