Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c505eef43 | ||
|
|
4429e95f2b | ||
|
|
61c07472e0 | ||
|
|
09969af10c | ||
|
|
f830821e0a |
@@ -144,7 +144,6 @@ import { FEATURE_FLAGS } from 'dashboard/featureFlags';
|
||||
import {
|
||||
ALLOWED_FILE_TYPES,
|
||||
ALLOWED_FILE_TYPES_FOR_TWILIO_WHATSAPP,
|
||||
ALLOWED_FILE_TYPES_FOR_LINE,
|
||||
} from 'shared/constants/messages';
|
||||
import VideoCallButton from '../VideoCallButton.vue';
|
||||
import AIAssistanceButton from '../AIAssistanceButton.vue';
|
||||
@@ -271,9 +270,6 @@ export default {
|
||||
return this.showFileUpload || this.isNote;
|
||||
},
|
||||
showAudioRecorderButton() {
|
||||
if (this.isALineChannel) {
|
||||
return false;
|
||||
}
|
||||
// Disable audio recorder for safari browser as recording is not supported
|
||||
const isSafari = /^((?!chrome|android|crios|fxios).)*safari/i.test(
|
||||
navigator.userAgent
|
||||
@@ -295,9 +291,6 @@ export default {
|
||||
if (this.isATwilioWhatsAppChannel) {
|
||||
return ALLOWED_FILE_TYPES_FOR_TWILIO_WHATSAPP;
|
||||
}
|
||||
if (this.isALineChannel) {
|
||||
return ALLOWED_FILE_TYPES_FOR_LINE;
|
||||
}
|
||||
return ALLOWED_FILE_TYPES;
|
||||
},
|
||||
enableDragAndDrop() {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
:message="inReplyTo"
|
||||
:message-type="data.message_type"
|
||||
:parent-has-attachments="hasAttachments"
|
||||
@click="navigateToMessage"
|
||||
/>
|
||||
<bubble-text
|
||||
v-if="data.content"
|
||||
@@ -519,6 +520,13 @@ export default {
|
||||
this.showBackgroundHighlight = false;
|
||||
}, HIGHLIGHT_TIMER);
|
||||
},
|
||||
async navigateToMessage() {
|
||||
this.$nextTick(() => {
|
||||
bus.$emit(BUS_EVENTS.SCROLL_TO_MESSAGE, {
|
||||
messageId: this.inReplyToMessageId,
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -377,12 +377,19 @@ export default {
|
||||
removeBusListeners() {
|
||||
bus.$off(BUS_EVENTS.SCROLL_TO_MESSAGE, this.onScrollToMessage);
|
||||
},
|
||||
onScrollToMessage({ messageId = '' } = {}) {
|
||||
async onScrollToMessage({ messageId }) {
|
||||
// TODO: check if the message is already loaded
|
||||
await this.$store.dispatch('setActiveChat', {
|
||||
data: this.currentChat,
|
||||
after: messageId,
|
||||
force: true,
|
||||
});
|
||||
|
||||
this.$nextTick(() => {
|
||||
const messageElement = document.getElementById('message' + messageId);
|
||||
if (messageElement) {
|
||||
this.isProgrammaticScroll = true;
|
||||
messageElement.scrollIntoView({ behavior: 'smooth' });
|
||||
messageElement.scrollIntoView();
|
||||
this.fetchPreviousMessages();
|
||||
} else {
|
||||
this.scrollToBottom();
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
v-if="shouldShowReplyToMessage"
|
||||
:message="inReplyTo"
|
||||
@dismiss="resetReplyToMessage"
|
||||
@navigate-to-message="navigateToMessage"
|
||||
/>
|
||||
<canned-response
|
||||
v-if="showMentions && hasSlashCommand"
|
||||
@@ -392,8 +393,7 @@ export default {
|
||||
this.isAPIInbox ||
|
||||
this.isAnEmailChannel ||
|
||||
this.isASmsInbox ||
|
||||
this.isATelegramChannel ||
|
||||
this.isALineChannel
|
||||
this.isATelegramChannel
|
||||
);
|
||||
},
|
||||
replyButtonLabel() {
|
||||
@@ -1159,6 +1159,12 @@ export default {
|
||||
LocalStorage.deleteFromJsonStore(replyStorageKey, this.conversationId);
|
||||
bus.$emit(BUS_EVENTS.TOGGLE_REPLY_TO_MESSAGE);
|
||||
},
|
||||
navigateToMessage(messageId) {
|
||||
bus.$emit(BUS_EVENTS.SCROLL_TO_MESSAGE, {
|
||||
messageId,
|
||||
behavior: 'instant',
|
||||
});
|
||||
},
|
||||
onNewConversationModalActive(isActive) {
|
||||
// Issue is if the new conversation modal is open and we drag and drop the file
|
||||
// then the file is not getting attached to the new conversation modal
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div
|
||||
class="reply-editor bg-slate-50 dark:bg-slate-800 rounded-md py-1 pl-2 pr-1 text-xs tracking-wide mt-2 flex items-center gap-1.5 -mx-2"
|
||||
class="reply-editor bg-slate-50 dark:bg-slate-800 rounded-md py-1 pl-2 pr-1 text-xs tracking-wide mt-2 flex items-center gap-1.5 -mx-2 cursor-pointer"
|
||||
@click="$emit('navigate-to-message', message.id)"
|
||||
>
|
||||
<fluent-icon class="flex-shrink-0 icon" icon="arrow-reply" size="14" />
|
||||
<div class="flex-grow gap-1 mt-px text-xs truncate">
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
<template>
|
||||
<div
|
||||
class="px-2 py-1.5 rounded-sm min-w-[10rem] mb-2"
|
||||
class="px-2 py-1.5 -mx-2 rounded-sm min-w-[15rem] mb-2 cursor-pointer"
|
||||
:class="{
|
||||
'bg-slate-50 dark:bg-slate-600 dark:text-slate-50':
|
||||
messageType === MESSAGE_TYPE.INCOMING,
|
||||
'bg-woot-600 text-woot-50': messageType === MESSAGE_TYPE.OUTGOING,
|
||||
'-mx-2': !parentHasAttachments,
|
||||
}"
|
||||
@click="$emit('click')"
|
||||
>
|
||||
<message-preview
|
||||
:message="message"
|
||||
|
||||
@@ -163,14 +163,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
const { messageId } = this.$route.query;
|
||||
this.$store
|
||||
.dispatch('setActiveChat', {
|
||||
data: selectedConversation,
|
||||
after: messageId,
|
||||
})
|
||||
.then(() => {
|
||||
bus.$emit(BUS_EVENTS.SCROLL_TO_MESSAGE, { messageId });
|
||||
});
|
||||
bus.$emit(BUS_EVENTS.SCROLL_TO_MESSAGE, { messageId });
|
||||
} else {
|
||||
this.$store.dispatch('clearSelectedState');
|
||||
}
|
||||
|
||||
@@ -160,10 +160,10 @@ const actions = {
|
||||
});
|
||||
},
|
||||
|
||||
async setActiveChat({ commit, dispatch }, { data, after }) {
|
||||
async setActiveChat({ commit, dispatch }, { data, after, force = false }) {
|
||||
commit(types.SET_CURRENT_CHAT_WINDOW, data);
|
||||
commit(types.CLEAR_ALL_MESSAGES_LOADED);
|
||||
if (data.dataFetched === undefined) {
|
||||
if (data.dataFetched === undefined || force) {
|
||||
try {
|
||||
await dispatch('fetchPreviousMessages', {
|
||||
after,
|
||||
|
||||
@@ -55,8 +55,6 @@ export const ALLOWED_FILE_TYPES_FOR_TWILIO_WHATSAPP =
|
||||
'audio/mpeg, audio/opus, audio/ogg, audio/amr,' +
|
||||
'video/mp4,' +
|
||||
'application/pdf,';
|
||||
// https://developers.line.biz/en/reference/messaging-api/#image-message, https://developers.line.biz/en/reference/messaging-api/#video-message
|
||||
export const ALLOWED_FILE_TYPES_FOR_LINE = 'image/png, image/jpeg,video/mp4';
|
||||
|
||||
export const CSAT_RATINGS = [
|
||||
{
|
||||
|
||||
@@ -42,42 +42,25 @@ class Line::IncomingMessageService
|
||||
end
|
||||
|
||||
def attach_files(message)
|
||||
return unless message_type_non_text?(message['type']) || message['type'] == 'sticker'
|
||||
return unless message_type_non_text?(message['type'])
|
||||
|
||||
if message['type'] == 'sticker'
|
||||
attachment_file = Down.download(
|
||||
"https://stickershop.line-scdn.net/stickershop/v1/sticker/#{message[:stickerId]}/iphone/sticker.png"
|
||||
)
|
||||
response = inbox.channel.client.get_message_content(message['id'])
|
||||
|
||||
@message.attachments.new(
|
||||
account_id: @message.account_id,
|
||||
file_type: 'image',
|
||||
file: {
|
||||
io: attachment_file,
|
||||
filename: "sticker-#{message['stickerId']}.png",
|
||||
content_type: attachment_file.content_type
|
||||
}
|
||||
)
|
||||
else
|
||||
response = inbox.channel.client.get_message_content(message['id'])
|
||||
file_name = "media-#{message['id']}.#{response.content_type.split('/')[1]}"
|
||||
temp_file = Tempfile.new(file_name)
|
||||
temp_file.binmode
|
||||
temp_file << response.body
|
||||
temp_file.rewind
|
||||
|
||||
file_name = "media-#{message['id']}.#{response.content_type.split('/')[1]}"
|
||||
temp_file = Tempfile.new(file_name)
|
||||
temp_file.binmode
|
||||
temp_file << response.body
|
||||
temp_file.rewind
|
||||
|
||||
@message.attachments.new(
|
||||
account_id: @message.account_id,
|
||||
file_type: file_content_type(response),
|
||||
file: {
|
||||
io: temp_file,
|
||||
filename: file_name,
|
||||
content_type: response.content_type
|
||||
}
|
||||
)
|
||||
|
||||
end
|
||||
@message.attachments.new(
|
||||
account_id: @message.account_id,
|
||||
file_type: file_content_type(response),
|
||||
file: {
|
||||
io: temp_file,
|
||||
filename: file_name,
|
||||
content_type: response.content_type
|
||||
}
|
||||
)
|
||||
@message.save!
|
||||
end
|
||||
|
||||
|
||||
@@ -6,8 +6,7 @@ class Line::SendOnLineService < Base::SendOnChannelService
|
||||
end
|
||||
|
||||
def perform_reply
|
||||
response = channel.client.push_message(message.conversation.contact_inbox.source_id, build_payload)
|
||||
|
||||
response = channel.client.push_message(message.conversation.contact_inbox.source_id, [{ type: 'text', text: message.content }])
|
||||
return if response.blank?
|
||||
|
||||
parsed_json = JSON.parse(response.body)
|
||||
@@ -21,37 +20,6 @@ class Line::SendOnLineService < Base::SendOnChannelService
|
||||
end
|
||||
end
|
||||
|
||||
def build_payload
|
||||
if message.content && message.attachments.any?
|
||||
[text_message, *attachments]
|
||||
elsif message.content.nil? && message.attachments.any?
|
||||
attachments
|
||||
else
|
||||
text_message
|
||||
end
|
||||
end
|
||||
|
||||
def attachments
|
||||
message.attachments.map do |attachment|
|
||||
# Support only image and video for now, https://developers.line.biz/en/reference/messaging-api/#image-message
|
||||
next unless attachment.file_type == 'image' || attachment.file_type == 'video'
|
||||
|
||||
{
|
||||
type: attachment.file_type,
|
||||
originalContentUrl: attachment.download_url,
|
||||
previewImageUrl: attachment.download_url
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
# https://developers.line.biz/en/reference/messaging-api/#text-message
|
||||
def text_message
|
||||
{
|
||||
type: 'text',
|
||||
text: message.content
|
||||
}
|
||||
end
|
||||
|
||||
# https://developers.line.biz/en/reference/messaging-api/#error-responses
|
||||
def external_error(error)
|
||||
# Message containing information about the error. See https://developers.line.biz/en/reference/messaging-api/#error-messages
|
||||
|
||||
+1
-1
@@ -104,7 +104,7 @@ RUN apk update && apk add --no-cache \
|
||||
&& gem install bundler
|
||||
|
||||
RUN if [ "$RAILS_ENV" != "production" ]; then \
|
||||
apk add --no-cache nodejs-current yarn; \
|
||||
apk add --no-cache nodejs yarn; \
|
||||
fi
|
||||
|
||||
COPY --from=pre-builder /gems/ /gems/
|
||||
|
||||
@@ -92,57 +92,5 @@ describe Line::SendOnLineService do
|
||||
expect(message.status).to eq('delivered')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with message attachments' do
|
||||
it 'sends the message with text and attachments' do
|
||||
attachment = message.attachments.new(account_id: message.account_id, file_type: :image)
|
||||
attachment.file.attach(io: Rails.root.join('spec/assets/avatar.png').open, filename: 'avatar.png', content_type: 'image/png')
|
||||
expected_url_regex = %r{rails/active_storage/disk/[a-zA-Z0-9=_\-+]+/avatar\.png}
|
||||
|
||||
expect(line_client).to receive(:push_message).with(
|
||||
message.conversation.contact_inbox.source_id,
|
||||
[
|
||||
{ type: 'text', text: message.content },
|
||||
{
|
||||
type: 'image',
|
||||
originalContentUrl: match(expected_url_regex),
|
||||
previewImageUrl: match(expected_url_regex)
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
described_class.new(message: message).perform
|
||||
end
|
||||
|
||||
it 'sends the message with attachments only' do
|
||||
attachment = message.attachments.new(account_id: message.account_id, file_type: :image)
|
||||
attachment.file.attach(io: Rails.root.join('spec/assets/avatar.png').open, filename: 'avatar.png', content_type: 'image/png')
|
||||
message.update!(content: nil)
|
||||
expected_url_regex = %r{rails/active_storage/disk/[a-zA-Z0-9=_\-+]+/avatar\.png}
|
||||
|
||||
expect(line_client).to receive(:push_message).with(
|
||||
message.conversation.contact_inbox.source_id,
|
||||
[
|
||||
{
|
||||
type: 'image',
|
||||
originalContentUrl: match(expected_url_regex),
|
||||
previewImageUrl: match(expected_url_regex)
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
described_class.new(message: message).perform
|
||||
end
|
||||
|
||||
it 'sends the message with text only' do
|
||||
message.attachments.destroy_all
|
||||
expect(line_client).to receive(:push_message).with(
|
||||
message.conversation.contact_inbox.source_id,
|
||||
{ type: 'text', text: message.content }
|
||||
)
|
||||
|
||||
described_class.new(message: message).perform
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user