mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-02 03:57:52 +00:00
feat: support reply to for incoming messages on facebook (#8076)
Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
@@ -93,6 +93,9 @@ class Messages::Facebook::MessageBuilder < Messages::Messenger::MessageBuilder
|
||||
message_type: @message_type,
|
||||
content: response.content,
|
||||
source_id: response.identifier,
|
||||
content_attributes: {
|
||||
in_reply_to_external_id: response.in_reply_to_external_id
|
||||
},
|
||||
sender: @outgoing_echo ? nil : @contact_inbox.contact
|
||||
}
|
||||
end
|
||||
|
||||
@@ -35,8 +35,9 @@
|
||||
/>
|
||||
</blockquote>
|
||||
<bubble-reply-to
|
||||
v-if="inReplyToMessageId && inboxSupportsReplyTo"
|
||||
v-if="inReplyToMessageId"
|
||||
:message="inReplyTo"
|
||||
:message-type="data.message_type"
|
||||
/>
|
||||
<bubble-text
|
||||
v-if="data.content"
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<template>
|
||||
<div
|
||||
class="px-2 py-1.5 -mx-2 rounded-md bg-woot-600 text-woot-50 min-w-[15rem] mb-2"
|
||||
class="px-2 py-1.5 -mx-2 rounded-sm min-w-[15rem] mb-2"
|
||||
:class="{
|
||||
'bg-slate-100 dark:bg-slate-600 dark:text-slate-50':
|
||||
messageType === MESSAGE_TYPE.INCOMING,
|
||||
'bg-woot-600 text-woot-50': messageType === MESSAGE_TYPE.OUTGOING,
|
||||
}"
|
||||
>
|
||||
<message-preview
|
||||
:message="message"
|
||||
@@ -12,6 +17,7 @@
|
||||
|
||||
<script>
|
||||
import MessagePreview from 'dashboard/components/widgets/conversation/MessagePreview.vue';
|
||||
import { MESSAGE_TYPE } from 'shared/constants/messages';
|
||||
|
||||
export default {
|
||||
name: 'ReplyTo',
|
||||
@@ -23,6 +29,13 @@ export default {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
messageType: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return { MESSAGE_TYPE };
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -20,7 +20,6 @@ export const INBOX_FEATURES = {
|
||||
export const INBOX_FEATURE_MAP = {
|
||||
[INBOX_FEATURES.REPLY_TO]: [
|
||||
INBOX_TYPES.WEB,
|
||||
INBOX_TYPES.FB,
|
||||
INBOX_TYPES.TWITTER,
|
||||
INBOX_TYPES.WHATSAPP,
|
||||
INBOX_TYPES.LINE,
|
||||
|
||||
@@ -60,6 +60,7 @@ class Message < ApplicationRecord
|
||||
|
||||
before_validation :ensure_content_type
|
||||
before_save :ensure_processed_message_content
|
||||
before_save :ensure_in_reply_to
|
||||
|
||||
validates :account_id, presence: true
|
||||
validates :inbox_id, presence: true
|
||||
@@ -233,6 +234,20 @@ class Message < ApplicationRecord
|
||||
self.processed_message_content = message_content&.truncate(150_000)
|
||||
end
|
||||
|
||||
# fetch the in_reply_to message and set the external id
|
||||
def ensure_in_reply_to
|
||||
in_reply_to = content_attributes[:in_reply_to]
|
||||
in_reply_to_external_id = content_attributes[:in_reply_to_external_id]
|
||||
|
||||
if in_reply_to.present? && in_reply_to_external_id.blank?
|
||||
message = conversation.messages.find_by(id: in_reply_to)
|
||||
content_attributes[:in_reply_to_external_id] = message.try(:source_id)
|
||||
elsif in_reply_to_external_id.present? && in_reply_to.blank?
|
||||
message = conversation.messages.find_by(source_id: in_reply_to_external_id)
|
||||
content_attributes[:in_reply_to] = message.try(:id)
|
||||
end
|
||||
end
|
||||
|
||||
def ensure_content_type
|
||||
self.content_type ||= Message.content_types[:text]
|
||||
end
|
||||
|
||||
@@ -47,6 +47,10 @@ class Integrations::Facebook::MessageParser
|
||||
def sent_from_chatwoot_app?
|
||||
app_id && app_id == GlobalConfigService.load('FB_APP_ID', '').to_i
|
||||
end
|
||||
|
||||
def in_reply_to_external_id
|
||||
@messaging.dig('message', 'reply_to', 'mid')
|
||||
end
|
||||
end
|
||||
|
||||
# Sample Response
|
||||
|
||||
@@ -415,4 +415,49 @@ RSpec.describe Message do
|
||||
expect(instagram_message.reload.attachments.count).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
describe '#ensure_in_reply_to' do
|
||||
let(:conversation) { create(:conversation) }
|
||||
let(:message) { create(:message, conversation: conversation, source_id: 12_345) }
|
||||
|
||||
context 'when in_reply_to is present' do
|
||||
let(:content_attributes) { { in_reply_to: message.id } }
|
||||
let(:new_message) { build(:message, conversation: conversation, content_attributes: content_attributes) }
|
||||
|
||||
it 'sets in_reply_to_external_id based on the source_id of the referenced message' do
|
||||
new_message.send(:ensure_in_reply_to)
|
||||
expect(new_message.content_attributes[:in_reply_to_external_id]).to eq(message.source_id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when in_reply_to is not present' do
|
||||
let(:content_attributes) { { in_reply_to_external_id: message.source_id } }
|
||||
let(:new_message) { build(:message, conversation: conversation, content_attributes: content_attributes) }
|
||||
|
||||
it 'sets in_reply_to based on the source_id of the referenced message' do
|
||||
new_message.send(:ensure_in_reply_to)
|
||||
expect(new_message.content_attributes[:in_reply_to]).to eq(message.id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the referenced message is not found' do
|
||||
let(:content_attributes) { { in_reply_to: message.id + 1 } }
|
||||
let(:new_message) { build(:message, conversation: conversation, content_attributes: content_attributes) }
|
||||
|
||||
it 'does not set in_reply_to_external_id' do
|
||||
new_message.send(:ensure_in_reply_to)
|
||||
expect(new_message.content_attributes[:in_reply_to_external_id]).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the source message is not found' do
|
||||
let(:content_attributes) { { in_reply_to_external_id: 'source-id-that-does-not-exist' } }
|
||||
let(:new_message) { build(:message, conversation: conversation, content_attributes: content_attributes) }
|
||||
|
||||
it 'does not set in_reply_to' do
|
||||
new_message.send(:ensure_in_reply_to)
|
||||
expect(new_message.content_attributes[:in_reply_to]).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user