Please update your import statements to use the official slack-io/slacker
.
shomali11 / slacker Goto Github PK
View Code? Open in Web Editor NEWSlack Bot Framework
License: MIT License
Slack Bot Framework
License: MIT License
Please update your import statements to use the official slack-io/slacker
.
Example 12 (https://github.com/shomali11/slacker/blob/master/examples/example12.go) doesn't work properly when running @bot secret
I got the following messages:
"*Error:* _You are not authorized to execute this command_"
"You are authorized!"
I noticed that is probably missing a flow interruption in:
https://github.com/shomali11/slacker/blob/master/slacker.go#L213
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?
Block Kit is the next evolution of message response ui for slack.
https://api.slack.com/block-kit
Using Block Kit a user can create reusable ui blocks and templates. Support for Block kit was added to nlopes/slack from mid February to the end of March.
cannot use attachments (type []"github.com/nlopes/slack".Attachment) as type []"github.com/shomali11/slacker/vendor/github.com/nlopes/slack".Attachment in assignment
What is required on the slack app setup side for the example 1
for the simple bot.Listen() to work for ping
?
I was trying to install slacker in an empty project and got the following error:
../../pkg/mod/github.com/shomali11/[email protected]/defaults.go:51:16: undefined: slack.Block
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:
I would like to submit a pull request for this, I have a branch ready to go
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.
I was just trying to trigger the bot with !<COMMAND_NAME> like !catch etc. commands. However, messages handled for only mention or direct message for slack.MessageEvent case. How can we add any condition like isCommandPrefixMatch or sth like this ?
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?
Slack only supports Oauth now, there is an issue upstream aswell (#184) , could you provide a way to authorize the bot?
It hard to mock our element because we have only struct instead of interface
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.
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?
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.
It does not look like the DefaultCommand is wired up so its not being called if you pass an unknown command to the bot. I have a PR to fix this
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.
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
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
Such as some notification system would send a message to a channel.
AuthFunc(slacker.Request) bool
that decides if command is auth'd and returns true or falseI will implement this today on my fork but I was looking for feedback if you had it/were interested in it.
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
?
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!
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)
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.
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.
How can get a channel name (#genenal like ) when received event? right now seems only channel id can read from even.
i copy the example go file, and wrote @app run, it only responds to the 1st mention. while if i register new command it respond again to the very 1st one. Any reason for this? thanks
currently it's hard coded to ignore message from other bot. My suggestion that this behavior is configurable and by default still ignores it.
My use case is to listen to react to prometheus error message do something in the background.
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)
},
...
}
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?
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
Slack Team started to return a query string parameter with their websocket URLs, and the current version of nslopes/slack stopped work. After this pull request merge nslopes/slack started to work again.
Here is a PR (#9) that aims to fix the version on shomali11/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.
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?
Data
on BotContext.Event()
points to https://pkg.go.dev/github.com/slack-go/[email protected]/slackevents#MessageEvent and does not have the team_id
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).
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:
When removed the Thread delivery, I get only one response
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",
},
},
},
},
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 ?
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
Hello 👋
Maybe a dumb question, but why this library isn't using the new (and maintained) https://github.com/slack-go/slack library, since github.com/nlopes/slack
has moved.
Thank you in advance.
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
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)
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!
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?
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
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.
The related commit is shomali11/commander@f0ee633 .
The type of IsParameter has been changed from bool to func() bool. Should update slacker.go:234 to:
if token.IsParameter() {
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.