-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathserver.go
114 lines (101 loc) · 2.79 KB
/
server.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
package traqbot
import (
"encoding/json"
"net/http"
"strings"
)
const (
contentTypeHeader = "Content-Type"
mimeApplicationJson = "application/json"
botTokenHeader = "X-TRAQ-BOT-TOKEN"
botEventHeader = "X-TRAQ-BOT-EVENT"
)
// EventHandler イベントハンドラ
type EventHandler func(event string, payload interface{})
// EventHandlers イベントハンドラマップ
type EventHandlers map[string]EventHandler
// BotServer BOTサーバー
type BotServer struct {
verificationToken string
handlers EventHandlers
}
// NewBotServer 新しくBOTサーバーを生成します
func NewBotServer(verification string, handlers EventHandlers) *BotServer {
return &BotServer{
verificationToken: verification,
handlers: handlers,
}
}
// ListenAndServe BOTサーバーを起動します
func (bs *BotServer) ListenAndServe(addr string) error {
mux := http.NewServeMux()
mux.Handle("/", bs)
server := &http.Server{Addr: addr, Handler: mux}
return server.ListenAndServe()
}
// ServeHTTP BOTサーバーハンドラ
func (bs *BotServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
// VerificationTokenチェック
if req.Header.Get(botTokenHeader) != bs.verificationToken {
rw.WriteHeader(http.StatusForbidden)
return
}
// Eventヘッダチェック
event := req.Header.Get(botEventHeader)
if len(event) == 0 {
rw.WriteHeader(http.StatusBadRequest)
return
}
// RequestがJSONかどうか
if !strings.HasPrefix(req.Header.Get(contentTypeHeader), mimeApplicationJson) {
rw.WriteHeader(http.StatusBadRequest)
return
}
var payload interface{}
switch event {
case Ping:
payload = &PingPayload{}
case Joined:
payload = &JoinedPayload{}
case Left:
payload = &LeftPayload{}
case MessageCreated:
payload = &MessageCreatedPayload{}
case MessageUpdated:
payload = &MessageUpdatedPayload{}
case MessageDeleted:
payload = &MessageDeletedPayload{}
case BotMessageStampsUpdated:
payload = &BotMessageStampsUpdatedPayload{}
case DirectMessageCreated:
payload = &DirectMessageCreatedPayload{}
case DirectMessageUpdated:
payload = &DirectMessageUpdatedPayload{}
case DirectMessageDeleted:
payload = &DirectMessageDeletedPayload{}
case ChannelCreated:
payload = &ChannelCreatedPayload{}
case ChannelTopicChanged:
payload = &ChannelTopicChangedPayload{}
case UserCreated:
payload = &UserCreatedPayload{}
case StampCreated:
payload = &StampCreatedPayload{}
case TagAdded:
payload = &TagAddedPayload{}
case TagRemoved:
payload = &TagRemovedPayload{}
default:
rw.WriteHeader(http.StatusNotImplemented)
return
}
if err := json.NewDecoder(req.Body).Decode(payload); err != nil {
rw.WriteHeader(http.StatusBadRequest)
return
}
rw.WriteHeader(http.StatusNoContent)
h, ok := bs.handlers[event]
if ok && h != nil {
h(event, payload)
}
}