This repository has been archived by the owner on Oct 28, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathinterfaces.go
253 lines (216 loc) · 8.39 KB
/
interfaces.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
package marvin
import (
"fmt"
"net/http"
"net/url"
"github.com/gorilla/mux"
"github.com/riking/marvin/database"
"github.com/riking/marvin/slack"
)
// ModuleID is a string constant identifying a module.
type ModuleID string
// ModuleState is an enum representing the state of a module.
type ModuleState int
const (
_ ModuleState = iota
ModuleStateConstructed
ModuleStateLoaded
ModuleStateEnabled
ModuleStateDisabled
ModuleStateErrorLoading
ModuleStateErrorEnabling
)
type Module interface {
// Modules should declare a constant named 'Identifier' in their package
// and return it from this function.
Identifier() ModuleID
// Load should declare dependencies.
Load(t Team)
// Enable has dependencies available.
Enable(t Team)
// Disable should shut down and unregister all resources.
Disable(t Team)
}
type ModuleStatus interface {
Instance() Module
State() ModuleState
// Returns non-nil if Degraded returns true.
Err() error
IsLoaded() bool
IsEnabled() bool
Degraded() bool
}
type ModuleConfig interface {
// Get gets a module configuration value. The error will be set on
// database errors. Get() will panic if the key was not initialized with
// Add() or AddProtect().
Get(key string) (string, error)
// GetIsDefault gets a module configuration value, but does not require the
// key have been initialized.
//
// 1) If the key was not initialized with Add(), value is the empty string,
// isDefault is true, and err is ErrConfNoDefault.
//
// 2) If the key was initialized, but has no override, value is the default
// value, isDefault is true, and err is nil.
//
// 3) If the key has an override, value is the override, isDefault is
// false, and err is nil.
GetIsDefault(key string) (value string, isDefault bool, err error)
// GetIsDefaultNotProtected acts like GetIsDefault, but returns ("", false,
// ErrConfProtected) if the key is protected.
GetIsDefaultNotProtected(key string) (value string, isDefault bool, err error)
// Set sets an override for the given configuration key.
Set(key, value string) error
// SetDefault resets the configuration for the given key to the default.
SetDefault(key string) error
// Add initializes the default value for a key for use with Get(). This
// must be called during the module Load phase.
Add(key, defaultValue string)
// Add initializes the default value for a key for use with Get(), and also
// sets the key as protected. This must be called during the module Load
// phase.
AddProtect(key, defaultValue string, protect bool)
// OnModify registers a callback for when a key is modified.
OnModify(f func(key string))
// ListDefaults returns the defaults map. This cannot be called during the
// module Load phase.
ListDefaults() map[string]string
// ListDefaults returns the protected-keys map. This cannot be called
// during the module Load phase.
ListProtected() map[string]bool
}
// ErrConfProtected is an error return from
// ModuleConfig.GetIsDefaultNotProtected.
type ErrConfProtected struct{ Key string }
// Error implements the error interface.
func (e ErrConfProtected) Error() string {
return fmt.Sprintf("%s is a protected configuration value. Viewing is restricted to admin DMs.", e.Key)
}
// ErrConfNoDefault is an error return from ModuleConfig.GetIsDefault.
type ErrConfNoDefault struct {
Key string
}
// Error implements the error interface.
func (e ErrConfNoDefault) Error() string {
return fmt.Sprintf("%s had no default set.", e.Key)
}
// AccessLevel represents the level of rights a user has.
type AccessLevel int
const (
AccessLevelInvalid AccessLevel = iota
AccessLevelBlacklisted
AccessLevelNormal
AccessLevelChannelAdmin
AccessLevelAdmin
AccessLevelController
)
// ActionSource represents the cause of actions or commands.
type ActionSource interface {
UserID() slack.UserID
ChannelID() slack.ChannelID
MsgTimestamp() slack.MessageTS
AccessLevel() AccessLevel
ArchiveLink() string
}
type SubCommand interface {
Handle(t Team, args *CommandArguments) CommandResult
Help(t Team, args *CommandArguments) CommandResult
}
type SubCommandFunc func(t Team, args *CommandArguments) CommandResult
type CommandRegistration interface {
RegisterCommand(name string, c SubCommand)
RegisterCommandFunc(name string, c SubCommandFunc, help string) SubCommand
UnregisterCommand(name string)
}
type HTTPDoer interface {
Do(*http.Request) (*http.Response, error)
}
type SendMessage interface {
SendMessage(channelID slack.ChannelID, message string) (slack.MessageTS, slack.RTMRawMessage, error)
SendComplexMessage(channelID slack.ChannelID, message slack.OutgoingSlackMessage) (slack.MessageTS, slack.RTMRawMessage, error)
}
// HasTeam is a type that references a marvin.Team.
type HasTeam interface {
Team() Team
}
// Team represents a Slack team, and is the "god object" for Marvin.
//
// Its implementation is in the marvin/slack/controller package.
type Team interface {
// Domain returns the leftmost component of the Slack domain name.
Domain() string
DB() *database.Conn
TeamConfig() *TeamConfig
ModuleConfig(mod ModuleID) ModuleConfig
// ModuleConfigList returns a list of all ModuleIDs with configs
ModuleConfigList() []ModuleID
// BotUser returns the user ID that Marvin is signed in as.
BotUser() slack.UserID
// TeamID returns the Slack Team ID of the connected Slack team.
TeamID() slack.TeamID
// EnableModules loads every module and attempts to transition them to
// the state listed in the configuration.
EnableModules() bool
Shutdown()
// DependModule places the instance of the requested module in the given
// pointer.
//
// If the requested module is already enabled, the pointer is filled
// immediately and the function returns 1. If the requested module has
// errored, the pointer is left alone and the function returns -2.
//
// During loading, when the requested module has not been enabled yet, the
// function returns 0 and remembers the pointer. If the requested module is
// not known, the function returns -1.
DependModule(self Module, dependencyID ModuleID, ptr *Module) int
// GetModule returns the Module instance for a module directly.
GetModule(modID ModuleID) Module
GetModuleStatus(modID ModuleID) ModuleStatus
// GetAllModules() returns the status of all modules.
GetAllModules() []ModuleStatus
// GetAllModules() returns the status of all enabled modules.
GetAllEnabledModules() []ModuleStatus
SendMessage
ReactMessage(msgID slack.MessageID, emojiName string) error
// SlackAPIPost makes a Slack API call by adding the token to the form. If
// the token parameter is already defined, the existing value is used.
SlackAPIPostRaw(method string, form url.Values) (*http.Response, error)
SlackAPIPostJSON(method string, form url.Values, result interface{}) error
ArchiveURL(msgID slack.MessageID) string
OnEveryEvent(mod ModuleID, f func(slack.RTMRawMessage))
OnEvent(mod ModuleID, event string, f func(slack.RTMRawMessage))
OnNormalMessage(mod ModuleID, f func(slack.RTMRawMessage))
OnSpecialMessage(mod ModuleID, msgSubtype []string, f func(slack.RTMRawMessage))
OffAllEvents(mod ModuleID)
GetRTMClient() interface{}
CommandRegistration
DispatchCommand(args *CommandArguments) CommandResult
// Add a new HTTP route handler.
HandleHTTP(path string, handler http.Handler) *mux.Route
// Get the Router object to add new routes.
Router() *mux.Router
// Inject middleware for every HTTP request. This is processed before CSRF
// protection.
HTTPMiddleware(f func(http.Handler) http.Handler)
// Resolve a relative path to an absolute URL, taking into account
// subfolder configuration.
AbsoluteURL(path string) string
ReportError(err error, source ActionSource)
ResolveChannelName(input string) slack.ChannelID
ChannelName(channel slack.ChannelID) string
FormatChannel(channel slack.ChannelID) string
ResolveUserName(input string) slack.UserID
UserName(user slack.UserID) string
UserLevel(user slack.UserID) AccessLevel
GetIM(user slack.UserID) (slack.ChannelID, error)
GetIMOtherUser(channel slack.ChannelID) (slack.UserID, error)
PublicChannelInfo(channel slack.ChannelID) (*slack.Channel, error)
PrivateChannelInfo(channel slack.ChannelID) (*slack.Channel, error)
ChannelIDByName(chName string) slack.ChannelID
ChannelMemberCount(channel slack.ChannelID) int
ChannelMemberList(channel slack.ChannelID) []slack.UserID
UserInfo(user slack.UserID) (*slack.User, error)
// Only supports private channels
UserInChannels(user slack.UserID, channels ...slack.ChannelID) map[slack.ChannelID]bool
}