diff --git a/app/controllers/public/api/v1/inboxes/conversations_controller.rb b/app/controllers/public/api/v1/inboxes/conversations_controller.rb
index 4e3b5dca9..242dcde77 100644
--- a/app/controllers/public/api/v1/inboxes/conversations_controller.rb
+++ b/app/controllers/public/api/v1/inboxes/conversations_controller.rb
@@ -3,7 +3,7 @@ class Public::Api::V1::Inboxes::ConversationsController < Public::Api::V1::Inbox
before_action :set_conversation, only: [:toggle_typing, :update_last_seen, :show, :toggle_status]
def index
- @conversations = @contact_inbox.hmac_verified? ? @contact.conversations : @contact_inbox.conversations
+ @conversations = @contact_inbox.hmac_verified? ? @contact_inbox.contact.conversations : @contact_inbox.conversations
end
def show; end
diff --git a/app/javascript/v3/views/auth/signup/Index.vue b/app/javascript/v3/views/auth/signup/Index.vue
index 508c755f5..86baff55c 100644
--- a/app/javascript/v3/views/auth/signup/Index.vue
+++ b/app/javascript/v3/views/auth/signup/Index.vue
@@ -62,7 +62,7 @@ export default {
- {{ $t('REGISTER.HAVE_AN_ACCOUNT') }}
+ {{ $t('REGISTER.HAVE_AN_ACCOUNT') }}
{{ replaceInstallationName($t('LOGIN.TITLE')) }}
diff --git a/app/services/line/incoming_message_service.rb b/app/services/line/incoming_message_service.rb
index 4761292d0..6a1192d02 100644
--- a/app/services/line/incoming_message_service.rb
+++ b/app/services/line/incoming_message_service.rb
@@ -10,11 +10,6 @@ class Line::IncomingMessageService
# probably test events
return if params[:events].blank?
- line_contact_info
- return if line_contact_info['userId'].blank?
-
- set_contact
- set_conversation
parse_events
end
@@ -22,6 +17,14 @@ class Line::IncomingMessageService
def parse_events
params[:events].each do |event|
+ next unless event_type_message?(event)
+
+ get_line_contact_info(event)
+ next if @line_contact_info['userId'].blank?
+
+ set_contact
+ set_conversation
+
next unless message_created? event
attach_files event['message']
@@ -30,8 +33,6 @@ class Line::IncomingMessageService
end
def message_created?(event)
- return unless event_type_message?(event)
-
@message = @conversation.messages.build(
content: message_content(event),
account_id: @inbox.account_id,
@@ -76,7 +77,8 @@ class Line::IncomingMessageService
response = inbox.channel.client.get_message_content(message['id'])
- file_name = "media-#{message['id']}.#{response.content_type.split('/')[1]}"
+ extension = get_file_extension(response)
+ file_name = message['fileName'] || "media-#{message['id']}.#{extension}"
temp_file = Tempfile.new(file_name)
temp_file.binmode
temp_file << response.body
@@ -93,25 +95,38 @@ class Line::IncomingMessageService
)
end
+ def get_file_extension(response)
+ if response.content_type&.include?('/')
+ response.content_type.split('/')[1]
+ else
+ 'bin'
+ end
+ end
+
def event_type_message?(event)
event['type'] == 'message' || event['type'] == 'sticker'
end
def message_type_non_text?(type)
- [Line::Bot::Event::MessageType::Video, Line::Bot::Event::MessageType::Audio, Line::Bot::Event::MessageType::Image].include?(type)
+ [
+ Line::Bot::Event::MessageType::Video,
+ Line::Bot::Event::MessageType::Audio,
+ Line::Bot::Event::MessageType::Image,
+ Line::Bot::Event::MessageType::File
+ ].include?(type)
end
def account
@account ||= inbox.account
end
- def line_contact_info
- @line_contact_info ||= JSON.parse(inbox.channel.client.get_profile(params[:events].first['source']['userId']).body)
+ def get_line_contact_info(event)
+ @line_contact_info = JSON.parse(inbox.channel.client.get_profile(event['source']['userId']).body)
end
def set_contact
contact_inbox = ::ContactInboxWithContactBuilder.new(
- source_id: line_contact_info['userId'],
+ source_id: @line_contact_info['userId'],
inbox: inbox,
contact_attributes: contact_attributes
).perform
@@ -138,15 +153,15 @@ class Line::IncomingMessageService
def contact_attributes
{
- name: line_contact_info['displayName'],
- avatar_url: line_contact_info['pictureUrl'],
+ name: @line_contact_info['displayName'],
+ avatar_url: @line_contact_info['pictureUrl'],
additional_attributes: additional_attributes
}
end
def additional_attributes
{
- social_line_user_id: line_contact_info['userId']
+ social_line_user_id: @line_contact_info['userId']
}
end
diff --git a/spec/controllers/public/api/v1/inbox/conversations_controller_spec.rb b/spec/controllers/public/api/v1/inbox/conversations_controller_spec.rb
index 2b2bdefc3..6684d18cf 100644
--- a/spec/controllers/public/api/v1/inbox/conversations_controller_spec.rb
+++ b/spec/controllers/public/api/v1/inbox/conversations_controller_spec.rb
@@ -16,6 +16,17 @@ RSpec.describe 'Public Inbox Contact Conversations API', type: :request do
expect(data.first['uuid']).to eq contact_inbox.conversations.first.uuid
end
+ it 'return the conversations when hmac_verified is true' do
+ contact_inbox.update(hmac_verified: true)
+ create(:conversation, contact: contact)
+ get "/public/api/v1/inboxes/#{api_channel.identifier}/contacts/#{contact_inbox.source_id}/conversations"
+
+ expect(response).to have_http_status(:success)
+ data = response.parsed_body
+ expect(data.length).to eq 1
+ expect(data.first['uuid']).to eq contact.conversations.first.uuid
+ end
+
it 'does not return any private or activity message' do
conversation = create(:conversation, contact_inbox: contact_inbox)
create(:message, account: conversation.account, inbox: conversation.inbox, conversation: conversation, content: 'message-1')
diff --git a/spec/services/line/incoming_message_service_spec.rb b/spec/services/line/incoming_message_service_spec.rb
index 3bcdf8b04..a7805ce9b 100644
--- a/spec/services/line/incoming_message_service_spec.rb
+++ b/spec/services/line/incoming_message_service_spec.rb
@@ -35,6 +35,62 @@ describe Line::IncomingMessageService do
}.with_indifferent_access
end
+ let(:follow_params) do
+ {
+ 'destination': '2342234234',
+ 'events': [
+ {
+ 'replyToken': '8cf9239d56244f4197887e939187e19e',
+ 'type': 'follow',
+ 'mode': 'active',
+ 'timestamp': 1_462_629_479_859,
+ 'source': {
+ 'type': 'user',
+ 'userId': 'U4af4980629'
+ }
+ }
+ ]
+ }.with_indifferent_access
+ end
+
+ let(:multi_user_params) do
+ {
+ 'destination': '2342234234',
+ 'events': [
+ {
+ 'replyToken': '0f3779fba3b349968c5d07db31eab56f1',
+ 'type': 'message',
+ 'mode': 'active',
+ 'timestamp': 1_462_629_479_859,
+ 'source': {
+ 'type': 'user',
+ 'userId': 'U4af4980629'
+ },
+ 'message': {
+ 'id': '3257081',
+ 'type': 'text',
+ 'text': 'Hello, world 1'
+ }
+ },
+ {
+ 'replyToken': '0f3779fba3b349968c5d07db31eab56f2',
+ 'type': 'message',
+ 'mode': 'active',
+ 'timestamp': 1_462_629_479_859,
+ 'source': {
+ 'type': 'user',
+ 'userId': 'U4af49806292'
+ },
+ 'message': {
+ 'id': '3257082',
+ 'type': 'text',
+ 'text': 'Hello, world 2'
+ }
+ }
+ ]
+ }.with_indifferent_access
+ end
+
let(:image_params) do
{
'destination': '2342234234',
@@ -105,6 +161,40 @@ describe Line::IncomingMessageService do
}.with_indifferent_access
end
+ let(:file_params) do
+ {
+ 'destination': '2342234234',
+ 'events': [
+ {
+ 'replyToken': '0f3779fba3b349968c5d07db31eab56f',
+ 'type': 'message',
+ 'mode': 'active',
+ 'timestamp': 1_462_629_479_859,
+ 'source': {
+ 'type': 'user',
+ 'userId': 'U4af4980629'
+ },
+ 'message': {
+ 'type': 'file',
+ 'id': '354718',
+ 'fileName': 'contacts.csv',
+ 'fileSize': 2978
+ }
+ },
+ {
+ 'replyToken': '8cf9239d56244f4197887e939187e19e',
+ 'type': 'follow',
+ 'mode': 'active',
+ 'timestamp': 1_462_629_479_859,
+ 'source': {
+ 'type': 'user',
+ 'userId': 'U4af4980629'
+ }
+ }
+ ]
+ }.with_indifferent_access
+ end
+
let(:sticker_params) do
{
'destination': '2342234234',
@@ -141,8 +231,8 @@ describe Line::IncomingMessageService do
end
describe '#perform' do
- context 'when valid text message params' do
- it 'creates appropriate conversations, message and contacts' do
+ context 'when non-text message params' do
+ it 'does not create conversations, messages and contacts' do
line_bot = double
line_user_profile = double
allow(Line::Bot::Client).to receive(:new).and_return(line_bot)
@@ -154,12 +244,56 @@ describe Line::IncomingMessageService do
'pictureUrl': 'https://test.com'
}.to_json
)
+ described_class.new(inbox: line_channel.inbox, params: follow_params).perform
+ expect(line_channel.inbox.conversations.size).to eq(0)
+ expect(Contact.all.size).to eq(0)
+ expect(line_channel.inbox.messages.size).to eq(0)
+ end
+ end
+
+ context 'when valid text message params' do
+ let(:line_bot) { double }
+ let(:line_user_profile) { double }
+
+ before do
+ allow(Line::Bot::Client).to receive(:new).and_return(line_bot)
+ allow(line_bot).to receive(:get_profile).with('U4af4980629').and_return(line_user_profile)
+ allow(line_user_profile).to receive(:body).and_return(
+ {
+ 'displayName': 'LINE Test',
+ 'userId': 'U4af4980629',
+ 'pictureUrl': 'https://test.com'
+ }.to_json
+ )
+ end
+
+ it 'creates appropriate conversations, message and contacts' do
described_class.new(inbox: line_channel.inbox, params: params).perform
expect(line_channel.inbox.conversations).not_to eq(0)
expect(Contact.all.first.name).to eq('LINE Test')
expect(Contact.all.first.additional_attributes['social_line_user_id']).to eq('U4af4980629')
expect(line_channel.inbox.messages.first.content).to eq('Hello, world')
end
+
+ it 'creates appropriate conversations, message and contacts for multi user' do
+ line_user_profile2 = double
+ allow(line_bot).to receive(:get_profile).with('U4af49806292').and_return(line_user_profile2)
+ allow(line_user_profile2).to receive(:body).and_return(
+ {
+ 'displayName': 'LINE Test 2',
+ 'userId': 'U4af49806292',
+ 'pictureUrl': 'https://test.com'
+ }.to_json
+ )
+ described_class.new(inbox: line_channel.inbox, params: multi_user_params).perform
+ expect(line_channel.inbox.conversations.size).to eq(2)
+ expect(Contact.all.first.name).to eq('LINE Test')
+ expect(Contact.all.first.additional_attributes['social_line_user_id']).to eq('U4af4980629')
+ expect(Contact.all.last.name).to eq('LINE Test 2')
+ expect(Contact.all.last.additional_attributes['social_line_user_id']).to eq('U4af49806292')
+ expect(line_channel.inbox.messages.first.content).to eq('Hello, world 1')
+ expect(line_channel.inbox.messages.last.content).to eq('Hello, world 2')
+ end
end
context 'when valid sticker message params' do
@@ -241,5 +375,35 @@ describe Line::IncomingMessageService do
expect(line_channel.inbox.messages.first.attachments.first.file.blob.filename.to_s).to eq('media-354718.mp4')
end
end
+
+ context 'when valid file message params' do
+ it 'creates appropriate conversations, message and contacts' do
+ line_bot = double
+ line_user_profile = double
+ allow(Line::Bot::Client).to receive(:new).and_return(line_bot)
+ allow(line_bot).to receive(:get_profile).and_return(line_user_profile)
+ file = fixture_file_upload(Rails.root.join('spec/assets/contacts.csv'), 'text/csv')
+ allow(line_bot).to receive(:get_message_content).and_return(
+ OpenStruct.new({
+ body: Base64.encode64(file.read),
+ content_type: 'text/csv'
+ })
+ )
+ allow(line_user_profile).to receive(:body).and_return(
+ {
+ 'displayName': 'LINE Test',
+ 'userId': 'U4af4980629',
+ 'pictureUrl': 'https://test.com'
+ }.to_json
+ )
+ described_class.new(inbox: line_channel.inbox, params: file_params).perform
+ expect(line_channel.inbox.conversations).not_to eq(0)
+ expect(Contact.all.first.name).to eq('LINE Test')
+ expect(Contact.all.first.additional_attributes['social_line_user_id']).to eq('U4af4980629')
+ expect(line_channel.inbox.messages.first.content).to be_nil
+ expect(line_channel.inbox.messages.first.attachments.first.file_type).to eq('file')
+ expect(line_channel.inbox.messages.first.attachments.first.file.blob.filename.to_s).to eq('contacts.csv')
+ end
+ end
end
end