-
Notifications
You must be signed in to change notification settings - Fork 43
/
defined_commands.go
146 lines (118 loc) · 3.53 KB
/
defined_commands.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
package command
import (
"fmt"
"regexp"
"sort"
"strings"
"github.com/innogames/slack-bot/bot"
"github.com/innogames/slack-bot/bot/config"
"github.com/innogames/slack-bot/bot/matcher"
"github.com/innogames/slack-bot/bot/msg"
"github.com/innogames/slack-bot/bot/util"
"github.com/innogames/slack-bot/client"
log "github.com/sirupsen/logrus"
)
// NewCommands defines custom commands by defining a trigger (regexp) and a list of commands which should be executed
// it also supports placeholders by {{ .param }} using the regexp group name
func NewCommands(base bot.BaseCommand, macros []config.Command) bot.Command {
commands := make([]command, len(macros))
for i, macro := range macros {
commands[i] = command{
re: util.CompileRegexp(macro.Trigger),
config: macro,
}
}
return &definedCommand{
base,
commands,
}
}
type definedCommand struct {
bot.BaseCommand
// precompiled regexp and list of commands
commands []command
}
type command struct {
re *regexp.Regexp
config config.Command
}
func (c *definedCommand) GetMatcher() matcher.Matcher {
return matcher.NewGroupMatcher(
matcher.NewTextMatcher("list template functions", c.ListTemplateFunction),
matcher.WildcardMatcher(c.Execute),
)
}
func (c *definedCommand) Execute(ref msg.Ref, text string) bool {
for _, macro := range c.commands {
match := macro.re.FindStringSubmatch(text)
if len(match) == 0 {
continue
}
// extract the parameters from regexp
params := util.RegexpResultToParams(macro.re, match)
params["userId"] = ref.GetUser()
for _, commandText := range macro.config.Commands {
command, err := util.CompileTemplate(commandText)
if err != nil {
log.Warnf("cannot parse command %s: %s", commandText, err.Error())
c.ReplyError(ref, err)
continue
}
text, err := util.EvalTemplate(command, params)
if err != nil {
fmt.Printf("cannot executing command %s: %s\n", commandText, err.Error())
c.ReplyError(ref, err)
continue
}
// each line is interpreted as command
for _, part := range strings.Split(text, "\n") {
client.InternalMessages <- ref.WithText(part)
}
}
return true
}
return false
}
// receiver for "list template functions". Sort all template functions by name
func (c *definedCommand) ListTemplateFunction(match matcher.Result, message msg.Message) {
functions := util.GetTemplateFunctions()
functionNames := make([]string, 0, len(functions))
for name := range functions {
functionNames = append(functionNames, name)
}
sort.Strings(functionNames)
text := fmt.Sprintf("This %d are available template functions:\n", len(functions))
for _, name := range functionNames {
text += fmt.Sprintf("- %s\n", name)
}
c.SendMessage(message, text)
}
func (c *definedCommand) GetHelp() []bot.Help {
help := make([]bot.Help, 0, len(c.commands))
for _, macro := range c.commands {
var category bot.Category
if macro.config.Category != "" {
category = bot.Category{
Name: macro.config.Category,
}
}
patternHelp := bot.Help{
Command: macro.config.Name,
Description: macro.config.Description,
Examples: macro.config.Examples,
Category: category,
}
// as fallback use the command regexp as example
if len(macro.config.Examples) == 0 {
patternHelp.Examples = []string{
macro.config.Trigger,
}
}
help = append(help, patternHelp)
}
help = append(help, bot.Help{
Command: "list template functions",
Description: "lists all available template functions for custom commands (global ones and user specific ones)",
})
return help
}