Feature: Introduce bots (#545)
Co-authored-by: Pranav Raj S <pranavrajs@gmail.com> Co-authored-by: Sojan Jose <sojan@pepalo.com>
This commit is contained in:
@@ -3,7 +3,7 @@ class Messages::Outgoing::NormalBuilder
|
||||
|
||||
def initialize(user, conversation, params)
|
||||
@content = params[:message]
|
||||
@private = ['1', 'true', 1, true].include? params[:private]
|
||||
@private = params[:private] || false
|
||||
@conversation = conversation
|
||||
@user = user
|
||||
@fb_id = params[:fb_id]
|
||||
|
||||
@@ -5,6 +5,7 @@ class Api::V1::WebhooksController < ApplicationController
|
||||
|
||||
before_action :login_from_basic_auth, only: [:chargebee]
|
||||
before_action :check_billing_enabled, only: [:chargebee]
|
||||
|
||||
def chargebee
|
||||
chargebee_consumer.consume
|
||||
head :ok
|
||||
|
||||
@@ -5,7 +5,7 @@ class AsyncDispatcher < BaseDispatcher
|
||||
end
|
||||
|
||||
def listeners
|
||||
listeners = [EmailNotificationListener.instance, ReportingListener.instance, WebhookListener.instance]
|
||||
listeners = [AgentBotListener.instance, EmailNotificationListener.instance, ReportingListener.instance, WebhookListener.instance]
|
||||
listeners << SubscriptionListener.instance if ENV['BILLING_ENABLED']
|
||||
listeners
|
||||
end
|
||||
|
||||
3
app/jobs/agent_bot_job.rb
Normal file
3
app/jobs/agent_bot_job.rb
Normal file
@@ -0,0 +1,3 @@
|
||||
class AgentBotJob < WebhookJob
|
||||
queue_as :bots
|
||||
end
|
||||
13
app/listeners/agent_bot_listener.rb
Normal file
13
app/listeners/agent_bot_listener.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class AgentBotListener < BaseListener
|
||||
def message_created(event)
|
||||
message = extract_message_and_account(event)[0]
|
||||
inbox = message.inbox
|
||||
return unless message.reportable? && inbox.agent_bot_inbox.present?
|
||||
return unless inbox.agent_bot_inbox.active?
|
||||
|
||||
agent_bot = inbox.agent_bot_inbox.agent_bot
|
||||
|
||||
payload = message.webhook_data.merge(event: __method__.to_s)
|
||||
AgentBotJob.perform_later(agent_bot.outgoing_url, payload)
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,8 @@
|
||||
class EmailNotificationListener < BaseListener
|
||||
def conversation_created(event)
|
||||
conversation, _account, _timestamp = extract_conversation_and_account(event)
|
||||
return if conversation.bot?
|
||||
|
||||
conversation.inbox.members.each do |agent|
|
||||
next unless agent.notification_settings.find_by(account_id: conversation.account_id).conversation_creation?
|
||||
|
||||
|
||||
19
app/models/agent_bot.rb
Normal file
19
app/models/agent_bot.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: agent_bots
|
||||
#
|
||||
# id :bigint not null, primary key
|
||||
# auth_token :string
|
||||
# description :string
|
||||
# name :string
|
||||
# outgoing_url :string
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
class AgentBot < ApplicationRecord
|
||||
include Avatarable
|
||||
has_many :agent_bot_inboxes, dependent: :destroy
|
||||
has_many :inboxes, through: :agent_bot_inboxes
|
||||
has_secure_token :auth_token
|
||||
end
|
||||
20
app/models/agent_bot_inbox.rb
Normal file
20
app/models/agent_bot_inbox.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: agent_bot_inboxes
|
||||
#
|
||||
# id :bigint not null, primary key
|
||||
# status :integer default("active")
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# agent_bot_id :integer
|
||||
# inbox_id :integer
|
||||
#
|
||||
|
||||
class AgentBotInbox < ApplicationRecord
|
||||
validates :inbox_id, presence: true
|
||||
validates :agent_bot_id, presence: true
|
||||
|
||||
belongs_to :inbox
|
||||
belongs_to :agent_bot
|
||||
enum status: { active: 0, inactive: 1 }
|
||||
end
|
||||
@@ -34,7 +34,7 @@ class Conversation < ApplicationRecord
|
||||
validates :account_id, presence: true
|
||||
validates :inbox_id, presence: true
|
||||
|
||||
enum status: [:open, :resolved]
|
||||
enum status: { open: 0, resolved: 1, bot: 2 }
|
||||
|
||||
scope :latest, -> { order(created_at: :desc) }
|
||||
scope :unassigned, -> { where(assignee_id: nil) }
|
||||
@@ -50,6 +50,8 @@ class Conversation < ApplicationRecord
|
||||
|
||||
before_create :set_display_id, unless: :display_id?
|
||||
|
||||
before_create :set_bot_conversation
|
||||
|
||||
after_update :notify_status_change, :create_activity, :send_email_notification_to_assignee
|
||||
|
||||
after_create :send_events, :run_round_robin
|
||||
@@ -102,6 +104,10 @@ class Conversation < ApplicationRecord
|
||||
|
||||
private
|
||||
|
||||
def set_bot_conversation
|
||||
self.status = :bot if inbox.agent_bot_inbox&.active?
|
||||
end
|
||||
|
||||
def dispatch_events
|
||||
dispatcher_dispatch(CONVERSATION_RESOLVED)
|
||||
end
|
||||
@@ -110,11 +116,18 @@ class Conversation < ApplicationRecord
|
||||
dispatcher_dispatch(CONVERSATION_CREATED)
|
||||
end
|
||||
|
||||
def notifiable_assignee_change?
|
||||
return false if self_assign?(assignee_id)
|
||||
return false unless saved_change_to_assignee_id?
|
||||
return false if assignee_id.blank?
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def send_email_notification_to_assignee
|
||||
return if self_assign?(assignee_id)
|
||||
return unless saved_change_to_assignee_id?
|
||||
return if assignee_id.blank?
|
||||
return unless notifiable_assignee_change?
|
||||
return if assignee.notification_settings.find_by(account_id: account_id).not_conversation_assignment?
|
||||
return if bot?
|
||||
|
||||
AgentNotifications::ConversationNotificationsMailer.conversation_assigned(self, assignee).deliver_later
|
||||
end
|
||||
@@ -161,6 +174,7 @@ class Conversation < ApplicationRecord
|
||||
def run_round_robin
|
||||
return unless inbox.enable_auto_assignment
|
||||
return if assignee
|
||||
return if bot?
|
||||
|
||||
inbox.next_available_agent.then { |new_assignee| update_assignee(new_assignee) }
|
||||
end
|
||||
|
||||
@@ -33,7 +33,10 @@ class Inbox < ApplicationRecord
|
||||
has_many :members, through: :inbox_members, source: :user
|
||||
has_many :conversations, dependent: :destroy
|
||||
has_many :messages, through: :conversations
|
||||
|
||||
has_one :agent_bot_inbox, dependent: :destroy
|
||||
has_many :webhooks, dependent: :destroy
|
||||
|
||||
after_create :subscribe_webhook, if: :facebook?
|
||||
after_destroy :delete_round_robin_agents
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ class MessageTemplates::HookExecutionService
|
||||
pattr_initialize [:message!]
|
||||
|
||||
def perform
|
||||
return if inbox.agent_bot_inbox&.active?
|
||||
|
||||
::MessageTemplates::Template::EmailCollect.new(conversation: conversation).perform if should_send_email_collect?
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user