slack.cr
Crystal client for building Slack apps and tools using the Slack API.
Installation
-
Add the dependency to your
shard.yml
:dependencies: slack: github: the-business-factory/slack.cr
-
Run
shards install
Usage
Demo App
A demo app is published at https://github.com/the-business-factory/hirobot.app.
Configuration
Slack.configure do |config|
config.bot_scopes = ["incoming-webhook"] # Array(String)
config.client_id = ENV["SLACK_CLIENT_ID"] # String
config.client_secret = ENV["SLACK_CLIENT_SECRET"] # String
config.signing_secret = ENV["SLACK_SIGNING_SECRET"] # String
config.signing_secret_version = "v0" # String
config.webhook_delivery_time_limit = 5.minutes # Time::Span
end
# Most apps will want to have OAuth enabled for installation.
Slack::AuthHandler.configure do |config|
config.oauth_redirect_url = ENV["OAUTH_REDIRECT_URL"]
end
Processing Webhook Events
require "slack"
def process_webhook(request : HTTP::Request)
event_payload = Slack.process_webhook(event)
case event_payload
when .is_a?(Slack::UrlVerification)
json(event_payload.response.to_json)
else
handle_event(event_payload.event)
end
end
# You can easily handle only the events you expect back, with type safety.
def handle_event(event : Slack::Event::Message::MessageChanged)
pp event.message.text
end
# And of course sometimes, you just want to ignore things you don't expect.
def handle_event(unhandled_event)
end
Web API calls
class SlackWebhookEvent < WebhookAction
post "/slack/webhook_events" do
event_payload = Slack.process_webhook(request)
case event_payload
when Slack::UrlVerification
json(event_payload.response)
else
handle_event(event_payload.event)
json({ok: true})
end
end
def handle_event(message : Slack::Events::Message)
return unless message.public_channel?
auth_token = SlackAccessTokenQuery
.new
.slack_team_id(message.team)
.created_at
.desc_order
.first
# channel : Slack::Models::PublicChannel
channel = Slack::Api::ConversationsInfo.new(token, message.channel_id).call
# Deal with Slack's polymorphic API in uniform ways.
case channel
when Slack::Models::PublicChannel
Log.info { "Public Team Channel Name: #{channel.name}" }
end
end
end
Slack UI Tools
# Users can easily define custom UI components to help build out "app specific"
# "UI Kits" fairly easily, focusing on the UX and business logic rather than
# the stupid internals of Slack's API.
class ButtonSection < Slack::UI::CustomComponent
include Slack::UI::BaseComponents
def self.render(action_id : String)
buttons = %w(Submit Cancel).map do |text|
style = text == "Submit" ? ButtonStyles::Primary : ButtonStyles::Danger
ButtonElement.render(
action_id: "#{action_id}_#{text.downcase}",
button_text: text,
style: style
)
end
Slack::UI::Blocks::Actions.new elements: buttons
end
end
class SlackLinkPage < WebhookAction
include Slack::UI::BaseComponents
post "/slack/links" do
command = Slack.process_command(request)
text = command.text.presence || "nothing"
text_section = TextSection.render(
text: "processed #{command.command} with #{text} as text."
)
input_element = InputElement.render(
action_id: "compensation",
placeholder_text: "e.g. $120,000-$190,000",
label_text: "Compensation",
initial_value: ""
)
button_section = ButtonSection.render(
action_id: "button_group_#{Random::Secure.hex}"
)
json({blocks: [text_section, input_element, button_section]})
end
end
Contributing
- Fork it (https://github.com/the-business-factory/slack.cr/fork)
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
Contributors
- Rob Cole - creator and maintainer
- Alex Piechowski - maintainer