Feature: Slack integration (#783)
- Integrations architecture - Slack integration
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
class Api::V1::Accounts::Integrations::AppsController < Api::V1::Accounts::BaseController
|
||||
before_action :fetch_apps, only: [:index]
|
||||
before_action :fetch_app, only: [:show]
|
||||
|
||||
def index; end
|
||||
|
||||
def show; end
|
||||
|
||||
private
|
||||
|
||||
def fetch_apps
|
||||
@apps = Integrations::App.all
|
||||
end
|
||||
|
||||
def fetch_app
|
||||
@app = Integrations::App.find(id: params[:id])
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,36 @@
|
||||
class Api::V1::Accounts::Integrations::SlackController < Api::V1::Accounts::BaseController
|
||||
before_action :fetch_hook, only: [:update, :destroy]
|
||||
|
||||
def create
|
||||
builder = Integrations::Slack::HookBuilder.new(
|
||||
account: current_account,
|
||||
code: params[:code],
|
||||
inbox_id: params[:inbox_id]
|
||||
)
|
||||
|
||||
@hook = builder.perform
|
||||
|
||||
render json: @hook
|
||||
end
|
||||
|
||||
def update
|
||||
builder = Integrations::Slack::ChannelBuilder.new(
|
||||
hook: @hook, channel: params[:channel]
|
||||
)
|
||||
builder.perform
|
||||
|
||||
render json: @hook
|
||||
end
|
||||
|
||||
def destroy
|
||||
@hook.destroy
|
||||
|
||||
head :ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def fetch_hook
|
||||
@hook = Integrations::Hook.find(params[:id])
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,7 @@
|
||||
class Api::V1::Integrations::WebhooksController < ApplicationController
|
||||
def create
|
||||
builder = Integrations::Slack::IncomingMessageBuilder.new(params)
|
||||
response = builder.perform
|
||||
render json: response
|
||||
end
|
||||
end
|
||||
@@ -9,7 +9,7 @@ class AsyncDispatcher < BaseDispatcher
|
||||
end
|
||||
|
||||
def listeners
|
||||
listeners = [EventListener.instance, WebhookListener.instance]
|
||||
listeners = [EventListener.instance, WebhookListener.instance, HookListener.instance]
|
||||
listeners
|
||||
end
|
||||
end
|
||||
|
||||
11
app/jobs/hook_job.rb
Normal file
11
app/jobs/hook_job.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class HookJob < ApplicationJob
|
||||
queue_as :integrations
|
||||
|
||||
def perform(hook, message)
|
||||
return unless hook.slack?
|
||||
|
||||
Integrations::Slack::OutgoingMessageBuilder.perform(hook, message)
|
||||
rescue StandardError => e
|
||||
Raven.capture_exception(e)
|
||||
end
|
||||
end
|
||||
10
app/listeners/hook_listener.rb
Normal file
10
app/listeners/hook_listener.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
class HookListener < BaseListener
|
||||
def message_created(event)
|
||||
message = extract_message_and_account(event)[0]
|
||||
return unless message.reportable?
|
||||
|
||||
message.account.hooks.each do |hook|
|
||||
HookJob.perform_later(hook, message)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -47,6 +47,7 @@ class Account < ApplicationRecord
|
||||
has_many :webhooks, dependent: :destroy
|
||||
has_many :labels, dependent: :destroy
|
||||
has_many :notification_settings, dependent: :destroy
|
||||
has_many :hooks, dependent: :destroy, class_name: 'Integrations::Hook'
|
||||
has_flags ACCOUNT_SETTINGS_FLAGS.merge(column: 'settings_flags').merge(DEFAULT_QUERY_SETTING)
|
||||
|
||||
enum locale: LANGUAGES_CONFIG.map { |key, val| [val[:iso_639_1_code], key] }.to_h
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
# id :integer not null, primary key
|
||||
# additional_attributes :jsonb
|
||||
# agent_last_seen_at :datetime
|
||||
# identifier :string
|
||||
# locked :boolean default(FALSE)
|
||||
# status :integer default("open"), not null
|
||||
# user_last_seen_at :datetime
|
||||
|
||||
@@ -42,6 +42,7 @@ class Inbox < ApplicationRecord
|
||||
has_one :agent_bot_inbox, dependent: :destroy
|
||||
has_one :agent_bot, through: :agent_bot_inbox
|
||||
has_many :webhooks, dependent: :destroy
|
||||
has_many :hooks, dependent: :destroy, class_name: 'Integrations::Hook'
|
||||
|
||||
after_destroy :delete_round_robin_agents
|
||||
|
||||
|
||||
5
app/models/integrations.rb
Normal file
5
app/models/integrations.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
module Integrations
|
||||
def self.table_name_prefix
|
||||
'integrations_'
|
||||
end
|
||||
end
|
||||
51
app/models/integrations/app.rb
Normal file
51
app/models/integrations/app.rb
Normal file
@@ -0,0 +1,51 @@
|
||||
class Integrations::App
|
||||
attr_accessor :params
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def id
|
||||
params[:id]
|
||||
end
|
||||
|
||||
def name
|
||||
params[:name]
|
||||
end
|
||||
|
||||
def description
|
||||
params[:description]
|
||||
end
|
||||
|
||||
def logo
|
||||
params[:logo]
|
||||
end
|
||||
|
||||
def fields
|
||||
params[:fields]
|
||||
end
|
||||
|
||||
def button
|
||||
params[:button]
|
||||
end
|
||||
|
||||
def enabled?(account)
|
||||
account.hooks.where(app_id: id).exists?
|
||||
end
|
||||
|
||||
class << self
|
||||
def apps
|
||||
Hashie::Mash.new(APPS_CONFIG)
|
||||
end
|
||||
|
||||
def all
|
||||
apps.values.each_with_object([]) do |app, result|
|
||||
result << new(app)
|
||||
end
|
||||
end
|
||||
|
||||
def find(params)
|
||||
all.detect { |app| app.id == params[:id] }
|
||||
end
|
||||
end
|
||||
end
|
||||
36
app/models/integrations/hook.rb
Normal file
36
app/models/integrations/hook.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: integrations_hooks
|
||||
#
|
||||
# id :bigint not null, primary key
|
||||
# access_token :string
|
||||
# hook_type :integer default("account")
|
||||
# settings :text
|
||||
# status :integer default("disabled")
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# account_id :integer
|
||||
# app_id :string
|
||||
# inbox_id :integer
|
||||
# reference_id :string
|
||||
#
|
||||
class Integrations::Hook < ApplicationRecord
|
||||
validates :account_id, presence: true
|
||||
validates :app_id, presence: true
|
||||
|
||||
enum status: { disabled: 0, enabled: 1 }
|
||||
|
||||
belongs_to :account
|
||||
belongs_to :inbox, optional: true
|
||||
has_secure_token :access_token
|
||||
|
||||
enum hook_type: { account: 0, inbox: 1 }
|
||||
|
||||
def app
|
||||
@app ||= Integrations::App.find(id: app_id)
|
||||
end
|
||||
|
||||
def slack?
|
||||
app_id == 'cw_slack'
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,7 @@
|
||||
json.array! @apps do |app|
|
||||
json.id app.id
|
||||
json.name app.name
|
||||
json.logo app.logo
|
||||
json.enabled app.enabled?(@current_account)
|
||||
json.button app.button
|
||||
end
|
||||
@@ -0,0 +1,7 @@
|
||||
json.id @app.id
|
||||
json.name @app.name
|
||||
json.logo @app.logo
|
||||
json.description @app.description
|
||||
json.fields @app.fields
|
||||
json.enabled @app.enabled?(@current_account)
|
||||
json.button @app.button
|
||||
Reference in New Issue
Block a user