-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Install MessageFilter in app and notifier
- Loading branch information
Showing
3 changed files
with
266 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,244 @@ | ||
package slack | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/oursky/github-actions-manager/pkg/utils/array" | ||
"github.com/slack-go/slack" | ||
"go.uber.org/zap" | ||
) | ||
|
||
type Argument struct { | ||
name string | ||
required bool | ||
acceptsMany bool | ||
description string | ||
} | ||
|
||
func NewArgument(name string, required bool, acceptsMany bool, description string) Argument { | ||
return Argument{name: name, required: required, acceptsMany: acceptsMany, description: description} | ||
} | ||
|
||
type Command struct { | ||
trigger string | ||
arguments []Argument | ||
description string | ||
execute func(env *CLI, args []string) CLIResult | ||
} | ||
|
||
type CLIResult struct { | ||
printToChannel bool | ||
message string | ||
} | ||
|
||
func NewCLIResult(printToChannel bool, message string) CLIResult { | ||
return CLIResult{printToChannel: printToChannel, message: message} | ||
} | ||
|
||
type CLI struct { | ||
commands *[]Command | ||
app *App | ||
ctx context.Context | ||
channelID string | ||
logger *zap.Logger | ||
} | ||
|
||
func (c Command) String() string { | ||
output := fmt.Sprintf("`%s`: %s", c.trigger, c.description) | ||
output += fmt.Sprintf("\nUsage of `%s`: `%s", c.trigger, c.trigger) | ||
for _, arg := range c.arguments { | ||
argname := arg.name | ||
if arg.acceptsMany { | ||
argname += "..." | ||
} | ||
if arg.required { | ||
output += " " + argname | ||
} else { | ||
output += " [" + argname + "]" | ||
} | ||
} | ||
output += "`" | ||
for _, arg := range c.arguments { | ||
output += fmt.Sprintf("\n\t`%s`: %s", arg.name, arg.description) | ||
} | ||
|
||
return output | ||
} | ||
|
||
func (cli *CLI) SetContext(ctx context.Context, a *App) { | ||
cli.app = a | ||
cli.ctx = ctx | ||
} | ||
|
||
func (cli *CLI) Execute(subcommand string, args []string) CLIResult { | ||
commands := *cli.commands | ||
for _, command := range commands { | ||
if subcommand != command.trigger { | ||
continue | ||
} | ||
return command.execute( | ||
cli, | ||
args, | ||
) | ||
} | ||
return NewCLIResult(false, fmt.Sprintf("Unknown command: %s", subcommand)) | ||
} | ||
|
||
func (cli *CLI) Parse(data slack.SlashCommand) map[string]interface{} { | ||
cli.channelID = data.ChannelID | ||
|
||
if data.Command != "/"+cli.app.commandName { | ||
return map[string]interface{}{"text": fmt.Sprintf("Unknown command '%s'\n", data.Command)} | ||
} | ||
|
||
args := strings.Split(data.Text, " ") | ||
if len(args) < 1 { | ||
return map[string]interface{}{"text": fmt.Sprintf("Please specify subcommand")} | ||
} | ||
|
||
result := cli.Execute(args[0], args[1:]) | ||
response := map[string]interface{}{"text": result.message} | ||
if result.printToChannel { | ||
response["response_type"] = "in_channel" | ||
} | ||
return response | ||
} | ||
|
||
func NewCLI(logger *zap.Logger) *CLI { | ||
cli := CLI{ | ||
commands: &[]Command{}, | ||
logger: logger, | ||
} | ||
cli.commands = &[]Command{ | ||
{ | ||
trigger: "help", | ||
arguments: []Argument{ | ||
NewArgument("subcommand", false, false, "The subcommand to get help about."), | ||
}, | ||
description: "Get help about a command.", | ||
execute: func(env *CLI, args []string) CLIResult { | ||
output := "" | ||
commands := (*cli.commands) | ||
if len(args) == 0 { | ||
output = "The known commands are:" | ||
for _, command := range commands { | ||
output += fmt.Sprintf(" `%s`", command.trigger) | ||
} | ||
return NewCLIResult(false, output) | ||
} | ||
subcommand := args[0] | ||
for _, command := range commands { | ||
if command.trigger != subcommand { | ||
continue | ||
} | ||
return NewCLIResult(false, command.String()) | ||
} | ||
return NewCLIResult(false, fmt.Sprintf("No such command: %s", subcommand)) | ||
}, | ||
}, | ||
{ | ||
trigger: "list", | ||
arguments: []Argument{ | ||
NewArgument("repo", true, false, "The repo to get the subscription data for."), | ||
}, | ||
description: "List the channels subscribed to a given repo.", | ||
execute: func(env *CLI, args []string) CLIResult { | ||
if len(args) < 1 { | ||
return NewCLIResult(false, "Please specify repo") | ||
} | ||
|
||
repo := args[0] | ||
if !repoRegex.MatchString(repo) { | ||
return NewCLIResult(false, fmt.Sprintf("Invalid repo *%s*\n", repo)) | ||
} | ||
|
||
channels, err := env.app.GetChannels(env.ctx, repo) | ||
if err != nil { | ||
env.logger.Warn("failed to list channels", zap.Error(err)) | ||
return NewCLIResult(false, fmt.Sprintf("Failed to get list of subscribed channels: '%s'", err)) | ||
} else { | ||
if len(channels) == 0 { | ||
return NewCLIResult(true, fmt.Sprintf("*%s* is sending updates to no channels", repo)) | ||
} | ||
channelStrings := array.Cast(channels) | ||
return NewCLIResult(true, fmt.Sprintf("*%s* is sending updates to: %s\n", repo, strings.Join(channelStrings, "; "))) | ||
} | ||
}, | ||
}, | ||
{ | ||
trigger: "subscribe", | ||
arguments: []Argument{ | ||
NewArgument("repo", true, false, "The repo to subscribe to."), | ||
NewArgument("filters", false, true, "In the format of filter_key:value1,value2,...:conclusion1,conclusion2,..., one of the supported filter keys (workflows, branches)"), | ||
}, | ||
description: "Subscribe this channel to a given repo.", | ||
execute: func(env *CLI, args []string) CLIResult { | ||
if len(args) < 1 { | ||
return NewCLIResult(false, fmt.Sprintf("Please specify repo")) | ||
} | ||
|
||
repo := args[0] | ||
if !repoRegex.MatchString(repo) { | ||
return NewCLIResult(false, fmt.Sprintf("Invalid repo *%s*\n", repo)) | ||
} | ||
|
||
filterLayers := array.Unique(args[1:]) | ||
filter, err := NewFilter(filterLayers) | ||
if err != nil { | ||
env.logger.Warn("failed to subscribe", zap.Error(err)) | ||
return NewCLIResult(false, fmt.Sprintf("Failed to subscribe to *%s*: '%s'\n", repo, err)) | ||
} | ||
|
||
channelInfo := ChannelInfo{ | ||
channelID: env.channelID, | ||
filter: filter, | ||
} | ||
err = env.app.AddChannel(env.ctx, repo, channelInfo) | ||
if err != nil { | ||
env.logger.Warn("failed to subscribe", zap.Error(err)) | ||
return NewCLIResult(false, fmt.Sprintf("Failed to subscribe to *%s*: '%s'\n", repo, err)) | ||
} | ||
if len(filterLayers) > 0 { | ||
return NewCLIResult(true, fmt.Sprintf("Subscribed to *%s* with filter layers %s", repo, filter.whitelists)) | ||
} else { | ||
return NewCLIResult(true, fmt.Sprintf("Subscribed to *%s*\n", repo)) | ||
} | ||
}, | ||
}, | ||
{ | ||
trigger: "unsubscribe", | ||
arguments: []Argument{ | ||
NewArgument("repo", true, false, "The repo to unsubscribe from."), | ||
}, | ||
description: "Unsubscribe this channel from a given repo.", | ||
execute: func(env *CLI, args []string) CLIResult { | ||
if len(args) < 1 { | ||
return NewCLIResult(false, fmt.Sprintf("Please specify repo")) | ||
} | ||
|
||
repo := args[0] | ||
if !repoRegex.MatchString(repo) { | ||
return NewCLIResult(false, fmt.Sprintf("Invalid repo *%s*\n", repo)) | ||
} | ||
|
||
err := env.app.DelChannel(env.ctx, repo, env.channelID) | ||
if err != nil { | ||
env.logger.Warn("failed to unsubscribe", zap.Error(err)) | ||
return NewCLIResult(false, fmt.Sprintf("Failed to unsubscribe from *%s*: '%s'\n", repo, err)) | ||
} else { | ||
return NewCLIResult(true, fmt.Sprintf("Unsubscribed from *%s*\n", repo)) | ||
} | ||
}, | ||
}, | ||
{ | ||
trigger: "meow", | ||
description: "Meow.", | ||
execute: func(env *CLI, args []string) CLIResult { | ||
return NewCLIResult(false, "meow") | ||
}, | ||
}, | ||
} | ||
return &cli | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters