This repository has been archived by the owner on Feb 25, 2024. It is now read-only.
/
router.go
123 lines (104 loc) · 2.83 KB
/
router.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
// Copyright (C) 2021 The Dank Grinder authors.
//
// This source code has been released under the GNU Affero General Public
// License v3.0. A copy of this license is available at
// https://www.gnu.org/licenses/agpl-3.0.en.html
package discord
import (
"fmt"
"regexp"
"strings"
)
type MessageRouter struct {
routes []*MessageRoute
middleware []func(h HandlerFunc) HandlerFunc
}
type MessageRoute struct {
conds []condFunc
handler HandlerFunc
}
type HandlerFunc func(msg Message)
type condFunc func(msg Message, eventType string) bool
func (rtr *MessageRouter) process(msg Message, eventType string) {
for _, rt := range rtr.routes {
if rt.matches(msg, eventType) {
h := rt.handler
for _, mw := range rtr.middleware {
h = mw(h)
}
h(msg)
}
}
}
func (rt *MessageRoute) matches(msg Message, eventType string) bool {
for _, cond := range rt.conds {
if !cond(msg, eventType) {
return false
}
}
return true
}
func (rtr *MessageRouter) NewRoute() *MessageRoute {
rt := &MessageRoute{
handler: func(msg Message) {}, // To avoid nil pointer dereference.
}
rtr.routes = append(rtr.routes, rt)
return rt
}
func (rtr *MessageRouter) Middleware(mw func(h HandlerFunc) HandlerFunc) {
rtr.middleware = append(rtr.middleware, mw)
}
func (rt *MessageRoute) EventType(et string) *MessageRoute {
rt.conds = append(rt.conds, func(_ Message, eventType string) bool {
return eventType == et
})
return rt
}
func (rt *MessageRoute) Mentions(id string) *MessageRoute {
rt.conds = append(rt.conds, func(msg Message, _ string) bool {
return strings.Contains(msg.Content, fmt.Sprintf("<@%v>", id))
})
return rt
}
func (rt *MessageRoute) ContentMatchesExp(exp *regexp.Regexp) *MessageRoute {
rt.conds = append(rt.conds, func(msg Message, _ string) bool {
return exp.MatchString(msg.Content)
})
return rt
}
func (rt *MessageRoute) ContentContains(s string) *MessageRoute {
rt.conds = append(rt.conds, func(msg Message, _ string) bool {
return strings.Contains(msg.Content, s)
})
return rt
}
func (rt *MessageRoute) Author(id string) *MessageRoute {
rt.conds = append(rt.conds, func(msg Message, _ string) bool {
return msg.Author.ID == id
})
return rt
}
func (rt *MessageRoute) Channel(id string) *MessageRoute {
rt.conds = append(rt.conds, func(msg Message, _ string) bool {
return msg.ChannelID == id
})
return rt
}
func (rt *MessageRoute) HasEmbeds(b bool) *MessageRoute {
rt.conds = append(rt.conds, func(msg Message, _ string) bool {
if b {
return len(msg.Embeds) > 0
}
return len(msg.Embeds) == 0
})
return rt
}
func (rt *MessageRoute) RespondsTo(id string) *MessageRoute {
rt.conds = append(rt.conds, func(msg Message, _ string) bool {
return msg.ReferencedMessage != nil && msg.ReferencedMessage.Author.ID == id
})
return rt
}
func (rt *MessageRoute) Handler(h func(msg Message)) {
rt.handler = h
}