GithubHelp home page GithubHelp logo

slack-go / slack Goto Github PK

View Code? Open in Web Editor NEW
4.6K 4.6K 1.1K 2.14 MB

Slack API in Go - community-maintained fork created by the original author, @nlopes

Home Page: https://pkg.go.dev/github.com/slack-go/slack

License: BSD 2-Clause "Simplified" License

Go 99.82% Makefile 0.18%
go golang slack

slack's People

Contributors

abourget avatar alyosha avatar antonylucisano avatar cjdenio avatar deto-r avatar dleviminzi avatar dlsniper avatar dvdplm avatar iaburton avatar james-lawrence avatar jamiehannaford avatar joefitzgerald avatar justinjudd avatar kanata2 avatar karoliskl avatar kouwakai avatar mumoshu avatar mzduke avatar nlopes avatar ollieparsley avatar parsley42 avatar rcarver avatar sryoya avatar stijndcl avatar suzuki-shunsuke avatar tylarb avatar valeriansaliou avatar winston-stripe avatar xnok avatar zchee 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  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

slack's Issues

Websocket / Keepalive

there are plenty of log.Fatal, log.Panic in the code, especially regarding disconnection...

My bot handles reconnecting after disconnection.. but this API makes it hard to recover as it kills the whole thing at many points.

Anyone using the websocket stream ? I'd like to either make it reconnection-handling friendly, or maybe implement the reconnection right into this lib. what do you think ?

OutgoingEventError

I'm somewhat unsure if this error even pertains directly to this package, but I think it might. Please correct me if I'm wrong in that assumption.

I'm currently using slick, which builds on top of this. For a number of messages I'm trying to send, I'm receiving OutgoingErrorEvents. A quickly hacked together debug event listener spits out that the description of these are write tcp my_ip:54821->slack_ip:443: i/o timeout. From reading other issues and PRs, I'm hoping this has something to do with https://github.com/nlopes/slack/pull/102. But I really don't have a clue... And if it doesn't, is there anything I could do to fix this?

Any help would be much appreciated ๐Ÿ™ƒ

don't crash when json can't be unmarshalled

Currently when a file is uploaded and the json can't be unmarshelled the lib class log.fatal instead it should panic so the code calling it can recover and does not need to manuall restart since log.Fatal calls os.Exit(1)

json.Unmarshal errors

Hi, great library, I'm using it for developing a bot, and yesterday he suddenly stopped with this error message:

json: cannot unmarshal number into Go value of type slack.JSONTimeString

I'm sorry that I cant' provide more information for now, but I'll try to catch this error later (the main problem is that it happened only once yet). I've taken a brief look at the code, and looks like there is a lot of JSONTimeString's everywhere, so probably, Slack guys started changing protocol a bit.

Use of closed tcp connection upon message send

So either I'm dumb or something's not working.

I've implemented a smallish bot using the lib that's supposed to respond to messages.
But after running for a while all incoming messages are processes, but once it tries to send a message I hit the following:

Unexpected: write tcp 10.249.126.60:58189->52.90.4.230:443: i/o timeout
Unexpected: write tcp 10.249.126.60:58189->52.90.4.230:443: i/o timeout
nlopes/slack2016/09/01 12:55:45 slack.go:86: Sending PING 20
nlopes/slack2016/09/01 12:55:45 slack.go:80: RTM Error sending 'PING 20': write tcp 10.249.126.60:58189->52.90.4.230:443: i/o timeout
nlopes/slack2016/09/01 12:55:45 slack.go:86: killing connection
Unexpected: &{false}
Unexpected: &{1 3}
Unexpected: read tcp 10.249.126.60:58189->52.90.4.230:443: use of closed network connection

Message is also not being re-sent on reconnect. Any ideas what I'm doing wrong? I saw that sendOutgoingMessage doesn't handle connection drops, but...

Add CI Build

Suggestion: Travis or Wecker.
Rationale: We need to run tests to verify we're not introducing regressions in PRs.

API stability

How stable is the current API? v0.0.1 is over a year old at this point - will the current code be tagged at some point soon?

Thanks

Naming

I am currently in the process of merging some really great changes from @abourget slack branch and a couple more from @mlbvsnba.

I would love to start moving towards merging naming for some things in the library but I thought asking what people prefer wouldn't harm anyone.

The ones I see so far are:
RTM vs WS
Client vs Slack

@joefitzgerald @abourget @mlbvsnba: would you guys mind chiming in on this if you feel strongly either way?

Thanks!

webhook support

May have missed it but I didn't see a method for posting to a webhook url. Ended up just generating a token to use but support and/or docs for webhook integration would be great!

mapping channel names to ids

hi, i'm wondering how to map a channel name (#general) to an ID or vice-versa.

in my code i would like to be able to write e.g. JoinChannel("#general") but to do that i need to get the channel id.

Channel type does not expose ID or name, so i am confused about how GetChannels or GetChannelInfo is useful...

Error starting the application

Returned the error when tried to start the application, the second try worked.

[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x55fa094141d5]

goroutine 12 [running]:
panic(0x55fa099da220, 0xc42000c050)
    /usr/lib/go/src/runtime/panic.go:500 +0x1a5
github.com/golang.org/x/net/websocket.(*Conn).SetWriteDeadline(0x0, 0xecfaec8ba, 0x55fa1492367a, 0x55fa09db18e0, 0xc4203f1900, 0x0)
    /go/src/github.com/golang.org/x/net/websocket/websocket.go:279 +0x45
github.com/github.com/nlopes/slack.(*RTM).connect(0xc4201c6900, 0x1, 0x8, 0x55fa096229ac, 0xb, 0x0)
    /go/src/github.com/github.com/nlopes/slack/websocket_managed_conn.go:94 +0x268
github.com/github.com/nlopes/slack.(*RTM).ManageConnection(0xc4201c6900)
    /go/src/github.com/github.com/nlopes/slack/websocket_managed_conn.go:32 +0x46

Searching I also found this issue in other project that uses the slack lib:
jpbruinsslot/slack-term#36

ManageConnection Loops forever after account_inactive event

I'm writing a slackbot service, and I noticed that when a user disconnects my slack app, even after I call rtm.Disconnect() my call to go rtm.ManageConnection() is continually attempting to reconnect with exponential backoff, and I have no way to tell it to stop running.

Is this a known issue? It looks like, from the code, that the unexported function rtm.connect doesn't listen to the killChannel until after it establishes the connection to slack, which won't ever happen if the error is because the user's token is invalid.

RTMEvent Decoder?

It would be ultra-convenient if RTMEvent implemented json.Unmarshaler so I could decode and replay RTMEvents from my Slackbot RTM event log for unit testing.

It seems the event mapping is not exported so this can't be done externally to the package without quite a bit of unnecessary overhead (unless I'm missing something.)

MessageEvent not triggering

It appears on the slack API documentation it talks about subscribing to channels to get information, however, when I run this package, doing the examples/websocket/websocket.go code with minor modifications, I never see the case *slack.MessageEvent: line trigger. I'm trying to figure out if there's a step to make this happen.. you can't make a bot join the channel.. So..

Error handling needs an update

https://github.com/nlopes/slack/blob/master/admin.go#L21 is a good example of bad errors.

That returns an error if something goes wrong, or it returns an error if the API gives a error. How do we differentiate between those two states? I can't show the API error to a user, because if it's a JSON Unmarshal error that's not a good idea. And currently the only way of checking would be to check if the error message contains a string, which is a bad idea.

Dave Cheney has a good set of examples on his blog http://dave.cheney.net/2016/04/27/dont-just-check-errors-handle-them-gracefully and has also made a very nice package that fits what he is saying https://github.com/pkg/errors

What do you think?

Edit: I accidentally the wrong dfc.

Shutting down gracefully is not obvious enough

Disclaimer: I'm very new to go, and also to the Slack API.

There's an rtm.Disconnect() available, which does appear to disconnect. However, if I use something starting with the websocket example, there's no obvious indication given to the client waiting on IncomingEvents that the disconnection has succeeded.

So, say I want to implement a "quit" command for the bot. I want the bot to say "Okay, fine" or something, then leave. If I break out of the event loop immediately after sending the message, the message never actually gets sent, because concurrency. If I call Disconnect, I do indeed disconnect and stop processing things, but... the program just sits there waiting for an event. It seems like maybe the channel should be closed once the disconnection is complete, since reconnect isn't implemented/available?

Attachment ts field is sometimes a string

I tried dumping messages from direct chats today and with one particular message I got an error:

json: cannot unmarshal string into Go value of type int64

After investigation I found that one message has the ts field for attachment as a string. I tired replacing the data type for attachment from int64 to string but it started crashing on another user, which means that this field can be both int64 and string.

I'm not fluent in Go to figure out a solution, so here's json of a response that crashes the script (changed names etc. for privacy):

{
  "ok": true,
  "latest": "1461156109.000043",
  "messages": [
    {
      "type": "message",
      "user": "U025QS77U",
      "text": "<https://something.slack.com/archives/lunch/p1461060720000152>",
      "attachments": [
        {
          "color": "4D394B",
          "from_url": "https://something.slack.com/archives/lunch/p1461060720000152",
          "fallback": "[April 19th, 2016 3:12 AM] someone: &gt; 12 1234 1234 1234 1234 1234 1234",
          "author_subname": "someone",
          "ts": "1461060720.000152",
          "text": "&gt; 12  1234 1234 1234 1234 1234 1234",
          "author_name": "Some User",
          "author_link": "https://something.slack.com/team/someone",
          "author_icon": "https://avatars.slack-edge.com/2015-04-17/12312312312231.jpg",
          "mrkdwn_in": [
            "text"
          ],
          "id": 1
        }
      ],
      "ts": "1461156085.000041"
    }
  ],
  "has_more": true
}

GetChannelHistory only retrieving last message posted on channel

I'm trying to get a history of messages for a channel.

`package main

import (
"fmt"
"github.com/nlopes/slack"
"io/ioutil"
"strings"
)

func main() {
token, err := ioutil.ReadFile("bot_token")
check(err)
str_token := strings.TrimSpace(string(token))
fmt.Printf("Token: %s\n", string(str_token))
api := slack.New(string(str_token))
channels, err := api.GetChannels(true)
check(err)
bot_id := getChannelIDFromName(channels, "bot")
fmt.Println(bot_id)
// msg_params := slack.PostMessageParameters{}
hst_params := slack.HistoryParameters{}
history, err := api.GetChannelHistory(bot_id, hst_params)
check(err)
fmt.Println(history)
for _, message := range history.Messages {
fmt.Println(message.Text)
}
}

func getChannelIDFromName(channels []slack.Channel, name string) string {
for _, channel := range channels {
if channel.Name == name {
return channel.ID
}
}
return ""
}

func check(e error) {
if e != nil {
panic(e)
}
}
`

The output from fmt.Println(history):
'&{ [{{message U17RLSCLA Hello World 1487703863.000191 false [] [] false [] false 0 []} }] true}`
This is despite the fact that there is actually a long history, and running the example command from the slack api doc returns many more messages.

Am I setting something up incorrectly?

deadlocks in rtm ping

to reproduce: revoke authorization from within slack ui for a bot, then try to invoke rtm.Disconnect().
it deadlocks. Adding a deadline to ping fixes the issue. it appears to be deadlocking during a force ping.

but the underlying cause is the websocket.JSON.Send(rtm.conn, msg) never returning. adding a deadline solves it. but it seems there is an underlying issue in the websocket library w/ regards to connections being closed.

func (rtm *RTM) ping() error {
    id := rtm.idGen.Next()
    rtm.Debugln("Sending PING ", id)
    rtm.pings[id] = time.Now()

    msg := &Ping{ID: id, Type: "ping"}
    // adding a deadline here prevents ping from potentially blocking forever on send.
    rtm.conn.SetWriteDeadline(time.Now().Add(1 * time.Second))
    err := websocket.JSON.Send(rtm.conn, msg)
    if err != nil {
        rtm.Debugf("RTM Error sending 'PING %d': %s", id, err.Error())
        return err
    }
    return nil
}

will provide a PR tomorrow.

RTM GetInfo() testing issue.

currently running into an issue we're trying to test some for that is looping over the IncomingEvents
and part of that is filtering out events from the bot user.

trying to test this code requires setting up a working connection even though none of the code actually needs a connection to be tested except for the fact there is no way of populating the Info structure without handshaking with slack.

Would be nice if we could manually set it (honestly I don't generally see the benefit in the GetInfo() call vs just exposing the field as you still have to check for nil since it may or may not be populated depending when you call it)

Websocket logging cleanup

Would be nice if some of the logging could be cleaned up.

It would be great if you either setup a public *log.Logger so the user can tweak the settings without messing with their own log or at least only log when the Slack struct has debug on.

Crash with unmarshallable json...

First off, thanks for the pkg. I was originally using hal, but have moved over to using your api and a tiny custom framework, and it's a real pleasure so far.

My bot is periodically dying, I suspect possibly due to something int he latency response code, I'll take a look soon, but thought I'd report it here just incase:

json: cannot unmarshal number into Go value of type slack.JSONTimeString

I've not got a definitive way of triggering the problem yet. Will send a PR if I work it out.

Panic when calling AckErrorEvent.Error()

Hi

The code panics when trying to calling the Error() method on a AckErrorEvent instance (looks like the underlying ErrorObj error is nil):

panic: value method slack.RTMError.Error called using nil *RTMError pointer

goroutine 18 [running]:
panic(0x988720, 0xc420433980)
        /usr/local/Cellar/go/1.7.3/libexec/src/runtime/panic.go:500 +0x1a1
github.com/nlopes/slack.(*RTMError).Error(0x0, 0x1, 0xffffffffffff0101)
        <autogenerated>:112 +0xc5
github.com/nlopes/slack.(*AckErrorEvent).Error(0xc42040aa10, 0x9, 0xa509f4)
        /Users/marc/dev/abitbot/vendor/src/github.com/nlopes/slack/websocket_internals.go:91 +0x33
abitbot/source.(*SlackSource).Run(0xc4201c0190)
        /Users/marc/dev/abitbot/src/abitbot/source/slack.go:361 +0x9ae
created by main.main
        /Users/marc/dev/abitbot/src/cmd/george/main.go:134 +0x950

Maybe it would be better for the Error() method to return directly the error value instead of a string representation, or at least check that the ErrorObj error is non-nil before calling the Error() method on it?

Send message to channel by name instead of id?

Hi, and thanks for this cool library. I have a small issue sending messages to channels by using name ('#general'). Using the channel id works just fine, but it's kind of tedious to maintain.

The RTM example on https://github.com/nlopes/slack/blob/master/examples/websocket/websocket.go uses #general (alltough it says to replace that name with the channel id). Is this library supposed to work with channel names, or do I have to lookup the channel id by name, when creating the client? Sorry to open a new issue for this.. :-)

Unhandled response

I'm working with this lib in a project using it for the websockets RTM API implementation, and when receiving an error response from the api this line https://github.com/nlopes/slack/blob/master/websocket.go#L184 Is making the app crash.

The error responses from slack are also going here and I think it should handle the error gracefully.

For instance when sending a message with empty text, slacks answer is: {"ok":false,"reply_to":1,"error":{"code":2,"msg":"message text is missing"}}

Making the Unmarshal fail and exiting the app.

I think that the unmarshal error could be relaxed and at least reach https://github.com/nlopes/slack/blob/master/websocket.go#L194-L195

Said that, agree that error should not end up in that bucket.

JSON Roundtrip Issue For Forward Slash

Slack's JSON escapes / such that it is emitted as \/. This Unmarshals correctly but json.Marshal doesn't re-escape this character by default. It may be worth adding a custom encoder to handle this scenario correctly.

json unmarshal error when starting RTM with wrong credentials

slackApi = slack.New("a-wrong-key")
slackApi.SetDebug(true)
_, err := slackApi.StartRTM("", "http://example.com")
if err != nil {
    log.Printf("Error starting RTM: %s", err)
}
2015/05/13 12:15:26 {"ok":false,"error":"invalid_auth"}
2015/05/13 12:15:26 Error starting RTM: json: cannot unmarshal string into Go value of type slack.SlackWSError

The response returned by Slack is {"ok":false,"error":"not_authed"}
This line then tries to parse that as a infoResponseFull and fails, which causes the error above.

Obtain channel ID

To send a message using the rtm protocol, I need the channel ID, it seems it does not work just using "#channelname".

Then, the problem is how to obtain that ID, as GetChannelInfo does not return it. I think it is returned bu the API, so it should be easy to return from GetChannelInfo

Possibility to extend the API?

Hello @nlopes,

First of all, great work with this client, seems pretty nice ๐Ÿ‘.
I'm opening this issue because I'm interested in extend the API for example of channels, creating a method getCurrentChannels or methods build on top of the Slack API.

In order to increase the usability and keep all the "module" the pure operations that you can do to get info of Slack.

What do you think?

Thanks!

Enhancement: Allow externally-provided *http.Client

I need to use this library from an AppEngine frontend, which necessitates the use of Google's urlfetch API, which provides a custom *http.Client. I have it patched on my end (slack.Slack gets an extra config *http.Client field that's initialized in slack.New()), but I wanted to be sure you were receptive to such a change before submitting a patch.

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.