Giter VIP home page Giter VIP logo

slacker's Introduction

shomali11/slacker has moved to slack-io/slacker

Please update your import statements to use the official slack-io/slacker.

slacker's People

Contributors

1k-off avatar arusso avatar asafalima avatar avbasov avatar ayjayt avatar batagliao-luizalabs avatar broxgit avatar ccrims0n avatar clstb avatar dependabot[bot] avatar erizocosmico avatar evandroflores avatar jazg avatar k321rf avatar kpaulisse avatar mavimo avatar nicolas-carlier-ls avatar piclemx avatar pims avatar pschwartz avatar raed-shomali avatar renatoaquino avatar sjauld avatar themarcelor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

slacker's Issues

Can't pass a handler to Bot.Command

So I have the following code:

func handleHello(request *slacker.Request, response slacker.ResponseWriter) {
	name := request.Param("name")
	if name == "" {
		response.Reply("Usage: @hellobot hello Name")
		return 
	}
	response.Reply("Hey " + name + "!")
}

func main() {
	bot := slacker.NewClient(os.Getenv("API_TOKEN"))
	bot.Command("hello <name>", "Say hello to someone", handleHello)
	err := bot.Listen()
	if err != nil {
		panic(err)
	}
}

but it's throwing an error if I use a function instead of defining a function in the Command call. Thoughts on this?

error is:

cannot use handle (type func(*slacker.Request, slacker.ResponseWriter)) as type func(slacker.Request, slacker.ResponseWriter) in argument to bot.Command

Send message to another user / expose RTM

Hi again,

I want to send a message to another user (not the one that sent the command) from the bot.

Using the nlopes/slack api I would do rtm.OpenIMChannel(userID) followed by rtm.SendMessage(rtm.NewOutgoingMessage("hello", userChannel)).

But right now the only the Client is exposed in the Slacker struct. Could the rtm be exported too? Or is there another way of doing this?

ctx.Cancel() won't propogate immediately

The control structure is set up so that ctx.Cancel won't propagate until some event occurs from the slack channel-

In slacker.go, in func (s *Slacker) Listen(ctx context.Context) error

It makes it hard to turn the bot on and off. Fix incoming.

RTM Error when processing events

Hello,

For the last few days the slacker library has been unable to process RTM events. Not sure if this is due to a bug or a upstream change by slack.

Debug Log
nlopes/slack2019/11/25 12:49:36 websocket_managed_conn.go:471: RTM Error, could not unmarshall event "message": {"client_msg_id":"a5dd84e7-de31-4988-b295-7c71a65b1f30","suppress_notification":false,"type":"message","text":"<@UCDV3PDHA> help","user":"UDB261B46","team":"T041L0Z03","blocks":[{"type":"rich_text","block_id":"f76c","elements":[{"type":"rich_text_section","elements":[{"type":"user","user_id":"UCDV3PDHA"},{"type":"text","text":" help"}]}]}],"user_team":"T041L0Z03","source_team":"T041L0Z03","channel":"DD9FTPJE8","event_ts":"1574704175.007700","ts":"1574704175.007700"}

Since you are dropping the actual error from json.Unmarshal I added it and see the following:
2019/11/25 12:49:36 unsupported block type

LMK what other information you might need to troubleshoot.

Allow ability to define a Default Inner Event Handler

It would be largely beneficial to be able to define a Default Inner Event Handler similar to how we define a defaultEventHandler.

This would allow custom handling for events such as:

  • member_joined_channel
  • member_left_channel
  • group_left
  • group_deleted
    etc...

I would like to submit a pull request for this, I have a branch ready to go

Retrieve Trigger ID from Slash Commands

I am trying to retrieve the Trigger ID from a Slash Command so that I can open a Modal. I noticed in the message handler when an event matches slash command, the Data prop is given the req object instead of the evt obj like the other Message Events. This means I can no longer pull the trigger_id from the event.

The slash command is the only type that uses request for the data prop instead of the evt

Remove vendored slack package

So that we can call the RTM func with all the power of the nlopes/slack library.

I.E. bot.Client.SendMessageContext(context.Background(), request.Event.Channel, slack.MsgOptionAttachments(attachments...)) which is not possible because it tries to compare to the vendored library.

When enabled threaded reply, two duplicate messages are delivered

Code:

  definition := &slacker.CommandDefinition{
    Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
      fmt.Println(botCtx.Event().BotID)
      image := request.Param("image")
      response.Reply(fmt.Sprintf("%s promoted here", image), slacker.WithThreadReply(true))
    },
  }

  bot.Command("promote <image>", definition)

Slack delivery:

image

When removed the Thread delivery, I get only one response

Using a different implementation of ResponseWriter in handleMessage?

Context

Even though a Command has a handler function that receives a ResponseWriter interface:

handler func(request *Request, response ResponseWriter)

handleMessage uses a implementation of ResponseWriter, Response:

slacker/slacker.go

Lines 140 to 158 in a253fd2

func (s *Slacker) handleMessage(event *slack.MessageEvent) {
response := NewResponse(event.Channel, s.RTM)
ctx := context.Background()
for _, cmd := range s.botCommands {
parameters, isMatch := cmd.Match(event.Text)
if !isMatch {
continue
}
cmd.Execute(NewRequest(ctx, event, parameters), response)
return
}
if s.defaultMessageHandler != nil {
s.defaultMessageHandler(NewRequest(ctx, event, &proper.Properties{}), response)
}
}

Question

What is the suggested approach to use a different implementation of ResponseWriter?

Username retrieval

I am trying to retrieve the username of the person talking to the bot, but have been unsuccessful. I can get the userid, but not the name. Is there any permission or other issues that you are aware of?

sendSlackNotification(concatenated + "---" + botCtx.Event().Username + "---" + botCtx.Event().User)

Adding flags

Hey, i think this could be a cool improvement for slacker if we got something like
https://github.com/spf13/cobra

with flags

Interesting you think?

Custom unauthorised error message not used.

There is a function to set the unauthorised error message

// UnAuthorizedError error message
func (s *Slacker) UnAuthorizedError(unAuthorizedError error) {
	s.unAuthorizedError = unAuthorizedError
}

However, this value is not used - the actual implementation just uses the var.

if cmd.Definition().AuthorizationFunc != nil && !cmd.Definition().AuthorizationFunc(request) {
			response.ReportError(unAuthorizedError)
			return
		}

Will send through a quick PR

Slack Side Setup?

What is required on the slack app setup side for the example 1 for the simple bot.Listen() to work for ping?

Getting all command arguments

Thanks for a nice library!

I wanted to create a command like this one:

bot.Command("alert <msg>", "Set the system alert msg. Example: `@deployprod alert Today at noon ...`", alert(bot))

If I use alert := request.Param("msg") I only get the first word Today not all the words Today at noon ....

I can parse it out from request.Event.Msg.Text, but it would be nice if there was an easy way to get it. Perhaps from the slacker.Request?

Any sentence containing the word `help` anywhere will call the Help Command

Hi,
I'm having some issues with the Help Command specification.

Currently using in my code Slacker Git revision: 37d2f0f

Specifically I set a command to be something like:

	// function tied to sentences sent to the Bot and starting with "open emergency" followed by some text
	emergencyCmdDefinition := &slacker.CommandDefinition{
		Description: "Open an EMERGENCY incident to Customer Support",
		Handler: func(request slacker.Request, response slacker.ResponseWriter) {
			if err := Emergency(request, response, config); err != nil {
				Err(err.Error())
				return
			}
		},
	}
	bot.Command("open emergency <msg>", emergencyCmdDefinition)

and then added the Help function as:

	// set the "help" message handling function
	helpCmdDefinition := &slacker.CommandDefinition{
		Description: "Help function",
		Handler: func(request slacker.Request, response slacker.ResponseWriter) {
			help(response, config)
		},
	}
	bot.Help(helpCmdDefinition)

But any sentence that contains the help word will trigger the Help Command (I guess because that's parsed earlier from what I read in your code).

Say that you write open emergency my printer is on fire... I need some help! that would still just print the help instead of triggering the open emergency command as it normally would.

I'd just want the help command to be triggered when the ONLY word is "help"... otherwise IMO the rest of the parsing should happen (go through normal commands parsing and then hit the DefaultCommand).

You can see the full code here: https://github.com/gravitational/slackbot/blob/master/slackbot.go#L74

Debugging why a response isn't being shown in Slack

I have a situation where I can see that my command is reaching the slackbot, and it is responding, but the response is not showing up in Slack. It's hard for me to tell if this is something wrong with the bot/slacker, or if it's something else, and I'm wonder if there are good strategies for debugging this? I'm happy to try things out and then add some documentation here via PR with any helpful info I come up with.

Here's what I have so far:

I have put the "ping" command for testing, with a log line to show that the handler is getting executed -- it is:

definition := &slacker.CommandDefinition{
     Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
          fmt.Println("I've been asked to ping-pong!")
          response.Reply("pong")
     },
}

bot.Command("ping", definition)

I've added debug(true) to the client:
bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"), slacker.WithDebug(true))

When I start the bot, I see what I'd expect, although there is a message about unsupported Events API event received:

Connecting to Slack with Socket Mode.
slack-go/slack/socketmode2021/06/17 14:25:32 socket_mode_managed_conn.go:258: Starting SocketMode
slack-go/slack2021/06/17 14:25:32 socket_mode.go:30: Using URL: wss://wss-primary.slack.com/link/?ticket=<etc>
slack-go/slack/socketmode2021/06/17 14:25:32 socket_mode_managed_conn.go:266: Dialing to websocket on url wss://wss-primary.slack.com/link/?ticket=<etc>
slack-go/slack/socketmode2021/06/17 14:25:33 socket_mode_managed_conn.go:91: WebSocket connection succeeded on try 0
slack-go/slack/socketmode2021/06/17 14:25:33 socket_mode_managed_conn.go:439: Starting to receive message
Connected to Slack with Socket Mode.
slack-go/slack/socketmode2021/06/17 14:25:33 socket_mode_managed_conn.go:481: Incoming WebSocket message: {
  "type": "hello",
  "num_connections": 2,
  "debug_info": {
    "host": "applink-d85c5c684-wkb2x",
    "build_number": 18,
    "approximate_connection_time": 18060
  },
  "connection_info": {
    "app_id": "<id here>"
  }
}

slack-go/slack/socketmode2021/06/17 14:25:33 socket_mode_managed_conn.go:493: Finished to receive message
slack-go/slack/socketmode2021/06/17 14:25:33 socket_mode_managed_conn.go:439: Starting to receive message
slack-go/slack/socketmode2021/06/17 14:25:33 socket_mode_managed_conn.go:336: Received WebSocket message: {"type":"hello","num_connections":2,"debug_info":{"host":"applink-d85c5c684-wkb2x","build_number":18,"approximate_connection_time":18060},"connection_info":{"app_id":"<id here>"}}
slack-go/slack/socketmode2021/06/17 14:25:33 slacker.go:185: unsupported Events API event received
slack-go/slack/socketmode2021/06/17 14:25:38 socket_mode_managed_conn.go:561: WebSocket ping message received: Ping from applink-d85c5c684-wkb2x

When I chat with the bot in Slack and say "ping", I get no response, but I see this logged:

slack-go/slack/socketmode2021/06/17 14:28:25 socket_mode_managed_conn.go:493: Finished to receive message
slack-go/slack/socketmode2021/06/17 14:28:25 socket_mode_managed_conn.go:439: Starting to receive message
slack-go/slack/socketmode2021/06/17 14:28:25 socket_mode_managed_conn.go:336: Received WebSocket message: {"envelope_id":"9159361e-b381-4801-85a5-eedad48bc59a","payload":{"token":"<token>","team_id":"<id>","api_app_id":"<id>","event":{"client_msg_id":"e7d533c4-9442-4fac-8b86-cef8181f93b7","type":"message","text":"ping","user":"<user>","ts":"1623965305.000200","team":"<team>","blocks":[{"type":"rich_text","block_id":"ckcY","elements":[{"type":"rich_text_section","elements":[{"type":"text","text":"ping"}]}]}],"channel":"<channel>","event_ts":"1623965305.000200","channel_type":"im"},"type":"event_callback","event_id":"Ev025MBNNNLC","event_time":1623965305,"authorizations":[{"enterprise_id":null,"team_id":"<team>","user_id":"<user>","is_bot":true,"is_enterprise_install":false}],"is_ext_shared_channel":false,"event_context":"2-message-T065FDZTQ-A02305WBY31-D024FNJ3953"},"type":"events_api","accepts_response_payload":false,"retry_attempt":0,"retry_reason":""}
slack-go/slack/socketmode2021/06/17 14:28:25 socket_mode_managed_conn.go:430: Scheduling Socket Mode response for envelope ID 9159361e-b381-4801-85a5-eedad48bc59a: {"envelope_id":"9159361e-b381-4801-85a5-eedad48bc59a"}
slack-go/slack/socketmode2021/06/17 14:28:25 socket_mode_managed_conn.go:312: Sending Socket Mode response with envelope ID "9159361e-b381-4801-85a5-eedad48bc59a": &{9159361e-b381-4801-85a5-eedad48bc59a <nil>}
I've been asked to ping-pong!
slack-go/slack/socketmode2021/06/17 14:28:25 socket_mode_managed_conn.go:321: Finished sending Socket Mode response with envelope ID "9159361e-b381-4801-85a5-eedad48bc59a"
slack-go/slack2021/06/17 14:28:25 chat.go:233: Sending request: attachments=%5B%5D&blocks=%5B%5D&channel=<channel>&text=pong&token=<token>

(I have obviously taken out anything potentially sensitive/security-related)

Since I can see the response being sent, I'm not sure where to check next to see what the problem might be -- all of the connection, auth, etc seems fine. Any suggestions would be very much appreciated -- thanks for your help!

Latest commit on master has errors on import

Hi,

Running go get github.com/shomali11/slacker gives me the following errors:

../../vendor/github.com/shomali11/slacker/response.go:47:19: too many arguments in call to r.rtm.Client.PostMessage
	have (string, slack.MsgOption, slack.MsgOption, slack.MsgOption, slack.MsgOption)
	want (string, string, slack.PostMessageParameters)
../../vendor/github.com/shomali11/slacker/slacker.go:38:29: undefined: slack.OptionDebug

Current version/commit pulled: 9751a4188b6a

Unable to compile my code with this version.

This only works with "classic" slack apps

I think the README should be updated to indicate it uses the RTM API which does not function with new slack apps that have granular oauth permissions.

Took me 40 minutes to figure out what was going on by finally dropping the debug option in the config and seeing:

slack-go/slack2020/07/18 13:56:31 websocket_managed_conn.go:177: Connecting to RTM
slack-go/slack2020/07/18 13:56:32 rtm.go:71: Using URL:
slack-go/slack2020/07/18 13:56:32 websocket_managed_conn.go:181: Failed to start or connect to RTM: not_allowed_token_type
slack-go/slack2020/07/18 13:56:32 websocket_managed_conn.go:147: reconnection 1 failed: not_allowed_token_type reconnecting in 100ms
...

It is possible to still create apps that use the old permissions scopes but they are pushing everything to the events API.

More info in this thread slackapi/node-slack-sdk#921 (comment)

Auth not working

Starting from your example, I'm testing a quick bot, but I'm getting an auth error. It's not clear from the code:

bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"))

Whether this requires either a BOT token or an APP token, or if it needs both and what the difference is? For our Slack setup, I got an "API token" that should be a BOT token. When I set that and run it, I get:

Connecting to Slack with Socket Mode.
2021/05/26 14:52:01 not_authed
exit status 1

Just to check, I used the token as SLACK_APP_TOKEN and then it just repeats:

Connecting to Slack with Socket Mode.
Connection failed. Retrying later...

Over and over.

It's not clear what the "not_authed" error means -- was the token refused, or did it fail to connect for authentication, or something else? Any hints on debugging this? Thank you!

interface order

Its more idiomatic in Go to have the "outout/response" as the first argument.

func (w slacker.Response, r slacker.Request, ...

I think this is likely worth the breaking change since you have yet to make public release according to the github UI. cheers.

Create releases for Slacker

It would be helpful to cut releases for Slacker that make it easy for users to pin to a particular versions (and not the auto-generated versions go creates) and provide release notes for each release.

While this isn't something that we'll be doing often, it's also easy to do with goreleaser and improves the quality of the project imo.

Infinity loop

When sending a gif url with the response.reply() func, my bot start to go in a infinity loop. Looks like the user in the context is empty or USLACKBOT
Do you got i idea how to handle that?

Creating a command with multiple long parameters

I'd like to create a command like so:

@bot <summary> <description>

Where I can specify summary as "my summary" and description as "my description" with the quotation marks there.

Is this possible to do?

Expose the slack client in AuthorizedFunc

We'd like to be able to authenticate a Slack user with a backend database that has no concept of Slack User IDs, but to get the requesting users profile details we need access to the Slack client. Simple example:

var myCommand = &slacker.CommandDefinition {
    ...
    AuthorizationFunc: func(request slacker.Request, client slack.Client) bool {
        ...
        userInfo, _ := client.GetUserInfo(request.Event().User)
        return AuthorizeFromDatabase("some-command", user.Profile.Email)
    },
    ...
}

Feature Request: ParseFunc to override parser

Are you open to these feature improvements:

  • CommandDefinition taking a ParseFunc(string) interface{} and uses this instead of default parser

  • CommandDefinition can override help string

I will implement this in my fork today but I was wondering if you had any feedback/were interested.

Allow overriding command constructor

Add the option for the user to provide a custom command constructor.
This can be used to prefix all commands with the bot name to make the bot respond to messages without proper Slack mention (for example instead of @MyBot ping you can make it listen to all messages in the channel, add the name prefix to the command and invoke mybot ping)
In out use case we need it to pass customize the creation of the commander command (See shomali11/commander#3).

Interactive callback example for attachment buttons and dropdown

I scan through the example, there is interactive callback for NewActionBlock, do you have example if action is from attachment ? For example

	Actions: []slack.AttachmentAction{
				slack.AttachmentAction{
					Name:  "accept",
					Text:  "Accept",
					Type:  "button",
					Value: "accept",
				},
				slack.AttachmentAction{
					Name:  "reject",
					Text:  "Reject",
					Type:  "button",
					Value: "reject",
					Style: "danger",
				},
				slack.AttachmentAction{
					Name: "Select Action",
					Type: "select",
					Options: []slack.AttachmentActionOption{
						{
							Text:  "Asahi Super Dry",
							Value: "Asahi Super Dry",
						},
						{
							Text:  "Kirin Lager Beer",
							Value: "Kirin Lager Beer",
						},
						{
							Text:  "Sapporo Black Label",
							Value: "Sapporo Black Label",
						},
						{
							Text:  "Suntory Malt’s",
							Value: "Suntory Malts",
						},
						{
							Text:  "Yona Yona Ale",
							Value: "Yona Yona Ale",
						},
					},
				},
			},

Support for Slash Commands

Slack's Slash Commands offer another method of invoking some kind of action from within Slack, much like bot commands can do, but have the benefit of providing an arguably nicer user experience by pulling up a context pop up on how to invoke it, without requiring the user to memorize commands or to send a help message to a bot user.

Given the similarities between slacker's bot commands and slash commands, seems like a logical step to support both, and with Socket Mode support, we now have that option.

Capture at beginning of line captures ID as well as capture item

The capture

bot.Command("<bot> <cluster>", "TODO", func(request slacker.Request, response slacker.ResponseWriter) {}

will return <bot> as

<@UABU3NX6D> foo

But the capture

bot.Command("features <bot> <cluster>", "TODO", func(request slacker.Request, response slacker.ResponseWriter) {}

will return <bot> as
foo

Not able to get a response using the slack token

I've been trying to get the ping program running by using a the Slack bot token. I was able to get this working before but it doesn't seem to work anymore. Is anyone else experiencing this ?

Copy & paste introduces nbsp `\u00a0` character

When someone copies & pastes commands, they end up with a weird character \u00a0 do the command ends up being ignored.

U+00A0 No-Break Space (NBSP) Unicode Character).

e.g., The payload shows something like "text":"\u00a0my-command arg1 arg2"

The payload can be visualized if we start Slacker in DEBUG mode:

                bot = slacker.NewClient(slackBotToken, slackAppToken, slacker.WithDebug(true))

Perhaps the input could be sanitized?

Getting a compilation error on Example 7

cannot use "github.com/nlopes/slack".FileUploadParameters literal (type "github.com/nlopes/slack".FileUploadParameters) as type "github.com/shomali11/slacker/vendor/github.com/nlopes/slack".FileUploadParameters in argument to bot.Client.UploadFile

What am I missing?

panic: runtime error when adding DispatchActionConfig.TriggerActionsOn NewPlainTextInputBlockElement

This works:

textElement := slack.NewPlainTextInputBlockElement(textPlaceholder, "bulkemails")
textElement.MaxLength = 2500
textElement.Multiline = true

But when I add:

var actions []string = []string{"on_enter_pressed"}

textElement.DispatchActionConfig.TriggerActionsOn = actions

I get:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x8193c4]

I've tried updating to the latest slack-go/slack API and still have the issue. It seems to be supported upstream: https://github.com/slack-go/slack/blob/03f86be11aa50ac65d66f3917e250d3257389028/block_element.go#L409

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.