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