forked from recursionpharma/anonymous-slack
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
136 lines (121 loc) · 3.13 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
)
const (
tokenConfig = "INCOMING_SLACK_TOKEN"
webhookConfig = "INCOMING_SLACK_WEBHOOK"
// Incoming payload form will have the following keys:
// (See: https://api.slack.com/slash-commands)
keyToken = "token"
keyTeamID = "team_id"
keyChannelID = "channel_id"
keyChannelName = "channel_name"
keyUserID = "user_id"
keyUserName = "user_name"
keyCommand = "command"
keyText = "text"
slackchannel = "#assassins"
)
type slackMsg struct {
Text string `json:"text"`
Username string `json:"username"`
Channel string `json:"channel"` // Recipient
AsUser string `json:"as_user"`
IconURL string `json:"icon_url"`
LinkNames string `json:"link_names"`
}
var (
port int
assassins = make(map[string][]string)
icon string
name string
)
// readAnonymousMessage parses the username and re-routes
// the message to the user from an anonymous animal
func readAnonymousMessage(r *http.Request) string {
err := r.ParseForm()
// TODO: Change HTTP status code
if err != nil {
return string(err.Error())
}
// Incoming POST's token should match the one set in Heroku
if len(r.Form[keyToken]) == 0 || r.Form[keyToken][0] != os.Getenv(tokenConfig) {
return "Config error."
}
if len(r.Form[keyText]) == 0 {
return "Slack bug; inform the team."
}
msg := strings.TrimSpace(r.Form[keyText][0])
user := r.Form[keyUserName][0]
err = sendAnonymousMessage(user, msg)
if err != nil {
return "Failed to send message."
}
fmt.Printf("%s posted %s", user, msg)
return fmt.Sprintf("Posted secretly to %s", slackchannel)
}
// sendAnonymousMessage uses an incoming hook to Direct Message
// the given user the message, from the registered assassin
func sendAnonymousMessage(username, message string) error {
url := os.Getenv(webhookConfig)
if len(assassins[username]) != 0 {
icon = assassins[username][1]
name = assassins[username][0]
} else {
icon = "https://38.media.tumblr.com/avatar_a9b397fda01a_128.png"
name = "Civilian"
}
payload, err := json.Marshal(slackMsg{
Text: message,
Channel: slackchannel,
AsUser: "False",
IconURL: icon,
LinkNames: "1",
Username: name,
})
if err != nil {
return err
}
_, err = http.Post(url, "application/json", bytes.NewBuffer(payload))
return err
}
func main() {
getAssassins()
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
result := readAnonymousMessage(r)
fmt.Fprintf(w, result)
})
http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
}
func init() {
flag.IntVar(&port, "port", 5000, "HTTP server port")
flag.Parse()
}
// Assassin data structure
type Assassin struct {
Username string `json:"username"`
AssassinName string `json:"assassin_name"`
IconURL string `json:"icon_url"`
}
func getAssassins() []Assassin {
raw, err := ioutil.ReadFile("./assassins.json")
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
var c []Assassin
json.Unmarshal(raw, &c)
for _, p := range c {
fmt.Println(p.Username)
assassins[p.Username] = []string{p.AssassinName, p.IconURL}
}
return c
}