Skip to content

Commit

Permalink
feat(rule): add limit_to_rooms (#184)
Browse files Browse the repository at this point in the history
  • Loading branch information
wass3r authored Jul 21, 2021
1 parent 3b7a296 commit 91e97b1
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 5 deletions.
45 changes: 41 additions & 4 deletions core/matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ func getProccessedInputAndHitValue(messageInput, ruleRespondValue, ruleHearValue
}

// handleChatServiceRule handles the processing logic for a rule that came from either the chat application or CLI remote
// nolint:gocyclo // mark for refactor
func handleChatServiceRule(outputMsgs chan<- models.Message, message models.Message, hitRule chan<- models.Rule, rule models.Rule, processedInput string, hit bool, bot *models.Bot) (bool, bool) {
match, stopSearch := false, false
if rule.Respond != "" || rule.Hear != "" {
Expand All @@ -87,6 +88,35 @@ func handleChatServiceRule(outputMsgs chan<- models.Message, message models.Mess
return true, true
}

// check if limit_to_rooms is set on the rule
if hit && len(rule.LimitToRooms) > 0 {
bot.Log.Debug().Msgf("rule '%s' has 'limit_to_rooms' set - checking whether message should be processed further", rule.Name)
// do we have a channel name to work with?
if message.ChannelName != "" {
// keep track of whether room is in list
isInLimitToRooms := false

for _, room := range rule.LimitToRooms {
if strings.EqualFold(room, message.ChannelName) {
// found the room in the list,
// stop looking
isInLimitToRooms = true
break
}
}

// if the room the message came from is not
// in the list of rooms the rule is limited to
// suppress the response
if !isInLimitToRooms {
bot.Log.Debug().Msgf("rule '%s' was matched but skipped due to message not coming from a room defined in 'limit_to_rooms'", rule.Name)
return true, false
}
}

bot.Log.Debug().Msgf("rule '%s' has 'limit_to_rooms' set, but the message didn't include the channel name to compare against", rule.Name)
}

// if it's a 'respond' rule, make sure the bot was mentioned
if hit && rule.Respond != "" && !message.BotMentioned && message.Type != models.MsgTypeDirect {
return match, stopSearch
Expand Down Expand Up @@ -449,16 +479,23 @@ func handleMessage(action models.Action, outputMsgs chan<- models.Message, msg *
}

msg.Output = output

// bridge for deprecation of LimitToRooms on action
if len(action.LimitToRooms) > 0 && len(action.OutputToRooms) == 0 {
bot.Log.Warn().Msgf("'limit_to_rooms' on actions is deprecated and will be removed in the next version - update action '%s' to use `output_to_rooms' instead", action.Name)
action.OutputToRooms = action.LimitToRooms[:]
}

// Send to desired room(s)
if direct && len(action.LimitToRooms) > 0 { // direct=true and limit_to_rooms is specified
if direct && len(action.OutputToRooms) > 0 { // direct=true and limit_to_rooms is specified
bot.Log.Debug().Msgf("'direct_message_only' is set - 'limit_to_rooms' field on the '%s' action will be ignored", action.Name)
} else if !direct && len(action.LimitToRooms) > 0 { // direct=false and limit_to_rooms is specified
msg.OutputToRooms = utils.GetRoomIDs(action.LimitToRooms, bot)
} else if !direct && len(action.OutputToRooms) > 0 { // direct=false and limit_to_rooms is specified
msg.OutputToRooms = utils.GetRoomIDs(action.OutputToRooms, bot)

if len(msg.OutputToRooms) == 0 {
return errors.New("the rooms defined in 'limit_to_rooms' do not exist")
}
} else if !direct && len(action.LimitToRooms) == 0 { // direct=false and no limit_to_rooms is specified
} else if !direct && len(action.OutputToRooms) == 0 { // direct=false and no limit_to_rooms is specified
msg.OutputToRooms = []string{msg.ChannelID}
}
// Else: direct=true and no limit_to_rooms is specified
Expand Down
32 changes: 32 additions & 0 deletions core/matcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,18 @@ func Test_handleChatServiceRule(t *testing.T) {
IgnoreThreads: true,
}

ruleLimitToRooms := models.Rule{
Name: "Test Rule with limit_to_rooms set",
Respond: "hello",
LimitToRooms: []string{"foo"},
}

ruleSkipDueToLimitToRooms := models.Rule{
Name: "Test Rule with limit_to_rooms set",
Respond: "hello",
LimitToRooms: []string{"foo"},
}

testBot := new(models.Bot)
testBot.Name = "Testbot"

Expand Down Expand Up @@ -740,6 +752,24 @@ func Test_handleChatServiceRule(t *testing.T) {
ThreadTimestamp: "x",
}

testMessageLimitToRooms := models.Message{
Input: "hello",
Vars: map[string]string{},
Timestamp: "x",
ThreadTimestamp: "x",
BotMentioned: true,
ChannelName: "foo",
}

testMessageSkipDueToLimitToRooms := models.Message{
Input: "hello",
Vars: map[string]string{},
Timestamp: "x",
ThreadTimestamp: "x",
BotMentioned: true,
ChannelName: "bar",
}

tests := []struct {
name string
args args
Expand All @@ -759,6 +789,8 @@ func Test_handleChatServiceRule(t *testing.T) {
{"respond rule - hit true - valid vargs", args{rule: ruleVarg, hit: true, bot: testBot, message: testMessageVargs, processedInput: "arg1 arg2 arg3 arg4"}, true, true, "", map[string]string{"arg1": "arg1", "argv": "arg2 arg3 arg4"}},
{"respond rule - hit true - invalid", args{rule: rule, hit: true, bot: testBot, message: testMessage}, true, true, "you might be missing an argument or two - this is what i'm looking for\n```foo <arg1> <arg2>```", map[string]string{}},
{"hear rule - ignore thread", args{rule: ruleIgnoreThread, hit: true, bot: testBot, message: testMessageIgnoreThread}, true, true, "", map[string]string{}},
{"respond rule - limit_to_rooms set", args{rule: ruleLimitToRooms, hit: true, bot: testBot, message: testMessageLimitToRooms}, true, true, "", map[string]string{}},
{"respond rule - skip due to limit_to_rooms", args{rule: ruleSkipDueToLimitToRooms, hit: true, bot: testBot, message: testMessageSkipDueToLimitToRooms}, true, false, "", map[string]string{}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
3 changes: 2 additions & 1 deletion models/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ type Action struct {
Auth []Auth `mapstructure:"auth"`
ExposeJSONFields map[string]string `mapstructure:"expose_json_fields"`
Response string `mapstructure:"response"`
LimitToRooms []string `mapstructure:"limit_to_rooms"`
LimitToRooms []string `mapstructure:"limit_to_rooms"` // deprecated
OutputToRooms []string `mapstructure:"output_to_rooms"`
Message string `mapstructure:"message"`
Reaction string `mapstructure:"update_reaction" binding:"omitempty"`
}
Expand Down
1 change: 1 addition & 0 deletions models/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type Rule struct {
Actions []Action `mapstructure:"actions" binding:"required"`
Remotes Remotes `mapstructure:"remotes" binding:"omitempty"`
Reaction string `mapstructure:"reaction" binding:"omitempty"`
LimitToRooms []string `mapstructure:"limit_to_rooms" binding:"omitempty"`
// The following fields are not included in rule file
RemoveReaction string
}

0 comments on commit 91e97b1

Please sign in to comment.