BlakeWilliams / Elixir-Slack

Slack real time messaging and web API client in Elixir
MIT License
674 stars 183 forks source link

Unable to send messages unless removed then re-invited #231

Open Rodeoclash opened 3 years ago

Rodeoclash commented 3 years ago

Apologies if this is something intrinsic to the way that Slack works and is not the fault of this library.

I've have some unusual behaviour that means I can only send a message if:

  1. The bot is connected
  2. The bot is invited to the channel within its "session".
  3. The bot maintains its current "session", that is, I cannot restart the server, without requiring the bot to removed and invited again to the test channel.

Currently as I right this, I have a work implementation and can send a hello world message using the example code from the Readme in my REPL. The bot is currently connected to its private test channel that I am using and I see the messages appearing fine.

If I restart iex using ctrl-c then start it again (iex -S mix) I see that the bot connects successfully (the handle_connect). However, if I send a message then I get the error: 12:20:41.848 [error] channel #bot-test not found.

If I remove the bot from the channel then re-invite the bot again, the correct behaviour is restored and I'm able to send messages once more (this is while maintaining the same iex session where it was previously failing) so something about removing then inviting the bot again seems to make things work again.

I'm a bit concerned that deployments are doing to be difficult as I'm not planning on using code reloading and instead just running everything in a Docker container. I assume this will suffer the same issues that I've described above.

Am I missing something when establishing my initial connection (or in general about how Slack bots work)? I'm happy to add something to the documentation in a PR to make this easier for the next developer once I understand what's going.

Please let me know what debugging would be useful if this is not a PEBCAK.

BlakeWilliams commented 3 years ago

That doesn't sound like how I'd expect the library to behave. Can you share code that reproduces the issue so I can look into it?

Rodeoclash commented 3 years ago

For sure. It's a bit work in progress:

This is a gen server I use to wrap your library, it handles storing the pid generated from starting it and tracking if it has connected to Slack or not. https://github.com/Rodeoclash/coronabot/blob/master/server/lib/coronabot/slack/slack.ex

Here is a duplicate of the example code with some additional debugging: https://github.com/Rodeoclash/coronabot/blob/master/server/lib/coronabot/slack/rtm.ex

I send messages by casting to the wrapping gen server. See line 19 of slack.ex

Coronabot.SlackBot.message("Hello world")

It's also worth noting that I'm using the "Bot" integration, not a Slack app. I could try converting it and seeing if I have the same issue.

BlakeWilliams commented 3 years ago

Can you reproduce the issue without the genserver wrapper?

Rodeoclash commented 3 years ago

I'll try that next. I wanted to check I'm not doing anything obviously wrong or misunderstanding its use before I got stuck into debugging. Thanks for the tech support and if I can replicate the issue stand alone, I'll let you know.

Rodeoclash commented 3 years ago

@BlakeWilliams Here's some additional debugging outside of the wrapped GenServer. In the debugging below, the module SlackRtm is a copy paste of the one from the example (I've redacted the GenServer state in the error as it contains the token and channel information - I can supply if required):

iex(1)> {:ok, rtm} = Slack.Bot.start_link(SlackRtm, [], "xoxb-493178807798-1256155172004-Se3kcwzJJhTS7t7O1XlkNZJw")
{:ok, #PID<0.295.0>}
Connected as coronabot
iex(2)> send rtm, {:message, "External message", "#coronabot-test"}                                                
Sending your message, captain!
{:message, "External message", "#coronabot-test"}
iex(3)> 
10:50:49.587 [error] [{Slack.Sends, :send_message, 3, [file: 'lib/slack/sends.ex', line: 19]}, {SlackRtm, :handle_info, 3, [file: 'iex', line: 18]}, {Slack.Bot, :websocket_info, 3, [file: 'lib/slack/bot.ex', line: 133]}, {:websocket_client, :handle_info, 3, [file: '/usr/src/app/deps/websocket_client/src/websocket_client.erl', line: 415]}, {:gen_fsm, :handle_msg, 8, [file: 'gen_fsm.erl', line: 497]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 249]}]

10:50:49.587 [error] channel #coronabot-test not found

10:50:49.592 [error] ** Websocket client Slack.Bot terminating in :websocket_info/3
   for the reason :error:%RuntimeError{message: "channel #coronabot-test not found"}
** Last message was {:message, "External message", "#coronabot-test"}

Here I've removed the bot and re-invited it to the channel again using the Slack client.

Screenshot from 2020-07-20 20-54-56

And a follow up message you can see in the screenshot:

iex(1)> {:ok, rtm} = Slack.Bot.start_link(SlackRtm, [], "xoxb-493178807798-1256155172004-Se3kcwzJJhTS7t7O1XlkNZJw")
{:ok, #PID<0.309.0>}
Connected as coronabot
iex(2)> send rtm, {:message, "External message", "#coronabot-test"}                                                
Sending your message, captain!
{:message, "External message", "#coronabot-test"}
iex(3)> 

As far as I can tell, the bot has to be online and connected when being asked to join the channel to have the correct state to post messages to it. If the bot is stopped then started again while remaining in the channel then it will be put into the failure state.

bigboxdave commented 3 years ago

For what it's worth, I'm experiencing the same issues trying to send messages via my bot.

I've tried creating a new channel and re-inviting the bot user, but I can't send a message via process PID.

20:51:08.542 [error] channel #bottest not found

20:51:08.543 [error] ** Websocket client Slack.Bot terminating in :websocket_info/3
   for the reason :error:%RuntimeError{message: "channel #bottest not found"}