From 3499436f4dfa40ffafc27be9e7e4b9208f760692 Mon Sep 17 00:00:00 2001 From: wass3r Date: Wed, 27 Mar 2019 22:43:52 -0500 Subject: [PATCH 1/8] chore(dep): update dependencies --- Gopkg.lock | 110 ++++++++++++++++++++++++++--------------------------- 1 file changed, 54 insertions(+), 56 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 1a3b38ea..239985b1 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -34,28 +34,20 @@ version = "v1.4.7" [[projects]] - digest = "1:97df918963298c287643883209a2c3f642e6593379f97ab400c2a2e219ab647d" + digest = "1:318f1c959a8a740366fce4b1e1eb2fd914036b4af58fbd0a003349b305f118ad" name = "github.com/golang/protobuf" packages = ["proto"] pruneopts = "UT" - revision = "aa810b61a9c79d51363740d207bb46cf8e620ed5" - version = "v1.2.0" - -[[projects]] - digest = "1:c79fb010be38a59d657c48c6ba1d003a8aa651fa56b579d959d74573b7dff8e1" - name = "github.com/gorilla/context" - packages = ["."] - pruneopts = "UT" - revision = "08b5f424b9271eedf6f9f0ce86cb9396ed337a42" - version = "v1.1.1" + revision = "b5d812f8a3706043e23a9cd5babf2e5423744d30" + version = "v1.3.1" [[projects]] - digest = "1:e73f5b0152105f18bc131fba127d9949305c8693f8a762588a82a48f61756f5f" + digest = "1:ca59b1175189b3f0e9f1793d2c350114be36eaabbe5b9f554b35edee1de50aea" name = "github.com/gorilla/mux" packages = ["."] pruneopts = "UT" - revision = "e3702bed27f0d39777b0b37b664b6280e8ef8fbf" - version = "v1.6.2" + revision = "a7962380ca08b5a188038c69871b8d3fbdf31e89" + version = "v1.7.0" [[projects]] digest = "1:7b5c6e2eeaa9ae5907c391a91c132abfd5c9e8a784a341b5625e750c67e6825d" @@ -66,7 +58,7 @@ version = "v1.4.0" [[projects]] - digest = "1:0c6aceca32885ed17808af2ad3a85f2cf18aca1a49b25de4a1d54f03913128c0" + digest = "1:c0d19ab64b32ce9fe5cf4ddceba78d5bc9807f0016db6b1183599da3dcc24d10" name = "github.com/hashicorp/hcl" packages = [ ".", @@ -85,20 +77,20 @@ version = "v1.0.0" [[projects]] - digest = "1:0a69a1c0db3591fcefb47f115b224592c8dfa4368b7ba9fae509d5e16cdc95c8" + digest = "1:31e761d97c76151dde79e9d28964a812c46efc5baee4085b86f68f0c654450de" name = "github.com/konsorten/go-windows-terminal-sequences" packages = ["."] pruneopts = "UT" - revision = "5c8c8bd35d3832f5d134ae1e1e375b69a4d25242" - version = "v1.0.1" + revision = "f55edac94c9bbba5d6182a4be46d86a2c9b5b50e" + version = "v1.0.2" [[projects]] branch = "master" - digest = "1:a28319de27d47bf8e613fb2ce1cf4873f2cf487421c115658aca7a5e9c5afa1f" + digest = "1:ef566e428a40e787fc2c0bf1ca4599796fe744ce1e7d387539c9801c4b22ac86" name = "github.com/leekchan/gtf" packages = ["."] pruneopts = "UT" - revision = "79e3a68ab435edb72c6490289a33ef8bedcee15a" + revision = "5fba33c5b00b4d204dbb2c1a7b27e2b999446cec" [[projects]] digest = "1:c568d7727aa262c32bdf8a3f7db83614f7af0ed661474b24588de635c20024c7" @@ -133,7 +125,7 @@ revision = "c48cc78d482608239f6c4c92a4abd87eb8761c90" [[projects]] - digest = "1:41c243b749b02670f87f849c205954af71f08d4ba8a0252a6c93128e692a6e3c" + digest = "1:0d01bcdbda5760553e5ab803faa3d3a0dc6a3ef357eb179b8ac8501b358d49ce" name = "github.com/nlopes/slack" packages = [ ".", @@ -153,32 +145,34 @@ version = "v1.2.0" [[projects]] - digest = "1:40e195917a951a8bf867cd05de2a46aaf1806c50cf92eebf4c16f78cd196f747" + digest = "1:cf31692c14422fa27c83a05292eb5cbe0fb2775972e8f1f8446a71549bd8980b" name = "github.com/pkg/errors" packages = ["."] pruneopts = "UT" - revision = "645ef00459ed84a119197bfb8d8205042c6df63d" - version = "v0.8.0" + revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4" + version = "v0.8.1" [[projects]] - digest = "1:b6221ec0f8903b556e127c449e7106b63e6867170c2d10a7c058623d086f2081" + digest = "1:d14a5f4bfecf017cb780bdde1b6483e5deb87e12c332544d2c430eda58734bcb" name = "github.com/prometheus/client_golang" - packages = ["prometheus"] + packages = [ + "prometheus", + "prometheus/promhttp", + ] pruneopts = "UT" revision = "c5b7fccd204277076155f10851dad72b76a49317" version = "v0.8.0" [[projects]] branch = "master" - digest = "1:0f37e09b3e92aaeda5991581311f8dbf38944b36a3edec61cc2d1991f527554a" + digest = "1:2d5cd61daa5565187e1d96bae64dbbc6080dacf741448e9629c64fd93203b0d4" name = "github.com/prometheus/client_model" packages = ["go"] pruneopts = "UT" - revision = "5c3871d89910bfb32f5fcab2aa4b9ec68e65a99f" + revision = "fd36f4220a901265f90734c3183c5f0c91daa0b8" [[projects]] - branch = "master" - digest = "1:dad2e5a2153ee7a6c9ab8fc13673a16ee4fb64434a7da980965a3741b0c981a3" + digest = "1:35cf6bdf68db765988baa9c4f10cc5d7dda1126a54bd62e252dbcd0b1fc8da90" name = "github.com/prometheus/common" packages = [ "expfmt", @@ -186,20 +180,22 @@ "model", ] pruneopts = "UT" - revision = "c7de2306084e37d54b8be01f3541a8464345e9a5" + revision = "cfeb6f9992ffa54aaa4f2170ade4067ee478b250" + version = "v0.2.0" [[projects]] branch = "master" - digest = "1:4f63dbf446cdeef6226bffe9bbc5fc8b93e13378f84833fb4306514411a76963" + digest = "1:c31163bd62461e0c5f7ddc7363e39ef8d9e929693e77b5c11c709b05f9cb9219" name = "github.com/prometheus/procfs" packages = [ ".", "internal/util", + "iostats", "nfs", "xfs", ] pruneopts = "UT" - revision = "185b4288413d2a0dd0806f78c90dde719829e5ae" + revision = "55ae3d9d557340b5bc24cd8aa5f6fa2c2ab31352" [[projects]] digest = "1:ed615c5430ecabbb0fb7629a182da65ecee6523900ac1ac932520860878ffcad" @@ -218,39 +214,39 @@ version = "v1.2.1" [[projects]] - digest = "1:dc2d85c13ac22c22a1f3170a41a8e1b897fa05134aaf533f16df44f66a25b4a1" + digest = "1:e4c72127d910a96daf869a44f3dd563b86dbe6931a172863a0e99c5ff04b59e4" name = "github.com/sirupsen/logrus" packages = ["."] pruneopts = "UT" - revision = "a67f783a3814b8729bd2dac5780b5f78f8dbd64d" - version = "v1.1.0" + revision = "dae0fa8d5b0c810a8ab733fbd5510c7cae84eca4" + version = "v1.4.0" [[projects]] - digest = "1:7f665ff60a4c8efd5a5c053bf862020cf9f7cd56c3f70dd140f45cd66fb08a8d" + digest = "1:bb495ec276ab82d3dd08504bbc0594a65de8c3b22c6f2aaa92d05b73fbf3a82e" name = "github.com/spf13/afero" packages = [ ".", "mem", ] pruneopts = "UT" - revision = "d40851caa0d747393da1ffb28f7f9d8b4eeffebd" - version = "v1.1.2" + revision = "588a75ec4f32903aa5e39a2619ba6a4631e28424" + version = "v1.2.2" [[projects]] - digest = "1:516e71bed754268937f57d4ecb190e01958452336fa73dbac880894164e91c1f" + digest = "1:08d65904057412fc0270fc4812a1c90c594186819243160dc779a402d4b6d0bc" name = "github.com/spf13/cast" packages = ["."] pruneopts = "UT" - revision = "8965335b8c7107321228e3e3702cab9832751bac" - version = "v1.2.0" + revision = "8c9545af88b134710ab1cd196795e7f2388358d7" + version = "v1.3.0" [[projects]] - digest = "1:68ea4e23713989dc20b1bded5d9da2c5f9be14ff9885beef481848edd18c26cb" + digest = "1:1b753ec16506f5864d26a28b43703c58831255059644351bbcb019b843950900" name = "github.com/spf13/jwalterweatherman" packages = ["."] pruneopts = "UT" - revision = "4a4406e478ca629068e7768fc33f3f044173c0a6" - version = "v1.0.0" + revision = "94f6ae3ed3bceceafa716478c5fbf8d29ca601a1" + version = "v1.1.0" [[projects]] digest = "1:c1b1102241e7f645bc8e0c22ae352e8f0dc6484b6cb4d132fa9f24174e0119e2" @@ -261,16 +257,16 @@ version = "v1.0.3" [[projects]] - digest = "1:214775c11fd26da94a100111a62daa25339198a4f9c57cb4aab352da889f5b93" + digest = "1:1b773526998f3dbde3a51a4a5881680c4d237d3600f570d900f97ac93c7ba0a8" name = "github.com/spf13/viper" packages = ["."] pruneopts = "UT" - revision = "2c12c60302a5a0e62ee102ca9bc996277c2f64f5" - version = "v1.2.1" + revision = "9e56dacc08fbbf8c9ee2dbc717553c758ce42bc9" + version = "v1.3.2" [[projects]] branch = "master" - digest = "1:a6c91777916f37c288a9f2e352feb7567c3ff4c47a3880b391070740d3357e4f" + digest = "1:e12267fedd4ad8ee3e151bf5618757ff389c5525f324d8dd8988c78fbe409d74" name = "golang.org/x/crypto" packages = [ "internal/subtle", @@ -280,21 +276,22 @@ "ssh/terminal", ] pruneopts = "UT" - revision = "e3636079e1a4c1f337f212cc5cd2aca108f6c900" + revision = "a5d413f7728c81fb97d96a2b722368945f651e78" [[projects]] branch = "master" - digest = "1:19b2eb89a60dafcfe5c699fa21ef51143d9bc4825c155608f81e56e0a9a4bba4" + digest = "1:78ed3d0c6d5b4996ef2867e280f39ea7b44438558c6331721740ab9061db532c" name = "golang.org/x/sys" packages = [ + "cpu", "unix", "windows", ] pruneopts = "UT" - revision = "4497e2df6f9e69048a54498c7affbbec3294ad47" + revision = "f49334f85ddcf0f08d7fb6dd7363e9e6d6b777eb" [[projects]] - digest = "1:038003d098ffc345c4c5c6d47bcc6920b2649ee0c0d557162e54e75c76cadf8b" + digest = "1:8029e9743749d4be5bc9f7d42ea1659471767860f0cdc34d37c3111bd308a295" name = "golang.org/x/text" packages = [ "internal/gen", @@ -309,12 +306,12 @@ version = "v0.3.0" [[projects]] - digest = "1:342378ac4dcb378a5448dd723f0784ae519383532f5e70ade24132c4c8693202" + digest = "1:4d2e5a73dc1500038e504a8d78b986630e3626dc027bc030ba5c75da257cdb96" name = "gopkg.in/yaml.v2" packages = ["."] pruneopts = "UT" - revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" - version = "v2.2.1" + revision = "51d6538a90f86fe93ac480b35f37b2be17fef232" + version = "v2.2.2" [solve-meta] analyzer-name = "dep" @@ -328,6 +325,7 @@ "github.com/nlopes/slack", "github.com/nlopes/slack/slackevents", "github.com/prometheus/client_golang/prometheus", + "github.com/prometheus/client_golang/prometheus/promhttp", "github.com/robfig/cron", "github.com/rs/xid", "github.com/sirupsen/logrus", From 0a211ed7f3836b8fe819121e6b4ffcbd66eab3d5 Mon Sep 17 00:00:00 2001 From: wass3r Date: Wed, 27 Mar 2019 22:47:47 -0500 Subject: [PATCH 2/8] style: fix various linter issues --- core/configure.go | 2 +- core/matcher.go | 15 ++++++--------- core/matcher_test.go | 6 +++--- core/outputs.go | 8 +++----- handlers/script.go | 2 +- remote/slack/util.go | 15 +++++++++------ 6 files changed, 23 insertions(+), 25 deletions(-) diff --git a/core/configure.go b/core/configure.go index 4dbad208..782c629c 100644 --- a/core/configure.go +++ b/core/configure.go @@ -101,7 +101,7 @@ func configureChatApplication(bot *models.Bot) { bot.InteractiveComponents = false } if iCallbackPath == "" { - bot.Log.Errorf("Slack Interactive Components callback path is empty: %s", iCallbackPath) + bot.Log.Warnf("Slack Interactive Components callback path is empty: %s", iCallbackPath) bot.InteractiveComponents = false } bot.SlackInteractionsCallbackPath = iCallbackPath diff --git a/core/matcher.go b/core/matcher.go index cf637547..fcd1de99 100644 --- a/core/matcher.go +++ b/core/matcher.go @@ -279,7 +279,7 @@ func doRuleActions(message models.Message, outputMsgs chan<- models.Message, rul func craftResponse(rule models.Rule, msg models.Message, bot *models.Bot) (string, error) { // The user removed the 'format_output' field, or it's not set if rule.FormatOutput == "" { - return "", errors.New("Hmm, the 'format_output' field in your configuration is empty") + return "", errors.New("hmm, the 'format_output' field in your configuration is empty") } // None of the rooms specified in 'output_to_rooms' exist @@ -302,10 +302,9 @@ func craftResponse(rule models.Rule, msg models.Message, bot *models.Bot) (strin // Check if the value contains html/template code, for advanced formatting if strings.Contains(output, "{{") { - t := new(template.Template) var i interface{} - t, err = template.New("output").Funcs(gtf.GtfFuncMap).Parse(output) + t, err := template.New("output").Funcs(gtf.GtfFuncMap).Parse(output) if err != nil { return "", err } @@ -328,7 +327,6 @@ func handleExec(action models.Action, msg *models.Message, bot *models.Bot) erro return fmt.Errorf("no command was supplied for the '%s' action named: %s", action.Type, action.Name) } - resp := &models.ScriptResponse{} resp, err := handlers.ScriptExec(action, msg, bot) // Set explicit variables to make script output, script status code accessible in rules @@ -348,7 +346,6 @@ func handleHTTP(action models.Action, msg *models.Message, bot *models.Bot) erro return fmt.Errorf("no URL was supplied for the '%s' action named: %s", action.Type, action.Name) } - resp := &models.HTTPResponse{} resp, err := handlers.HTTPReq(action, msg) if err != nil { msg.Error = fmt.Sprintf("Error in request made by action '%s'. See bot admin for more information", action.Name) @@ -369,7 +366,7 @@ func handleHTTP(action models.Action, msg *models.Message, bot *models.Bot) erro // Do we need to expose any fields? if len(action.ExposeJSONFields) > 0 { for k, v := range action.ExposeJSONFields { - t := new(template.Template) + var t *template.Template v, err = utils.Substitute(v, msg.Vars) if err != nil { @@ -403,7 +400,7 @@ func handleHTTP(action models.Action, msg *models.Message, bot *models.Bot) erro // Handle standard message/logging actions func handleMessage(action models.Action, outputMsgs chan<- models.Message, msg *models.Message, direct, startMsgThread bool, hitRule chan<- models.Rule, bot *models.Bot) error { if action.Message == "" { - return fmt.Errorf("No message was set") + return fmt.Errorf("no message was set") } if action.Type == "message" && startMsgThread && msg.ThreadTimestamp == "" { @@ -424,7 +421,7 @@ func handleMessage(action models.Action, outputMsgs chan<- models.Message, msg * msg.OutputToRooms = utils.GetRoomIDs(action.LimitToRooms, bot) if len(msg.OutputToRooms) == 0 { - return errors.New("The rooms defined in 'limit_to_rooms' do not exist") + 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 msg.OutputToRooms = []string{msg.ChannelID} @@ -457,7 +454,7 @@ func updateReaction(action models.Action, rule *models.Rule, vars map[string]str } action.Reaction = reaction - t := new(template.Template) + var t *template.Template var i interface{} t, err = template.New("update_reaction").Funcs(gtf.GtfFuncMap).Parse(action.Reaction) diff --git a/core/matcher_test.go b/core/matcher_test.go index e2cb5efc..2edb9b18 100644 --- a/core/matcher_test.go +++ b/core/matcher_test.go @@ -171,7 +171,7 @@ func TestHandleExec(t *testing.T) { testFailScriptResponse := models.ScriptResponse{ Status: 1, - Output: "Hmm, something timed out. Please try again", + Output: "hmm, something timed out. Please try again", } testNoCmdScriptAction := models.Action{ @@ -717,7 +717,7 @@ func Test_handleChatServiceRule(t *testing.T) { }{ {"basic", args{}, false, false, ""}, {"respond rule - hit false", args{rule: rule, hit: false}, false, false, ""}, - {"respond rule - hit true - valid", args{rule: rule, hit: true, bot: testBot, message: testMessage, processedInput: "arg1 arg2"}, true, true, "Hmm, the 'format_output' field in your configuration is empty"}, + {"respond rule - hit true - valid", args{rule: rule, hit: true, bot: testBot, message: testMessage, processedInput: "arg1 arg2"}, true, true, "hmm, the 'format_output' field in your configuration is empty"}, {"respond rule - hit true - bot not mentioned", args{rule: rule, hit: true, bot: testBot, message: testMessageBotNotMentioned, processedInput: "arg1 arg2"}, false, false, ""}, {"respond rule - hit true - valid - not enough args", args{rule: rule, hit: true, bot: testBot, message: testMessageNotEnoughArgs, processedInput: "arg1"}, true, true, "You might be missing an argument or two. This is what I'm looking for\n```foo ```"}, {"respond rule - hit true - valid optional arg", args{rule: ruleOpt, hit: true, bot: testBot, message: testMessageOptionalArgs, processedInput: "arg1"}, true, true, ""}, @@ -973,7 +973,7 @@ func Test_doRuleActions(t *testing.T) { args args expectedMessage string }{ - {"Missing format_output", args{message: models.Message{}, rule: models.Rule{}, bot: testBot}, "Hmm, the 'format_output' field in your configuration is empty"}, + {"Missing format_output", args{message: models.Message{}, rule: models.Rule{}, bot: testBot}, "hmm, the 'format_output' field in your configuration is empty"}, {"Message Action", args{message: testMessage, rule: testRule, bot: testBot}, "hi there from foo action"}, {"Exec Action", args{message: testMessage, rule: execRule, bot: testBot}, "hi"}, {"Http Action", args{message: testMessage, rule: httpRule, bot: testBot}, "OK"}, diff --git a/core/outputs.go b/core/outputs.go index fd7f7465..1a5b46c5 100644 --- a/core/outputs.go +++ b/core/outputs.go @@ -12,9 +12,6 @@ import ( // Outputs determines where messages are output based on fields set in the bot.yml // TODO: Refactor to keep remote specifics in remote/ func Outputs(outputMsgs <-chan models.Message, hitRule <-chan models.Rule, bot *models.Bot) { - remoteCLI := &cli.Client{} - remoteDiscord := &discord.Client{} - remoteSlack := &slack.Client{} for { message := <-outputMsgs rule := <-hitRule @@ -28,12 +25,12 @@ func Outputs(outputMsgs <-chan models.Message, hitRule <-chan models.Rule, bot * bot.Log.Warn("Scheduler does not currently support Discord") break } - remoteDiscord = &discord.Client{Token: bot.DiscordToken} + remoteDiscord := &discord.Client{Token: bot.DiscordToken} remoteDiscord.Reaction(message, rule, bot) remoteDiscord.Send(message, bot) case "slack": // Create Slack client - remoteSlack = &slack.Client{ + remoteSlack := &slack.Client{ Token: bot.SlackToken, VerificationToken: bot.SlackVerificationToken, WorkspaceToken: bot.SlackWorkspaceToken, @@ -49,6 +46,7 @@ func Outputs(outputMsgs <-chan models.Message, hitRule <-chan models.Rule, bot * bot.Log.Debugf("Chat application %s is not supported", chatApp) } case models.MsgServiceCLI: + remoteCLI := &cli.Client{} remoteCLI.Send(message, bot) case models.MsgServiceUnknown: bot.Log.Error("Found unknown service") diff --git a/handlers/script.go b/handlers/script.go index eaa5778c..140fe80e 100644 --- a/handlers/script.go +++ b/handlers/script.go @@ -49,7 +49,7 @@ func ScriptExec(args models.Action, msg *models.Message, bot *models.Bot) (*mode // Handle timeouts if ctx.Err() == context.DeadlineExceeded { result.Output = "Hmm, something timed out. Please try again." - return result, fmt.Errorf("Timeout reached, exec process for action '%s' cancelled", args.Name) + return result, fmt.Errorf("timeout reached, exec process for action '%s' cancelled", args.Name) } // Deal with non-zero exit codes diff --git a/remote/slack/util.go b/remote/slack/util.go index 20a7e4ee..5dc71270 100644 --- a/remote/slack/util.go +++ b/remote/slack/util.go @@ -40,10 +40,10 @@ func getMessageType(channel string) (models.MessageType, error) { case "G": return models.MsgTypePrivateChannel, nil default: - return models.MsgTypeUnknown, fmt.Errorf("Unable to handle channel: UNKNOWN_%s", channel) + return models.MsgTypeUnknown, fmt.Errorf("unable to handle channel: UNKNOWN_%s", channel) } } - return models.MsgTypeUnknown, fmt.Errorf("Unable to handle channel: UNKNOWN_%s", channel) + return models.MsgTypeUnknown, fmt.Errorf("unable to handle channel: UNKNOWN_%s", channel) } // isValidPath - regex matches a URL's path string to check if it is a correct path @@ -70,7 +70,7 @@ func isValidURL(url string) bool { return false } -// removeBotMention - parse out the preppended bot mention in a message +// removeBotMention - parse out the prepended bot mention in a message func removeBotMention(contents, botID string) (string, bool) { mention := fmt.Sprintf("<@%s> ", botID) wasMentioned := false @@ -83,10 +83,13 @@ func removeBotMention(contents, botID string) (string, bool) { } // sanitizeContents - sanitizes a buffer's contents from incoming http payloads -func sanitizeContents(b []byte) string { +func sanitizeContents(b []byte) (string, error) { contents := string(b) contents = strings.Replace(contents, "payload=", "", 1) - contents, _ = url.QueryUnescape(contents) + contents, err := url.QueryUnescape(contents) + if err != nil { + return "", err + } contents = strings.Replace(contents, `\/`, `/`, -1) - return contents + return contents, nil } From 11ad99f0f2fc88f97503701e1641c7fc1b10f43d Mon Sep 17 00:00:00 2001 From: wass3r Date: Wed, 27 Mar 2019 22:48:21 -0500 Subject: [PATCH 3/8] chore(prometheus): update deprecated handler --- core/prommetric.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/prommetric.go b/core/prommetric.go index 6f6bd499..5ada0864 100644 --- a/core/prommetric.go +++ b/core/prommetric.go @@ -5,6 +5,7 @@ import ( "github.com/gorilla/mux" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/target/flottbot/models" ) @@ -42,8 +43,7 @@ func Prommetric(input string, bot *models.Bot) { // metrics handler prometheus.MustRegister(botResponseCollector) - promRouter.HandleFunc("/metrics", prometheus.Handler().ServeHTTP).Methods("GET") - // http.Handle("/metrics", prometheus.Handler()) + promRouter.Handle("/metrics", promhttp.Handler()) // start prometheus server go http.ListenAndServe(":8080", promRouter) From 3b0c4c552f96115ab49cb03f031230ebd3924d07 Mon Sep 17 00:00:00 2001 From: wass3r Date: Wed, 27 Mar 2019 22:48:50 -0500 Subject: [PATCH 4/8] chore(unfurl): remove dead code --- remote/slack/helper.go | 164 +++++++++++++---------------------------- 1 file changed, 52 insertions(+), 112 deletions(-) diff --git a/remote/slack/helper.go b/remote/slack/helper.go index b45a491f..249ad26a 100644 --- a/remote/slack/helper.go +++ b/remote/slack/helper.go @@ -7,7 +7,6 @@ import ( "io/ioutil" "net/http" "strings" - "time" "github.com/gorilla/mux" "github.com/nlopes/slack" @@ -137,7 +136,7 @@ func handleCallBack(api *slack.Client, event slackevents.EventsAPIInnerEvent, bo delete(bot.Rooms, ev.Channel) bot.Log.Debugf("%s has left the channel %s", bot.Name, bot.Rooms[ev.Channel]) default: - bot.Log.Errorf("getEventsAPIEventHandler: Unrecognized event type") + bot.Log.Errorf("getEventsAPIEventHandler: Unrecognized event type: %v", ev) } } @@ -205,7 +204,10 @@ func getInteractiveComponentRuleHandler(verificationToken string, inputMsgs chan bot.Log.Errorf("getInteractiveComponentRuleHandler: Failed to read request body: %s", err.Error()) } - contents := sanitizeContents(buff) + contents, err := sanitizeContents(buff) + if err != nil { + bot.Log.Debugf("failed to santize content: %v", err) + } var callback slack.AttachmentActionCallback if err := json.Unmarshal([]byte(contents), &callback); err != nil { @@ -261,7 +263,7 @@ func getSlackUsers(api *slack.Client, message models.Message) ([]slack.User, err if len(message.OutputToUsers) > 0 { res, err := api.GetUsers() if err != nil { - return []slack.User{}, fmt.Errorf("Did not find any users listed in 'output_to_users': %s", err.Error()) + return []slack.User{}, fmt.Errorf("did not find any users listed in 'output_to_users': %s", err.Error()) } slackUsers = res } @@ -474,56 +476,54 @@ func readFromEventsAPI(api *slack.Client, vToken string, inputMsgs chan<- models func readFromRTM(rtm *slack.RTM, inputMsgs chan<- models.Message, bot *models.Bot) { go rtm.ManageConnection() for { - select { - case msg := <-rtm.IncomingEvents: - switch ev := msg.Data.(type) { - case *slack.MessageEvent: - senderID := ev.User - // Sometimes message events in RTM don't have a User ID? - // Also, only process messages that aren't from the bot itself - if senderID != "" && bot.ID != senderID { - channel := ev.Channel - msgType, err := getMessageType(channel) - if err != nil { - bot.Log.Debug(err.Error()) - } - text, mentioned := removeBotMention(ev.Text, bot.ID) - user, err := rtm.GetUserInfo(senderID) - if err != nil && senderID != "" { // we only care if senderID is not empty and there's an error (senderID == "" could be a thread from a message) - bot.Log.Errorf("Did not get Slack user info: %s", err.Error()) - } - timestamp := ev.Timestamp - threadTimestamp := ev.ThreadTimestamp - inputMsgs <- populateMessage(models.NewMessage(), msgType, channel, text, timestamp, threadTimestamp, mentioned, user, bot) - } - case *slack.ConnectedEvent: - // populate users - populateBotUsers(ev.Info.Users, bot) - // populate user groups - populateUserGroups(bot) - bot.Log.Debugf("RTM connection established!") - case *slack.GroupJoinedEvent: - // when the bot joins a channel add it to the internal lookup - // NOTE: looks like there is another unsupported event we could use - // Received unmapped event \"member_joined_channel\" - // Maybe watch ffor an update to slack package for future support - if bot.Rooms[ev.Channel.Name] == "" { - bot.Rooms[ev.Channel.Name] = ev.Channel.ID - bot.Log.Debugf("Joined new channel. %s(%s) added to lookup", ev.Channel.Name, ev.Channel.ID) + msg := <-rtm.IncomingEvents + switch ev := msg.Data.(type) { + case *slack.MessageEvent: + senderID := ev.User + // Sometimes message events in RTM don't have a User ID? + // Also, only process messages that aren't from the bot itself + if senderID != "" && bot.ID != senderID { + channel := ev.Channel + msgType, err := getMessageType(channel) + if err != nil { + bot.Log.Debug(err.Error()) } - case *slack.HelloEvent: - // ignore - this is the very first initial event sent when connecting to Slack - case *slack.RTMError: - bot.Log.Error(ev.Error()) - case *slack.ConnectionErrorEvent: - bot.Log.Errorf("RTM connection error: %+v", ev) - case *slack.InvalidAuthEvent: - if !bot.CLI { - bot.Log.Debug("Invalid Authorization. Please double check your Slack token.") + text, mentioned := removeBotMention(ev.Text, bot.ID) + user, err := rtm.GetUserInfo(senderID) + if err != nil && senderID != "" { // we only care if senderID is not empty and there's an error (senderID == "" could be a thread from a message) + bot.Log.Errorf("Did not get Slack user info: %s", err.Error()) } - } // EOF inner switch - } // EOF outter switch - } // EOF for + timestamp := ev.Timestamp + threadTimestamp := ev.ThreadTimestamp + inputMsgs <- populateMessage(models.NewMessage(), msgType, channel, text, timestamp, threadTimestamp, mentioned, user, bot) + } + case *slack.ConnectedEvent: + // populate users + populateBotUsers(ev.Info.Users, bot) + // populate user groups + populateUserGroups(bot) + bot.Log.Debugf("RTM connection established!") + case *slack.GroupJoinedEvent: + // when the bot joins a channel add it to the internal lookup + // NOTE: looks like there is another unsupported event we could use + // Received unmapped event \"member_joined_channel\" + // Maybe watch ffor an update to slack package for future support + if bot.Rooms[ev.Channel.Name] == "" { + bot.Rooms[ev.Channel.Name] = ev.Channel.ID + bot.Log.Debugf("Joined new channel. %s(%s) added to lookup", ev.Channel.Name, ev.Channel.ID) + } + case *slack.HelloEvent: + // ignore - this is the very first initial event sent when connecting to Slack + case *slack.RTMError: + bot.Log.Error(ev.Error()) + case *slack.ConnectionErrorEvent: + bot.Log.Errorf("RTM connection error: %+v", ev) + case *slack.InvalidAuthEvent: + if !bot.CLI { + bot.Log.Debug("Invalid Authorization. Please double check your Slack token.") + } + } + } } // send - handles the sending logic of a message going to Slack @@ -608,63 +608,3 @@ func sendMessage(api *slack.Client, ephemeral bool, channel, userID, text, threa } return nil } - -// unfurlLink is not being used for anything but could be pretty handy later -func unfurlLink(workspaceToken, messageTimeStamp, channel, link string) error { - if isValidURL(link) { - var jsonStr = []byte(fmt.Sprintf(`{ - "token":"%s", - "ts":"%s", - "channel":"%s", - "unfurls": { - "%s": { - "parse": "full", - "response_type": "in_channel", - "text": "<%s>", - "attachments":[ - { - "image_url": "%s" - } - ], - "unfurl_media":true, - "unfurl_links":true - } - } - }`, workspaceToken, messageTimeStamp, channel, link, link, link)) - req, err := http.NewRequest("POST", "https://slack.com/api/chat.unfurl", bytes.NewBuffer(jsonStr)) - if err != nil { - return err - } - req.Header.Add("Content-Type", "application/json; charset=utf-8") - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", workspaceToken)) - req.Close = true - - client := &http.Client{ - Timeout: 10 * time.Second, - } - resp, err := client.Do(req) - if err != nil { - return err - } - - defer resp.Body.Close() - - resultBytes, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - - type result struct { - Error string `json:"error"` - } - var rslt result - err = json.Unmarshal(resultBytes, &rslt) - if err != nil { - return err - } - if rslt.Error != "" { - return fmt.Errorf("Could not unfurl message with link '%s' because of error '%s'", link, rslt.Error) - } - } - return fmt.Errorf("URL link to unfurl is invalid, please check it's validity and try again") -} From ab42e988d62a99e2ddd2224a02c78df9e51161b1 Mon Sep 17 00:00:00 2001 From: wass3r Date: Thu, 28 Mar 2019 00:03:20 -0500 Subject: [PATCH 5/8] chore(examples): fix examples --- config-example/rules/gopher.yml | 2 +- config-example/rules/joke.json | 13 +++++----- config-example/rules/joke.yml | 12 +++++----- config-example/rules/weather.yml | 41 ++++++++++---------------------- 4 files changed, 26 insertions(+), 42 deletions(-) diff --git a/config-example/rules/gopher.yml b/config-example/rules/gopher.yml index 91713b5e..8835eadb 100644 --- a/config-example/rules/gopher.yml +++ b/config-example/rules/gopher.yml @@ -2,7 +2,7 @@ name: get a random gopher active: true respond: gopher -reaction: waiting +reaction: thinking_face # actions actions: - name: gopher http request diff --git a/config-example/rules/joke.json b/config-example/rules/joke.json index 924729d5..026fe85b 100644 --- a/config-example/rules/joke.json +++ b/config-example/rules/joke.json @@ -6,16 +6,17 @@ { "name": "joke http request", "type": "GET", - "url": "https://08ad1pao69.execute-api.us-east-1.amazonaws.com/dev/random_joke", - "auth": null, + "url": "https://icanhazdadjoke.com/", "expose_json_fields": { - "setup": ".setup", - "punchline": ".punchline" + "joke": ".setup" + }, + "custom_headers": { + "Accept": "application/json" } } ], - "format_output": "${setup}\n\n${punchline}", + "format_output": "${joke}", "direct_message_only": false, "help_text": "joke", "include_in_help": true -} +} \ No newline at end of file diff --git a/config-example/rules/joke.yml b/config-example/rules/joke.yml index 620b92a8..d948b6e5 100644 --- a/config-example/rules/joke.yml +++ b/config-example/rules/joke.yml @@ -7,14 +7,14 @@ respond: joke actions: - name: joke http request type: GET - url: https://08ad1pao69.execute-api.us-east-1.amazonaws.com/dev/random_joke - auth: + url: https://icanhazdadjoke.com/ + custom_headers: + Accept: 'application/json' expose_json_fields: - setup: '.setup' - punchline: '.punchline' + joke: '.joke' # response -format_output: "${setup}\n\n${punchline}" +format_output: "${joke}" direct_message_only: false # help help_text: joke -include_in_help: true +include_in_help: true \ No newline at end of file diff --git a/config-example/rules/weather.yml b/config-example/rules/weather.yml index 55e26d5d..e06ade86 100644 --- a/config-example/rules/weather.yml +++ b/config-example/rules/weather.yml @@ -4,43 +4,26 @@ active: true # trigger and args respond: weather args: - - location + - lonlat # actions actions: - name: weather http request type: GET - url: http://api.openweathermap.org/data/2.5/weather - query_data: - q: ${location} - APPID: ${APPID} - units: metric - auth: + url: http://api.weather.gov/points/${lonlat} expose_json_fields: - temperature: '.main.temp' - loc: '.name' - desc: |- - {{ range .weather }} - {{ range $k, $v := . }} - - {{- $v -}} - {{ end }} - - {{ end }} - country: '.sys.country' - - name: location http request + city: '.properties.relativeLocation.properties.city' + state: '.properties.relativeLocation.properties.state' + fc_url: '.properties.forecast' + - name: get forecast type: GET - url: https://restcountries.eu/rest/v2/alpha/${country} - auth: + url: ${fc_url} expose_json_fields: - flag_url: .flag - full_name: '.name' - population: 'printf "%0.f" .population' - native_name: .nativeName + tomorrow_temp: |- + {{ (index .properties.periods 1).temperature }}{{ (index .properties.periods 1).temperatureUnit }} # response -format_output: "It is ${temperature}C in ${loc} (${full_name}/${native_name}, country population: ${population})" +format_output: "Tomorrow's temperature in ${city}, ${state} will be ${tomorrow_temp}" direct_message_only: false -output_to_rooms: - - general # help -help_text: weather -include_in_help: true +help_text: weather +include_in_help: true \ No newline at end of file From d1f905f0b83fb8a6de618933b5ec35d16e25f5aa Mon Sep 17 00:00:00 2001 From: wass3r Date: Thu, 18 Apr 2019 00:13:53 -0500 Subject: [PATCH 6/8] style(sh): change bash to sh --- config-example/rules/fotd.yml | 2 +- config-example/rules/{bash.yml => shell.yml} | 6 +++--- config-example/scripts/random.sh | 2 +- config-example/scripts/script.sh | 4 ++-- testdata/fail.sh | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) rename config-example/rules/{bash.yml => shell.yml} (72%) diff --git a/config-example/rules/fotd.yml b/config-example/rules/fotd.yml index 4aacd730..0ea9a7f8 100644 --- a/config-example/rules/fotd.yml +++ b/config-example/rules/fotd.yml @@ -14,7 +14,7 @@ actions: {{len .data.Events}} - name: random number between 1-40 type: exec - cmd: bash config/scripts/random.sh ${num_of_events} + cmd: sh config/scripts/random.sh ${num_of_events} - name: today in history http request type: GET url: https://history.muffinlabs.com/date diff --git a/config-example/rules/bash.yml b/config-example/rules/shell.yml similarity index 72% rename from config-example/rules/bash.yml rename to config-example/rules/shell.yml index bfa7c819..97c14fab 100644 --- a/config-example/rules/bash.yml +++ b/config-example/rules/shell.yml @@ -2,15 +2,15 @@ name: script-rule active: true # trigger and args -respond: bashscript +respond: shellscript # actions actions: - name: sample script type: exec - cmd: bash config/scripts/script.sh + cmd: sh config/scripts/script.sh # response format_output: "${_exec_output}" direct_message_only: false # help -help_text: bashscript +help_text: shellscript include_in_help: true diff --git a/config-example/scripts/random.sh b/config-example/scripts/random.sh index 02d64ceb..00180ebf 100755 --- a/config-example/scripts/random.sh +++ b/config-example/scripts/random.sh @@ -1,3 +1,3 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh echo $RANDOM % $1 + 1 | bc diff --git a/config-example/scripts/script.sh b/config-example/scripts/script.sh index bf1b11a6..f8998975 100755 --- a/config-example/scripts/script.sh +++ b/config-example/scripts/script.sh @@ -1,3 +1,3 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh -echo "hi from bash running on $(whoami)'s machine" +echo "hi from the shell running on $(whoami)'s machine" diff --git a/testdata/fail.sh b/testdata/fail.sh index afc4d3aa..08b3ae1d 100644 --- a/testdata/fail.sh +++ b/testdata/fail.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh echo "error is coming" exit 1 \ No newline at end of file From 1c0c613ffbdbef641325df85d05dd83744a80847 Mon Sep 17 00:00:00 2001 From: wass3r Date: Thu, 18 Apr 2019 00:38:41 -0500 Subject: [PATCH 7/8] style(lint): make linter happy --- remote/discord/remote.go | 5 ++++- utils/access_check.go | 2 +- utils/parse.go | 2 +- utils/rooms_test.go | 5 ++--- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/remote/discord/remote.go b/remote/discord/remote.go index 84f3cd26..26cbbecd 100644 --- a/remote/discord/remote.go +++ b/remote/discord/remote.go @@ -88,7 +88,10 @@ func (c *Client) Send(message models.Message, bot *models.Bot) { dg := c.new() switch message.Type { case models.MsgTypeDirect, models.MsgTypeChannel: - dg.ChannelMessageSend(message.ChannelID, message.Output) + _, err := dg.ChannelMessageSend(message.ChannelID, message.Output) + if err != nil { + bot.Log.Errorf("Unable to send message: %v", err) + } default: bot.Log.Errorf("Unable to send message of type %d", message.Type) } diff --git a/utils/access_check.go b/utils/access_check.go index a13f2f26..5e00fbe9 100644 --- a/utils/access_check.go +++ b/utils/access_check.go @@ -89,7 +89,7 @@ func isMemberOfGroup(currentUserID string, userGroups []string, bot *models.Bot) bot.Log.Debugf("Limiting to usergroups only works if you register " + "your bot as an app with Slack and set the 'slack_workspace_token' property. " + "Restricting access to rule. Unset 'allow_usergroups' and/or 'ignore_usergroups', or set 'slack_workspace_token'.") - return false, fmt.Errorf("SlackWorkspaceToken not supplied. Restricting access.") + return false, fmt.Errorf("slack_workspace_token not supplied - restricting access") } // Check if we are restricting by usergroup if bot.SlackWorkspaceToken != "" { diff --git a/utils/parse.go b/utils/parse.go index 47e8d1d6..69c05483 100644 --- a/utils/parse.go +++ b/utils/parse.go @@ -10,8 +10,8 @@ import ( // Match checks given value against given pattern func Match(pattern, value string, trimInput bool) (string, bool) { + var regx *regexp.Regexp re := strings.HasPrefix(pattern, "/") && strings.HasSuffix(pattern, "/") - regx := new(regexp.Regexp) if re { pattern = strings.Replace(pattern, "/", "", -1) diff --git a/utils/rooms_test.go b/utils/rooms_test.go index 21e0cb6f..10a2f596 100644 --- a/utils/rooms_test.go +++ b/utils/rooms_test.go @@ -9,9 +9,8 @@ import ( func TestGetRoomIDs(t *testing.T) { type args struct { - wantRooms []string - activeRooms map[string]string - bot *models.Bot + wantRooms []string + bot *models.Bot } // For Room Exists From 75eb0ed1afcc24c008536df99156c24a6f04c524 Mon Sep 17 00:00:00 2001 From: wass3r Date: Tue, 7 May 2019 22:50:54 -0500 Subject: [PATCH 8/8] style: fix typos --- remote/slack/helper.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/remote/slack/helper.go b/remote/slack/helper.go index 249ad26a..12a3f141 100644 --- a/remote/slack/helper.go +++ b/remote/slack/helper.go @@ -206,7 +206,7 @@ func getInteractiveComponentRuleHandler(verificationToken string, inputMsgs chan contents, err := sanitizeContents(buff) if err != nil { - bot.Log.Debugf("failed to santize content: %v", err) + bot.Log.Debugf("failed to sanitize content: %v", err) } var callback slack.AttachmentActionCallback @@ -507,7 +507,7 @@ func readFromRTM(rtm *slack.RTM, inputMsgs chan<- models.Message, bot *models.Bo // when the bot joins a channel add it to the internal lookup // NOTE: looks like there is another unsupported event we could use // Received unmapped event \"member_joined_channel\" - // Maybe watch ffor an update to slack package for future support + // Maybe watch for an update to slack package for future support if bot.Rooms[ev.Channel.Name] == "" { bot.Rooms[ev.Channel.Name] = ev.Channel.ID bot.Log.Debugf("Joined new channel. %s(%s) added to lookup", ev.Channel.Name, ev.Channel.ID)