Feature: Slack integration (#783)
- Integrations architecture - Slack integration
This commit is contained in:
33
lib/integrations/slack/channel_builder.rb
Normal file
33
lib/integrations/slack/channel_builder.rb
Normal file
@@ -0,0 +1,33 @@
|
||||
class Integrations::Slack::ChannelBuilder
|
||||
attr_reader :params, :channel
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def perform
|
||||
create_channel
|
||||
update_reference_id
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def hook
|
||||
@hook ||= params[:hook]
|
||||
end
|
||||
|
||||
def slack_client
|
||||
Slack.configure do |config|
|
||||
config.token = hook.access_token
|
||||
end
|
||||
Slack::Web::Client.new
|
||||
end
|
||||
|
||||
def create_channel
|
||||
@channel = slack_client.conversations_create(name: params[:channel])
|
||||
end
|
||||
|
||||
def update_reference_id
|
||||
@hook.reference_id = channel['channel']['id']
|
||||
end
|
||||
end
|
||||
42
lib/integrations/slack/hook_builder.rb
Normal file
42
lib/integrations/slack/hook_builder.rb
Normal file
@@ -0,0 +1,42 @@
|
||||
class Integrations::Slack::HookBuilder
|
||||
attr_reader :params
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def perform
|
||||
token = fetch_access_token
|
||||
|
||||
hook = account.hooks.new(
|
||||
access_token: token,
|
||||
status: 'enabled',
|
||||
inbox_id: params[:inbox_id],
|
||||
hook_type: hook_type,
|
||||
app_id: 'cw_slack'
|
||||
)
|
||||
|
||||
hook.save!
|
||||
hook
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def account
|
||||
params[:account]
|
||||
end
|
||||
|
||||
def hook_type
|
||||
params[:inbox_id] ? 'inbox' : 'account'
|
||||
end
|
||||
|
||||
def fetch_access_token
|
||||
client = Slack::Web::Client.new
|
||||
|
||||
client.oauth_access(
|
||||
client_id: ENV.fetch('SLACK_CLIENT_ID', 'TEST_CLIENT_ID'),
|
||||
client_secret: ENV.fetch('SLACK_CLIENT_SECRET', 'TEST_CLIENT_SECRET'),
|
||||
code: params[:code]
|
||||
)['bot']['bot_access_token']
|
||||
end
|
||||
end
|
||||
78
lib/integrations/slack/incoming_message_builder.rb
Normal file
78
lib/integrations/slack/incoming_message_builder.rb
Normal file
@@ -0,0 +1,78 @@
|
||||
class Integrations::Slack::IncomingMessageBuilder
|
||||
attr_reader :params
|
||||
|
||||
SUPPORTED_EVENT_TYPES = %w[event_callback url_verification].freeze
|
||||
SUPPORTED_EVENTS = %w[message].freeze
|
||||
SUPPORTED_MESSAGE_TYPES = %w[rich_text].freeze
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def perform
|
||||
return unless valid_event?
|
||||
|
||||
if hook_verification?
|
||||
verify_hook
|
||||
elsif create_message?
|
||||
create_message
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def valid_event?
|
||||
supported_event_type? && supported_event?
|
||||
end
|
||||
|
||||
def supported_event_type?
|
||||
SUPPORTED_EVENT_TYPES.include?(params[:type])
|
||||
end
|
||||
|
||||
def supported_event?
|
||||
hook_verification? || SUPPORTED_EVENTS.include?(params[:event][:type])
|
||||
end
|
||||
|
||||
def supported_message?
|
||||
SUPPORTED_MESSAGE_TYPES.include?(message[:type])
|
||||
end
|
||||
|
||||
def hook_verification?
|
||||
params[:type] == 'url_verification'
|
||||
end
|
||||
|
||||
def create_message?
|
||||
supported_message? && integration_hook
|
||||
end
|
||||
|
||||
def message
|
||||
params[:event][:blocks].first
|
||||
end
|
||||
|
||||
def verify_hook
|
||||
{
|
||||
challenge: params[:challenge]
|
||||
}
|
||||
end
|
||||
|
||||
def integration_hook
|
||||
@integration_hook ||= Integrations::Hook.where(reference_id: params[:event][:channel])
|
||||
end
|
||||
|
||||
def conversation
|
||||
@conversation ||= Conversation.where(identifier: params[:event][:thread_ts]).first
|
||||
end
|
||||
|
||||
def create_message
|
||||
return unless conversation
|
||||
|
||||
conversation.messages.create(
|
||||
message_type: 0,
|
||||
account_id: conversation.account_id,
|
||||
inbox_id: conversation.inbox_id,
|
||||
content: message[:elements].first[:elements].first[:text]
|
||||
)
|
||||
|
||||
{ status: 'success' }
|
||||
end
|
||||
end
|
||||
50
lib/integrations/slack/outgoing_message_builder.rb
Normal file
50
lib/integrations/slack/outgoing_message_builder.rb
Normal file
@@ -0,0 +1,50 @@
|
||||
class Integrations::Slack::OutgoingMessageBuilder
|
||||
attr_reader :hook, :message
|
||||
|
||||
def self.perform(hook, message)
|
||||
new(hook, message).perform
|
||||
end
|
||||
|
||||
def initialize(hook, message)
|
||||
@hook = hook
|
||||
@message = message
|
||||
end
|
||||
|
||||
def perform
|
||||
send_message
|
||||
update_reference_id
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def conversation
|
||||
@conversation ||= message.conversation
|
||||
end
|
||||
|
||||
def contact
|
||||
@contact ||= conversation.contact
|
||||
end
|
||||
|
||||
def send_message
|
||||
@slack_message = slack_client.chat_postMessage(
|
||||
channel: hook.reference_id,
|
||||
text: message.content,
|
||||
username: contact.try(:name),
|
||||
thread_ts: conversation.identifier
|
||||
)
|
||||
end
|
||||
|
||||
def update_reference_id
|
||||
return if conversation.identifier
|
||||
|
||||
conversation.identifier = @slack_message['ts']
|
||||
conversation.save!
|
||||
end
|
||||
|
||||
def slack_client
|
||||
Slack.configure do |config|
|
||||
config.token = hook.access_token
|
||||
end
|
||||
Slack::Web::Client.new
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user