-
Notifications
You must be signed in to change notification settings - Fork 42
/
retry.go
109 lines (95 loc) · 2.89 KB
/
retry.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
package command
import (
"fmt"
"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/storage"
"github.com/innogames/slack-bot/client"
log "github.com/sirupsen/logrus"
"github.com/slack-go/slack"
)
const storageKey = "user_history"
// NewRetryCommand store the history of the commands of the user sent to the bot in a local storage
// With "retry" the most recent command of the channel will be repeated
func NewRetryCommand(base bot.BaseCommand, cfg *config.Config) bot.Command {
return &retryCommand{
base,
cfg,
}
}
type retryCommand struct {
bot.BaseCommand
cfg *config.Config
}
func (c *retryCommand) GetMatcher() matcher.Matcher {
return matcher.NewGroupMatcher(
matcher.NewTextMatcher(`retry`, c.Retry),
matcher.NewTextMatcher(`repeat`, c.Retry),
matcher.NewRegexpMatcher(`<?https://(.*)slack.com/archives/(?P<channel>\w+)/p(?P<timestamp>\d{16})>?`, c.SlackMessage),
matcher.WildcardMatcher(c.Store),
)
}
// retry the last stored message
func (c *retryCommand) Retry(match matcher.Result, message msg.Message) {
key := message.GetUniqueKey()
var lastCommand string
storage.Read(storageKey, key, &lastCommand)
if lastCommand != "" {
c.SendMessage(message, fmt.Sprintf("Executing command: %s", lastCommand))
client.InternalMessages <- message.WithText(lastCommand)
} else {
c.SendMessage(message, "Sorry, no history found.")
}
}
// store any message in the storage to get repeatable
func (c *retryCommand) Store(ref msg.Ref, text string) bool {
if ref.IsInternalMessage() {
return false
}
key := ref.GetUniqueKey()
err := storage.Write(storageKey, key, text)
if err != nil {
log.Error(err)
}
return false
}
// re-execute a slack message
func (c *retryCommand) SlackMessage(match matcher.Result, message msg.Message) {
channel := match.GetString("channel")
timestamp := match.GetString("timestamp")
m, err := c.SlackClient.GetConversationHistory(&slack.GetConversationHistoryParameters{
ChannelID: channel,
Latest: timestamp[0:10] + "." + timestamp[10:],
Inclusive: true,
Limit: 1,
})
if err != nil {
c.ReplyError(message, err)
return
}
historyMessage := msg.FromSlackEvent(&slack.MessageEvent{
Msg: m.Messages[0].Msg,
})
historyMessage.Channel = channel
// check if the user is allowed to re-post the message: either the author of the message or an admin
if historyMessage.User != message.User && c.cfg.AdminUsers.Contains(message.User) {
c.SendMessage(message, "this is not your message")
return
}
c.AddReaction("white_check_mark", message)
client.InternalMessages <- historyMessage
}
func (c *retryCommand) GetHelp() []bot.Help {
return []bot.Help{
{
Command: "repeat",
Description: "repeat the last executed command",
Examples: []string{
"retry",
"repeat",
},
},
}
}