feat: Instagram story replies will display the original story link (#6846)

This commit is contained in:
Tejaswini Chile
2023-04-26 15:27:07 +05:30
committed by GitHub
parent 5d30dabf97
commit 3c2d6faf68
7 changed files with 112 additions and 3 deletions

View File

@@ -70,17 +70,28 @@ class Messages::Instagram::MessageBuilder < Messages::Messenger::MessageBuilder
@messaging[:message][:text]
end
def story_reply_attributes
message[:reply_to][:story] if message[:reply_to].present? && message[:reply_to][:story].present?
end
def build_message
return if @outgoing_echo && already_sent_from_chatwoot?
return if message_content.blank? && all_unsupported_files?
@message = conversation.messages.create!(message_params)
save_story_id
attachments.each do |attachment|
process_attachment(attachment)
end
end
def save_story_id
return if story_reply_attributes.blank?
@message.save_story_info(story_reply_attributes)
end
def build_conversation
@contact_inbox ||= contact.contact_inboxes.find_by!(source_id: message_source_id)
Conversation.create!(conversation_params.merge(

View File

@@ -22,6 +22,14 @@
:bcc="emailHeadAttributes.bcc"
:is-incoming="isIncoming"
/>
<blockquote v-if="storyReply" class="story-reply-quote">
<span>{{ $t('CONVERSATION.REPLIED_TO_STORY') }}</span>
<bubble-image
v-if="!hasStoryError"
:url="storyUrl"
@error="onStoryLoadError"
/>
</blockquote>
<bubble-text
v-if="data.content"
:message="message"
@@ -79,7 +87,7 @@
:sender="data.sender"
:story-sender="storySender"
:external-error="externalError"
:story-id="storyId"
:story-id="`${storyId}`"
:is-a-tweet="isATweet"
:is-a-whatsapp-channel="isAWhatsAppChannel"
:has-instagram-story="hasInstagramStory"
@@ -192,6 +200,7 @@ export default {
hasImageError: false,
contextMenuPosition: {},
showBackgroundHighlight: false,
hasStoryError: false,
};
},
computed: {
@@ -277,6 +286,12 @@ export default {
storyId() {
return this.contentAttributes.story_id || null;
},
storyUrl() {
return this.contentAttributes.story_url || null;
},
storyReply() {
return this.storyUrl && this.hasInstagramStory;
},
contentType() {
const {
data: { content_type: contentType },
@@ -414,10 +429,12 @@ export default {
watch: {
data() {
this.hasImageError = false;
this.hasStoryError = false;
},
},
mounted() {
this.hasImageError = false;
this.hasStoryError = false;
bus.$on(BUS_EVENTS.ON_MESSAGE_LIST_SCROLL, this.closeContextMenu);
this.setupHighlightTimer();
},
@@ -432,6 +449,9 @@ export default {
const { file_type: fileType } = attachments[0];
return fileType === type && !this.hasImageError;
}
if (this.storyReply) {
return true;
}
return false;
},
handleContextMenuClick() {
@@ -443,6 +463,9 @@ export default {
onImageLoadError() {
this.hasImageError = true;
},
onStoryLoadError() {
this.hasStoryError = true;
},
openContextMenu(e) {
const shouldSkipContextMenu =
e.target?.classList.contains('skip-context-menu') ||
@@ -672,7 +695,6 @@ li.right {
blockquote {
border-left: var(--space-micro) solid var(--s-75);
color: var(--s-800);
padding: var(--space-smaller) var(--space-small);
margin: var(--space-smaller) 0;
padding: var(--space-small) var(--space-small) 0 var(--space-normal);
}
@@ -704,4 +726,11 @@ li.right {
}
}
}
.story-reply-quote {
border-left: var(--space-micro) solid var(--s-75);
color: var(--s-600);
margin: var(--space-small) var(--space-normal) 0;
padding: var(--space-small) var(--space-small) 0 var(--space-small);
}
</style>

View File

@@ -195,7 +195,7 @@ export default {
return '';
}
const { storySender, storyId } = this;
return `https://www.instagram.com/stories/${storySender}/${storyId}`;
return `https://www.instagram.com/stories/direct/${storySender}_${storyId}`;
},
showStatusIndicators() {
if ((this.isOutgoing || this.isTemplate) && !this.isPrivate) {

View File

@@ -37,6 +37,7 @@
"UNKNOWN_FILE_TYPE": "Unknown File",
"SAVE_CONTACT": "Save",
"UPLOADING_ATTACHMENTS": "Uploading attachments...",
"REPLIED_TO_STORY": "Replied to your story",
"SUCCESS_DELETE_MESSAGE": "Message deleted successfully",
"FAIL_DELETE_MESSSAGE": "Couldn't delete message! Try again",
"NO_RESPONSE": "No response",

View File

@@ -198,6 +198,17 @@ class Message < ApplicationRecord
outgoing? && human_response? && not_created_by_automation? && !private?
end
def save_story_info(story_info)
self.content_attributes = content_attributes.merge(
{
story_id: story_info['id'],
story_sender: inbox.channel.instagram_id,
story_url: story_info['url']
}
)
save!
end
private
def ensure_content_type

View File

@@ -13,6 +13,7 @@ describe ::Messages::Instagram::MessageBuilder do
let!(:instagram_inbox) { create(:inbox, channel: instagram_channel, account: account, greeting_enabled: false) }
let!(:dm_params) { build(:instagram_message_create_event).with_indifferent_access }
let!(:story_mention_params) { build(:instagram_story_mention_event).with_indifferent_access }
let!(:instagram_story_reply_event) { build(:instagram_story_reply_event).with_indifferent_access }
let(:fb_object) { double }
let(:contact) { create(:contact, id: 'Sender-id-1', name: 'Jane Dae') }
let(:contact_inbox) { create(:contact_inbox, contact_id: contact.id, inbox_id: instagram_inbox.id, source_id: 'Sender-id-1') }
@@ -44,6 +45,29 @@ describe ::Messages::Instagram::MessageBuilder do
expect(message.content).to eq('This is the first message from the customer')
end
it 'creates message with for reply with story id' do
allow(Koala::Facebook::API).to receive(:new).and_return(fb_object)
allow(fb_object).to receive(:get_object).and_return(
{
name: 'Jane',
id: 'Sender-id-1',
account_id: instagram_inbox.account_id,
profile_pic: 'https://chatwoot-assets.local/sample.png'
}.with_indifferent_access
)
messaging = instagram_story_reply_event[:entry][0]['messaging'][0]
contact_inbox
described_class.new(messaging, instagram_inbox).perform
message = instagram_channel.inbox.messages.first
expect(message.content).to eq('This is the story reply')
expect(message.content_attributes[:story_sender]).to eq(instagram_inbox.channel.instagram_id)
expect(message.content_attributes[:story_id]).to eq('chatwoot-app-user-id-1')
expect(message.content_attributes[:story_url]).to eq('https://chatwoot-assets.local/sample.png')
end
it 'raises exception on deleted story' do
allow(Koala::Facebook::API).to receive(:new).and_return(fb_object)
allow(fb_object).to receive(:get_object).and_raise(Koala::Facebook::ClientError.new(

View File

@@ -26,6 +26,39 @@ FactoryBot.define do
initialize_with { attributes }
end
factory :instagram_story_reply_event, class: Hash do
entry do
[
{
'id': 'instagram-message-id-123',
'time': '2021-09-08T06:34:04+0000',
'messaging': [
{
'sender': {
'id': 'Sender-id-1'
},
'recipient': {
'id': 'chatwoot-app-user-id-1'
},
'timestamp': '2021-09-08T06:34:04+0000',
'message': {
'mid': 'message-id-1',
'text': 'This is the story reply',
'reply_to': {
'story': {
'id': 'chatwoot-app-user-id-1',
'url': 'https://chatwoot-assets.local/sample.png'
}
}
}
}
]
}
]
end
initialize_with { attributes }
end
factory :instagram_test_text_event, class: Hash do
entry do
[