feat: Add agent_reply_time_window in API channels (#4857)

This commit is contained in:
Pranav Raj S 2022-06-14 18:05:37 +05:30 committed by GitHub
parent f0db8545cb
commit 1bb0371c1d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 116 additions and 36 deletions

View file

@ -80,7 +80,7 @@
@click="toggleMessageSignature"
/>
<woot-button
v-if="showWhatsappTemplatesButton"
v-if="hasWhatsappTemplates"
v-tooltip.top-end="'Whatsapp Templates'"
icon="whatsapp"
color-scheme="secondary"
@ -275,9 +275,6 @@ export default {
showMessageSignatureButton() {
return !this.isPrivate && this.isAnEmailChannel;
},
showWhatsappTemplatesButton() {
return !this.isOnPrivateNote && this.hasWhatsappTemplates;
},
sendWithSignature() {
const { send_with_signature: isEnabled } = this.uiSettings;
return isEnabled;

View file

@ -1,19 +1,11 @@
<template>
<div class="view-box fill-height">
<banner
v-if="!currentChat.can_reply && !isAWhatsappChannel"
v-if="!currentChat.can_reply"
color-scheme="alert"
:banner-message="$t('CONVERSATION.CANNOT_REPLY')"
:href-link="facebookReplyPolicy"
:href-link-text="$t('CONVERSATION.24_HOURS_WINDOW')"
/>
<banner
v-if="!currentChat.can_reply && isAWhatsappChannel"
color-scheme="alert"
:banner-message="$t('CONVERSATION.TWILIO_WHATSAPP_CAN_REPLY')"
:href-link="twilioWhatsAppReplyPolicy"
:href-link-text="$t('CONVERSATION.TWILIO_WHATSAPP_24_HOURS_WINDOW')"
:banner-message="replyWindowBannerMessage"
:href-link="replyWindowLink"
:href-link-text="replyWindowLinkText"
/>
<banner
@ -159,7 +151,6 @@ export default {
hasSelectedTweetId() {
return !!this.selectedTweetId;
},
tweetBannerText() {
return !this.selectedTweetId
? this.$t('CONVERSATION.SELECT_A_TWEET_TO_REPLY')
@ -237,12 +228,6 @@ export default {
}
return '';
},
facebookReplyPolicy() {
return REPLY_POLICY.FACEBOOK;
},
twilioWhatsAppReplyPolicy() {
return REPLY_POLICY.TWILIO_WHATSAPP;
},
isRightOrLeftIcon() {
if (this.isContactPanelOpen) {
return 'arrow-chevron-right';
@ -254,6 +239,41 @@ export default {
const { contact_last_seen_at: contactLastSeenAt } = this.currentChat;
return contactLastSeenAt;
},
replyWindowBannerMessage() {
if (this.isAWhatsappChannel) {
return this.$t('CONVERSATION.TWILIO_WHATSAPP_CAN_REPLY');
}
if (this.isAPIInbox) {
const { additional_attributes: additionalAttributes = {} } = this.inbox;
if (additionalAttributes) {
const {
agent_reply_time_window_message: agentReplyTimeWindowMessage,
} = additionalAttributes;
return agentReplyTimeWindowMessage;
}
return '';
}
return this.$t('CONVERSATION.CANNOT_REPLY');
},
replyWindowLink() {
if (this.isAWhatsappChannel) {
return REPLY_POLICY.FACEBOOK;
}
if (!this.isAPIInbox) {
return REPLY_POLICY.TWILIO_WHATSAPP;
}
return '';
},
replyWindowLinkText() {
if (this.isAWhatsappChannel) {
return this.$t('CONVERSATION.24_HOURS_WINDOW');
}
if (!this.isAPIInbox) {
return this.$t('CONVERSATION.TWILIO_WHATSAPP_24_HOURS_WINDOW');
}
return '';
},
},
watch: {

View file

@ -26,8 +26,22 @@ class Channel::Api < ApplicationRecord
has_secure_token :identifier
has_secure_token :hmac_token
validate :ensure_valid_agent_reply_time_window
def name
'API'
end
def messaging_window_enabled?
additional_attributes.present? && additional_attributes['agent_reply_time_window'].present?
end
private
def ensure_valid_agent_reply_time_window
return if additional_attributes['agent_reply_time_window'].blank?
return if additional_attributes['agent_reply_time_window'].to_i.positive?
errors.add(:agent_reply_time_window, 'agent_reply_time_window must be greater than 0')
end
end

View file

@ -32,7 +32,7 @@ class Channel::FacebookPage < ApplicationRecord
'Facebook'
end
def has_24_hour_messaging_window?
def messaging_window_enabled?
false
end

View file

@ -34,7 +34,7 @@ class Channel::TwilioSms < ApplicationRecord
medium == 'sms' ? 'Twilio SMS' : 'Whatsapp'
end
def has_24_hour_messaging_window?
def messaging_window_enabled?
medium == 'whatsapp'
end
end

View file

@ -57,7 +57,7 @@ class Channel::Whatsapp < ApplicationRecord
{ 'D360-API-KEY' => provider_config['api_key'], 'Content-Type' => 'application/json' }
end
def has_24_hour_messaging_window?
def messaging_window_enabled?
true
end

View file

@ -6,7 +6,7 @@ module Channelable
has_one :inbox, as: :channel, dependent: :destroy_async
end
def has_24_hour_messaging_window?
def messaging_window_enabled?
false
end
end

View file

@ -93,23 +93,24 @@ class Conversation < ApplicationRecord
delegate :auto_resolve_duration, to: :account
def can_reply?
channel = inbox&.channel
return can_reply_on_instagram? if additional_attributes['type'] == 'instagram_direct_message'
return true unless inbox&.channel&.has_24_hour_messaging_window?
return true unless channel&.messaging_window_enabled?
return false if last_incoming_message.nil?
last_message_less_than_24_hrs?
messaging_window = inbox.api? ? channel.additional_attributes['agent_reply_time_window'].to_i : 24
last_message_in_messaging_window?(messaging_window)
end
def last_incoming_message
messages&.incoming&.last
end
def last_message_less_than_24_hrs?
def last_message_in_messaging_window?(time)
return false if last_incoming_message.nil?
Time.current < last_incoming_message.created_at + 24.hours
Time.current < last_incoming_message.created_at + time.hours
end
def can_reply_on_instagram?
@ -120,7 +121,7 @@ class Conversation < ApplicationRecord
if global_config['ENABLE_MESSENGER_CHANNEL_HUMAN_AGENT']
Time.current < last_incoming_message.created_at + 7.days
else
last_message_less_than_24_hrs?
last_message_in_messaging_window?(24)
end
end

View file

@ -7,7 +7,7 @@ RSpec.describe Channel::TwilioSms do
let!(:whatsapp_channel) { create(:channel_twilio_sms, medium: :whatsapp) }
it 'returns true' do
expect(whatsapp_channel.has_24_hour_messaging_window?).to eq true
expect(whatsapp_channel.messaging_window_enabled?).to eq true
expect(whatsapp_channel.name).to eq 'Whatsapp'
expect(whatsapp_channel.medium).to eq 'whatsapp'
end
@ -17,7 +17,7 @@ RSpec.describe Channel::TwilioSms do
let!(:sms_channel) { create(:channel_twilio_sms, medium: :sms) }
it 'returns false' do
expect(sms_channel.has_24_hour_messaging_window?).to eq false
expect(sms_channel.messaging_window_enabled?).to eq false
expect(sms_channel.name).to eq 'Twilio SMS'
expect(sms_channel.medium).to eq 'sms'
end

View file

@ -545,6 +545,54 @@ RSpec.describe Conversation, type: :model do
end
end
end
describe 'on API channels' do
let!(:api_channel) { create(:channel_api, additional_attributes: {}) }
let!(:api_channel_with_limit) { create(:channel_api, additional_attributes: { agent_reply_time_window: '12' }) }
context 'when agent_reply_time_window is not configured' do
it 'return true irrespective of the last message time' do
conversation = create(:conversation, inbox: api_channel.inbox)
create(
:message,
account: conversation.account,
inbox: api_channel.inbox,
conversation: conversation,
created_at: Time.now - 13.hours
)
expect(api_channel.additional_attributes['agent_reply_time_window']).to eq nil
expect(conversation.can_reply?).to eq true
end
end
context 'when agent_reply_time_window is configured' do
it 'return false if it is outside of agent_reply_time_window' do
conversation = create(:conversation, inbox: api_channel_with_limit.inbox)
create(
:message,
account: conversation.account,
inbox: api_channel_with_limit.inbox,
conversation: conversation,
created_at: Time.now - 13.hours
)
expect(api_channel_with_limit.additional_attributes['agent_reply_time_window']).to eq '12'
expect(conversation.can_reply?).to eq false
end
it 'return true if it is inside of agent_reply_time_window' do
conversation = create(:conversation, inbox: api_channel_with_limit.inbox)
create(
:message,
account: conversation.account,
inbox: api_channel_with_limit.inbox,
conversation: conversation
)
expect(conversation.can_reply?).to eq true
end
end
end
end
describe '#delete conversation' do