chore: Change the conversation bot
status to pending
(#2677)
fixes: #2649
This commit is contained in:
parent
a0886d37bc
commit
a7ca55c080
22 changed files with 87 additions and 54 deletions
|
@ -49,7 +49,8 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro
|
|||
|
||||
def toggle_status
|
||||
if params[:status]
|
||||
@conversation.status = params[:status]
|
||||
status = params[:status] == 'bot' ? 'pending' : params[:status]
|
||||
@conversation.status = status
|
||||
@status = @conversation.save
|
||||
else
|
||||
@status = @conversation.toggle_status
|
||||
|
@ -106,6 +107,9 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro
|
|||
def conversation_params
|
||||
additional_attributes = params[:additional_attributes]&.permit! || {}
|
||||
status = params[:status].present? ? { status: params[:status] } : {}
|
||||
|
||||
# TODO: temporary fallback for the old bot status in conversation, we will remove after couple of releases
|
||||
status = { status: 'pending' } if status[:status] == 'bot'
|
||||
{
|
||||
account_id: Current.account.id,
|
||||
inbox_id: @contact_inbox.inbox_id,
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
{{ this.$t('CONVERSATION.HEADER.REOPEN_ACTION') }}
|
||||
</woot-button>
|
||||
<woot-button
|
||||
v-else-if="isBot"
|
||||
v-else-if="isPending"
|
||||
class-names="resolve"
|
||||
color-scheme="primary"
|
||||
icon="ion-person"
|
||||
|
@ -48,12 +48,12 @@
|
|||
class="dropdown-pane dropdown-pane--open"
|
||||
>
|
||||
<woot-dropdown-menu>
|
||||
<woot-dropdown-item v-if="!isBot">
|
||||
<woot-dropdown-item v-if="!isPending">
|
||||
<woot-button
|
||||
variant="clear"
|
||||
@click="() => toggleStatus(STATUS_TYPE.BOT)"
|
||||
@click="() => toggleStatus(STATUS_TYPE.PENDING)"
|
||||
>
|
||||
{{ this.$t('CONVERSATION.RESOLVE_DROPDOWN.OPEN_BOT') }}
|
||||
{{ this.$t('CONVERSATION.RESOLVE_DROPDOWN.MARK_PENDING') }}
|
||||
</woot-button>
|
||||
</woot-dropdown-item>
|
||||
</woot-dropdown-menu>
|
||||
|
@ -91,20 +91,20 @@ export default {
|
|||
isOpen() {
|
||||
return this.currentChat.status === wootConstants.STATUS_TYPE.OPEN;
|
||||
},
|
||||
isBot() {
|
||||
return this.currentChat.status === wootConstants.STATUS_TYPE.BOT;
|
||||
isPending() {
|
||||
return this.currentChat.status === wootConstants.STATUS_TYPE.PENDING;
|
||||
},
|
||||
isResolved() {
|
||||
return this.currentChat.status === wootConstants.STATUS_TYPE.RESOLVED;
|
||||
},
|
||||
buttonClass() {
|
||||
if (this.isBot) return 'primary';
|
||||
if (this.isPending) return 'primary';
|
||||
if (this.isOpen) return 'success';
|
||||
if (this.isResolved) return 'warning';
|
||||
return '';
|
||||
},
|
||||
showDropDown() {
|
||||
return !this.isBot;
|
||||
return !this.isPending;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -8,7 +8,7 @@ export default {
|
|||
STATUS_TYPE: {
|
||||
OPEN: 'open',
|
||||
RESOLVED: 'resolved',
|
||||
BOT: 'bot',
|
||||
PENDING: 'pending',
|
||||
},
|
||||
};
|
||||
export const DEFAULT_REDIRECT_URL = '/app/';
|
||||
|
|
|
@ -47,8 +47,8 @@
|
|||
"VALUE": "resolved"
|
||||
},
|
||||
{
|
||||
"TEXT": "Bot",
|
||||
"VALUE": "bot"
|
||||
"TEXT": "Pending",
|
||||
"VALUE": "pending"
|
||||
}
|
||||
],
|
||||
"ATTACHMENTS": {
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
"DETAILS": "details"
|
||||
},
|
||||
"RESOLVE_DROPDOWN": {
|
||||
"OPEN_BOT": "Open with bot"
|
||||
"MARK_PENDING": "Mark as pending"
|
||||
},
|
||||
"FOOTER": {
|
||||
"MSG_INPUT": "Shift + enter for new line. Start with '/' to select a Canned Response.",
|
||||
|
|
|
@ -7,10 +7,10 @@ jest.mock('widget/helpers/axios');
|
|||
describe('#actions', () => {
|
||||
describe('#get attributes', () => {
|
||||
it('sends mutation if api is success', async () => {
|
||||
API.get.mockResolvedValue({ data: { id: 1, status: 'bot' } });
|
||||
API.get.mockResolvedValue({ data: { id: 1, status: 'pending' } });
|
||||
await actions.getAttributes({ commit });
|
||||
expect(commit.mock.calls).toEqual([
|
||||
['SET_CONVERSATION_ATTRIBUTES', { id: 1, status: 'bot' }],
|
||||
['SET_CONVERSATION_ATTRIBUTES', { id: 1, status: 'pending' }],
|
||||
['conversation/setMetaUserLastSeenAt', undefined, { root: true }],
|
||||
]);
|
||||
});
|
||||
|
@ -23,10 +23,10 @@ describe('#actions', () => {
|
|||
|
||||
describe('#update attributes', () => {
|
||||
it('sends correct mutations', () => {
|
||||
actions.update({ commit }, { id: 1, status: 'bot' });
|
||||
actions.update({ commit }, { id: 1, status: 'pending' });
|
||||
expect(commit).toBeCalledWith('UPDATE_CONVERSATION_ATTRIBUTES', {
|
||||
id: 1,
|
||||
status: 'bot',
|
||||
status: 'pending',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,11 +4,11 @@ describe('#getters', () => {
|
|||
it('getConversationParams', () => {
|
||||
const state = {
|
||||
id: 1,
|
||||
status: 'bot',
|
||||
status: 'pending',
|
||||
};
|
||||
expect(getters.getConversationParams(state)).toEqual({
|
||||
id: 1,
|
||||
status: 'bot',
|
||||
status: 'pending',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -14,7 +14,7 @@ describe('#mutations', () => {
|
|||
|
||||
describe('#UPDATE_CONVERSATION_ATTRIBUTES', () => {
|
||||
it('update status if it is same conversation', () => {
|
||||
const state = { id: 1, status: 'bot' };
|
||||
const state = { id: 1, status: 'pending' };
|
||||
mutations.UPDATE_CONVERSATION_ATTRIBUTES(state, {
|
||||
id: 1,
|
||||
status: 'open',
|
||||
|
@ -22,12 +22,12 @@ describe('#mutations', () => {
|
|||
expect(state).toEqual({ id: 1, status: 'open' });
|
||||
});
|
||||
it('doesnot update status if it is not the same conversation', () => {
|
||||
const state = { id: 1, status: 'bot' };
|
||||
const state = { id: 1, status: 'pending' };
|
||||
mutations.UPDATE_CONVERSATION_ATTRIBUTES(state, {
|
||||
id: 2,
|
||||
status: 'open',
|
||||
});
|
||||
expect(state).toEqual({ id: 1, status: 'bot' });
|
||||
expect(state).toEqual({ id: 1, status: 'pending' });
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class NotificationListener < BaseListener
|
||||
def conversation_created(event)
|
||||
conversation, account = extract_conversation_and_account(event)
|
||||
return if conversation.bot?
|
||||
return if conversation.pending?
|
||||
|
||||
conversation.inbox.members.each do |agent|
|
||||
NotificationBuilder.new(
|
||||
|
@ -17,7 +17,7 @@ class NotificationListener < BaseListener
|
|||
conversation, account = extract_conversation_and_account(event)
|
||||
assignee = conversation.assignee
|
||||
return unless conversation.notifiable_assignee_change?
|
||||
return if conversation.bot?
|
||||
return if conversation.pending?
|
||||
|
||||
NotificationBuilder.new(
|
||||
notification_type: 'conversation_assignment',
|
||||
|
|
|
@ -45,7 +45,7 @@ class Conversation < ApplicationRecord
|
|||
validates :inbox_id, presence: true
|
||||
before_validation :validate_additional_attributes
|
||||
|
||||
enum status: { open: 0, resolved: 1, bot: 2 }
|
||||
enum status: { open: 0, resolved: 1, pending: 2 }
|
||||
|
||||
scope :latest, -> { order(last_activity_at: :desc) }
|
||||
scope :unassigned, -> { where(assignee_id: nil) }
|
||||
|
@ -64,7 +64,7 @@ class Conversation < ApplicationRecord
|
|||
has_one :csat_survey_response, dependent: :destroy
|
||||
has_many :notifications, as: :primary_actor, dependent: :destroy
|
||||
|
||||
before_create :set_bot_conversation
|
||||
before_create :mark_conversation_pending_if_bot
|
||||
|
||||
# wanted to change this to after_update commit. But it ended up creating a loop
|
||||
# reinvestigate in future and identity the implications
|
||||
|
@ -91,7 +91,7 @@ class Conversation < ApplicationRecord
|
|||
def toggle_status
|
||||
# FIXME: implement state machine with aasm
|
||||
self.status = open? ? :resolved : :open
|
||||
self.status = :open if bot?
|
||||
self.status = :open if pending?
|
||||
save
|
||||
end
|
||||
|
||||
|
@ -144,8 +144,9 @@ class Conversation < ApplicationRecord
|
|||
self.additional_attributes = {} unless additional_attributes.is_a?(Hash)
|
||||
end
|
||||
|
||||
def set_bot_conversation
|
||||
self.status = :bot if inbox.agent_bot_inbox&.active? || inbox.hooks.pluck(:app_id).include?('dialogflow')
|
||||
def mark_conversation_pending_if_bot
|
||||
# TODO: make this an inbox config instead of assuming bot conversations should start as pending
|
||||
self.status = :pending if inbox.agent_bot_inbox&.active? || inbox.hooks.pluck(:app_id).include?('dialogflow')
|
||||
end
|
||||
|
||||
def notify_conversation_creation
|
||||
|
|
|
@ -63,7 +63,7 @@ en:
|
|||
status:
|
||||
resolved: "Conversation was marked resolved by %{user_name}"
|
||||
open: "Conversation was reopened by %{user_name}"
|
||||
bot: "Conversation was transferred to bot by %{user_name}"
|
||||
pending: "Conversation was marked as pending by %{user_name}"
|
||||
auto_resolved: "Conversation was marked resolved by system due to %{duration} days of inactivity"
|
||||
assignee:
|
||||
self_assigned: "%{user_name} self-assigned this conversation"
|
||||
|
|
|
@ -5,7 +5,7 @@ class Integrations::Dialogflow::ProcessorService
|
|||
message = event_data[:message]
|
||||
return if message.private?
|
||||
return unless processable_message?(message)
|
||||
return unless message.conversation.bot?
|
||||
return unless message.conversation.pending?
|
||||
|
||||
response = get_dialogflow_response(message.conversation.contact_inbox.source_id, message_content(message))
|
||||
process_response(message, response)
|
||||
|
|
|
@ -32,7 +32,7 @@ RSpec.describe 'API Base', type: :request do
|
|||
describe 'request with api_access_token for bot' do
|
||||
let!(:agent_bot) { create(:agent_bot) }
|
||||
let!(:inbox) { create(:inbox, account: account) }
|
||||
let!(:conversation) { create(:conversation, account: account, inbox: inbox, assignee: user, status: 'bot') }
|
||||
let!(:conversation) { create(:conversation, account: account, inbox: inbox, assignee: user, status: 'pending') }
|
||||
|
||||
context 'when it is an unauthorized url' do
|
||||
it 'returns unauthorized' do
|
||||
|
|
|
@ -200,6 +200,20 @@ RSpec.describe 'Conversations API', type: :request do
|
|||
end
|
||||
|
||||
it 'creates a conversation in specificed status' do
|
||||
allow(Rails.configuration.dispatcher).to receive(:dispatch)
|
||||
post "/api/v1/accounts/#{account.id}/conversations",
|
||||
headers: agent.create_new_auth_token,
|
||||
params: { source_id: contact_inbox.source_id, status: 'pending' },
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
response_data = JSON.parse(response.body, symbolize_names: true)
|
||||
expect(response_data[:status]).to eq('pending')
|
||||
end
|
||||
|
||||
# TODO: remove this spec when we remove the condition check in controller
|
||||
# Added for backwards compatibility for bot status
|
||||
it 'creates a conversation as pending if status is specified as bot' do
|
||||
allow(Rails.configuration.dispatcher).to receive(:dispatch)
|
||||
post "/api/v1/accounts/#{account.id}/conversations",
|
||||
headers: agent.create_new_auth_token,
|
||||
|
@ -208,7 +222,7 @@ RSpec.describe 'Conversations API', type: :request do
|
|||
|
||||
expect(response).to have_http_status(:success)
|
||||
response_data = JSON.parse(response.body, symbolize_names: true)
|
||||
expect(response_data[:status]).to eq('bot')
|
||||
expect(response_data[:status]).to eq('pending')
|
||||
end
|
||||
|
||||
it 'creates a new conversation with message when message is passed' do
|
||||
|
@ -269,8 +283,8 @@ RSpec.describe 'Conversations API', type: :request do
|
|||
expect(conversation.reload.status).to eq('resolved')
|
||||
end
|
||||
|
||||
it 'toggles the conversation status to open from bot' do
|
||||
conversation.update!(status: 'bot')
|
||||
it 'toggles the conversation status to open from pending' do
|
||||
conversation.update!(status: 'pending')
|
||||
|
||||
post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/toggle_status",
|
||||
headers: agent.create_new_auth_token,
|
||||
|
@ -283,13 +297,27 @@ RSpec.describe 'Conversations API', type: :request do
|
|||
it 'toggles the conversation status to specific status when parameter is passed' do
|
||||
expect(conversation.status).to eq('open')
|
||||
|
||||
post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/toggle_status",
|
||||
headers: agent.create_new_auth_token,
|
||||
params: { status: 'pending' },
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(conversation.reload.status).to eq('pending')
|
||||
end
|
||||
|
||||
# TODO: remove this spec when we remove the condition check in controller
|
||||
# Added for backwards compatibility for bot status
|
||||
it 'toggles the conversation status to pending status when parameter bot is passed' do
|
||||
expect(conversation.status).to eq('open')
|
||||
|
||||
post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/toggle_status",
|
||||
headers: agent.create_new_auth_token,
|
||||
params: { status: 'bot' },
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(conversation.reload.status).to eq('bot')
|
||||
expect(conversation.reload.status).to eq('pending')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ require 'rails_helper'
|
|||
describe Integrations::Dialogflow::ProcessorService do
|
||||
let(:account) { create(:account) }
|
||||
let(:hook) { create(:integrations_hook, :dialogflow, account: account) }
|
||||
let(:conversation) { create(:conversation, account: account, status: :bot) }
|
||||
let(:conversation) { create(:conversation, account: account, status: :pending) }
|
||||
let(:message) { create(:message, account: account, conversation: conversation) }
|
||||
let(:event_name) { 'message.created' }
|
||||
let(:event_data) { { message: message } }
|
||||
|
|
|
@ -40,7 +40,7 @@ shared_examples_for 'round_robin_handler' do
|
|||
account: account,
|
||||
contact: create(:contact, account: account),
|
||||
inbox: inbox,
|
||||
status: 'bot',
|
||||
status: 'pending',
|
||||
assignee: nil
|
||||
)
|
||||
|
||||
|
|
|
@ -345,8 +345,8 @@ RSpec.describe Conversation, type: :model do
|
|||
let!(:bot_inbox) { create(:agent_bot_inbox) }
|
||||
let(:conversation) { create(:conversation, inbox: bot_inbox.inbox) }
|
||||
|
||||
it 'returns conversation status as bot' do
|
||||
expect(conversation.status).to eq('bot')
|
||||
it 'returns conversation status as pending' do
|
||||
expect(conversation.status).to eq('pending')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -354,8 +354,8 @@ RSpec.describe Conversation, type: :model do
|
|||
let(:hook) { create(:integrations_hook, :dialogflow) }
|
||||
let(:conversation) { create(:conversation, inbox: hook.inbox) }
|
||||
|
||||
it 'returns conversation status as bot' do
|
||||
expect(conversation.status).to eq('bot')
|
||||
it 'returns conversation status as pending' do
|
||||
expect(conversation.status).to eq('pending')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ properties:
|
|||
description: ID of the inbox
|
||||
status:
|
||||
type: string
|
||||
enum: ['open', 'resolved', 'bot']
|
||||
enum: ['open', 'resolved', 'pending']
|
||||
description: The status of the conversation
|
||||
timestamp:
|
||||
type: string
|
||||
|
|
|
@ -14,7 +14,7 @@ get:
|
|||
- name: status
|
||||
in: query
|
||||
type: string
|
||||
enum: ['open', 'resolved', 'bot']
|
||||
enum: ['open', 'resolved', 'pending']
|
||||
required: true
|
||||
- name: page
|
||||
in: query
|
||||
|
|
|
@ -15,7 +15,7 @@ get:
|
|||
- name: status
|
||||
in: query
|
||||
type: string
|
||||
enum: ['open', 'resolved', 'bot']
|
||||
enum: ['open', 'resolved', 'pending']
|
||||
- name: page
|
||||
in: query
|
||||
type: integer
|
||||
|
@ -71,8 +71,8 @@ post:
|
|||
description: Lets you specify attributes like browser information
|
||||
status:
|
||||
type: string
|
||||
enum: ['open', 'resolved', 'bot']
|
||||
description: Specify the conversation whether it's bot, open, closed
|
||||
enum: ['open', 'resolved', 'pending']
|
||||
description: Specify the conversation whether it's pending, open, closed
|
||||
|
||||
responses:
|
||||
200:
|
||||
|
|
|
@ -15,7 +15,7 @@ parameters:
|
|||
properties:
|
||||
status:
|
||||
type: string
|
||||
enum: ["open", "resolved", "bot"]
|
||||
enum: ["open", "resolved", "pending"]
|
||||
required: true
|
||||
description: The status of the conversation
|
||||
responses:
|
||||
|
|
|
@ -1417,7 +1417,7 @@
|
|||
"enum": [
|
||||
"open",
|
||||
"resolved",
|
||||
"bot"
|
||||
"pending"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -1508,9 +1508,9 @@
|
|||
"enum": [
|
||||
"open",
|
||||
"resolved",
|
||||
"bot"
|
||||
"pending"
|
||||
],
|
||||
"description": "Specify the conversation whether it's bot, open, closed"
|
||||
"description": "Specify the conversation whether it's pending, open, closed"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1574,7 +1574,7 @@
|
|||
"enum": [
|
||||
"open",
|
||||
"resolved",
|
||||
"bot"
|
||||
"pending"
|
||||
],
|
||||
"required": true
|
||||
},
|
||||
|
@ -1688,7 +1688,7 @@
|
|||
"enum": [
|
||||
"open",
|
||||
"resolved",
|
||||
"bot"
|
||||
"pending"
|
||||
],
|
||||
"required": true,
|
||||
"description": "The status of the conversation"
|
||||
|
@ -2850,7 +2850,7 @@
|
|||
"enum": [
|
||||
"open",
|
||||
"resolved",
|
||||
"bot"
|
||||
"pending"
|
||||
],
|
||||
"description": "The status of the conversation"
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue