A thin wrapper around event subscriptions and web API. Existing Elixir slack libraries seem to use the deprecated RTM API (and don’t work for new apps/bots).
slack_elixir leverages Slack’s new Socket Mode for event subscriptions.
See it here:
A thin wrapper around event subscriptions and web API. Existing Elixir slack libraries seem to use the deprecated RTM API (and don’t work for new apps/bots).
slack_elixir leverages Slack’s new Socket Mode for event subscriptions.
See it here:
Thanks for putting this library together, it’s exactly what we needed!
I’ve followed the README and when a user types “!Roll” for instance into a channel, I am receiving a response:
"debug] [Socket] message: %{“accepts_response_payload” => false, “envelope_id” => “ad67455d-8e23-4f59-a3de-fbb6b73332d6”, “payload” => %{“api_app_id” => “A0628UXU7FB”, “authorizations” => [%{“enterprise_id” => ni… "
So, all seems good there, but when the send_message function fires and returns {:ok}, I do not see the response message in the channel. Anything I could try to see the bot’s response in the channel?
Also, right now, for user / channel, I’m receiving the Slack ID versions of the user / channel, which is a string of integers/letters, but is there a way to return the actual user name / channel vs. just the ID? Thanks again and as I wrap my head around this library, will definitely try to contribute in the future!
Also, not sure this PR has anything to do w/ messages not being received in Slack: Fix issue with Enum.into by dotslashdash · Pull Request #3 · ryanwinchester/slack_elixir · GitHub
Yes, I need to test this out and I’ll get back to you.
Tested and released v1.0.1
You use the IDs for replying and mentions but if you need the usernames (or any other user info) for other reasons, I think you’ll need to use the API with the ID.
It’s not in the README but there is an API client:
https://hexdocs.pm/slack_elixir/Slack.API.html
I need to add more docs for this stuff.
Thanks so much! Send_message is still not posting messages to the channel, but it probably has do to w/ how I configured Slack (maybe my permissions aren’t correct or something) than your lib. Your API client is working great though!
You should add them to the channel and give them the correct permissions
Sorry, Ryan, I’m not sure what you mean by “You should add them to channel.” I’ve added the bot to the correct channel w/ correct permissions and able to receive messages and reply to messages using:
post(“https://slack.com/api/chat.postMessage”, token, message)
Also, was able to use your advice and get user_names/emails through /get user.list, but still unable to use the send_messages function (returns {:ok}, but no response in the channel.
Sure thing:
def start(_type, _args) do
config = [
app_token:
"APP_TOKEN",
bot_token: "BOT_TOKEN",
bot: AppWeb.SlackBot
]
children = [
# Start the Telemetry supervisor
AppWeb.Telemetry,
# Start the Ecto repository
App.Repo,
# Start the PubSub system
{Phoenix.PubSub, name: App.PubSub},
# Start Finch
{Finch, name: App.Finch},
{Slack.Supervisor, config},
# Start the Endpoint (http/https)
AppWeb.Endpoint
# Start a worker by calling: App.Worker.start_link(arg)
# {App.Worker, arg}
]
# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: App.Supervisor]
Supervisor.start_link(children, opts)
end
__
defmodule AppWeb.SlackBot do
@moduledoc false
use Slack.Bot
import Slack.API
require Logger
@impl true
def handle_event(
"message",
%{"text" => "!" <> _command, "channel" => channel, "user" => user} = _params
) do
send_message(channel, "Hello! <@#{user}>")
{:ok, data} =
get(
"https://slack.com/api/users.list",
"APP-TOKEN"
)
user_data =
for member <- data["members"] do
%{
"real_name" => member["real_name"],
"id" => member["id"]
}
end
path = "PATH"
Enum.each(user_data, fn %{"real_name" => _real_name, "id" => id} ->
post_message_to_member(id, path)
end)
end
defp post_message_to_member(id, path) do
token = "BOT TOKEN"
message = %{
"channel" => id,
"text" =>
#"Hello" <> id <> ""
"Hello <@#{id}>! Please take 30 seconds to reflect and share your key thing today at #{path}"
}
post("https://slack.com/api/chat.postMessage", token, message)
end
end
The API calls are working, but not the send_message func. Thanks!
Very strange. Do you get any error message? slack_elixir/lib/slack/message_server.ex at main · ryanwinchester/slack_elixir · GitHub
If you can turn on debug logs (or run locally in dev env) are there any others from [MessageServer] that show the messages are queued and being sent?
Yeah, definitely strange. No, no error message (receiving {:ok}), and receiving this message:
“[debug] [Socket] Sending message event to Elixir.AppWeb.SlackBot,” which leads me to believe it should be working.
Also,
test = send_message(channel, "Hello! <@#{user}>")
Logger.debug("#{inspect(test)}")
That debug returns {:ok}
You get that log when the socket gets an incoming message from slack and then sends that as a message event to the bot which you receive in handle_event("message", ...).
From there you should be using send_message which should be adding outgoing messages to a queue (for self-rate-limiting) of messages to send to Slack. [MessageServer] debug logs should be showing up from that.
Ah, yeah, thanks, not receiving any [MessageServer] debug logs. I think I’m going to fork the repo, add some logging statements and go from there…
@Fraih001 I think you’re trying to send a message on a private channel and channel_server tries to fetch only public channels via “users.conversations” API hence you must be facing this issue. CMIIW
To quick fix, you can fork the repo and add this in channel_server.ex
defp fetch_channels(token) do
"users.conversations"
|> Slack.API.stream(token, "channels", types: "public_channel, private_channel")
|> Enum.map(& &1["id"])
end
Note: I have added types as an additional argument to the stream.
@ryanwinchester I’m raising 2 issues I have found in the repo while using the library.
Fixed in v1.1.0 let me know if there are any more problems with that