feat: Ability to receive location on whatsapp inbox (#5742)

- Ability to  receive location messages on WhatsApp Inbox

ref: https://github.com/chatwoot/chatwoot/issues/3398

Co-authored-by: Sojan Jose <sojan@pepalo.com>
This commit is contained in:
salman652 2022-11-08 10:36:47 +05:00 committed by GitHub
parent 20406dce01
commit 6ff0c93659
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 88 additions and 19 deletions

View file

@ -40,6 +40,12 @@
:url="attachment.data_url" :url="attachment.data_url"
:readable-time="readableTime" :readable-time="readableTime"
/> />
<bubble-location
v-else-if="attachment.file_type === 'location'"
:latitude="attachment.coordinates_lat"
:longitude="attachment.coordinates_long"
:name="attachment.fallback_title"
/>
<bubble-file <bubble-file
v-else v-else
:url="attachment.data_url" :url="attachment.data_url"
@ -119,6 +125,7 @@ import BubbleImage from './bubble/Image';
import BubbleFile from './bubble/File'; import BubbleFile from './bubble/File';
import BubbleVideo from './bubble/Video.vue'; import BubbleVideo from './bubble/Video.vue';
import BubbleActions from './bubble/Actions'; import BubbleActions from './bubble/Actions';
import BubbleLocation from './bubble/Location';
import Spinner from 'shared/components/Spinner'; import Spinner from 'shared/components/Spinner';
import ContextMenu from 'dashboard/modules/conversations/components/MessageContextMenu'; import ContextMenu from 'dashboard/modules/conversations/components/MessageContextMenu';
@ -136,6 +143,7 @@ export default {
BubbleFile, BubbleFile,
BubbleVideo, BubbleVideo,
BubbleMailHead, BubbleMailHead,
BubbleLocation,
ContextMenu, ContextMenu,
Spinner, Spinner,
}, },

View file

@ -7,6 +7,7 @@
<h5 class="text-block-title text-truncate"> <h5 class="text-block-title text-truncate">
{{ name }} {{ name }}
</h5> </h5>
<div class="link-wrap">
<a <a
class="download clear link button small" class="download clear link button small"
rel="noreferrer noopener nofollow" rel="noreferrer noopener nofollow"
@ -17,6 +18,7 @@
</a> </a>
</div> </div>
</div> </div>
</div>
</template> </template>
<script> <script>
@ -51,23 +53,26 @@ export default {
cursor: pointer; cursor: pointer;
.icon-wrap { .icon-wrap {
color: var(--white); color: var(--s-600);
line-height: 1; line-height: 1;
margin: 0 var(--space-smaller); margin: 0 var(--space-smaller);
} }
.text-block-title { .text-block-title {
margin: 0; margin: 0;
color: var(--white); color: var(--s-800);
word-break: break-word; word-break: break-word;
} }
.button { .meta {
color: var(--s-25); display: flex;
flex-direction: column;
align-items: flex-start;
padding-right: var(--space-normal);
} }
.meta { .link-wrap {
padding-right: var(--space-normal); display: flex;
} }
} }
</style> </style>

View file

@ -23,6 +23,7 @@ class Whatsapp::IncomingMessageBaseService
source_id: @processed_params[:messages].first[:id].to_s source_id: @processed_params[:messages].first[:id].to_s
) )
attach_files attach_files
attach_location
@message.save! @message.save!
end end
@ -78,6 +79,7 @@ class Whatsapp::IncomingMessageBaseService
return :image if %w[image sticker].include?(file_type) return :image if %w[image sticker].include?(file_type)
return :audio if %w[audio voice].include?(file_type) return :audio if %w[audio voice].include?(file_type)
return :video if ['video'].include?(file_type) return :video if ['video'].include?(file_type)
return :location if ['location'].include?(file_type)
:file :file
end end
@ -91,7 +93,7 @@ class Whatsapp::IncomingMessageBaseService
end end
def attach_files def attach_files
return if %w[text button interactive].include?(message_type) return if %w[text button interactive location].include?(message_type)
attachment_payload = @processed_params[:messages].first[message_type.to_sym] attachment_payload = @processed_params[:messages].first[message_type.to_sym]
attachment_file = download_attachment_file(attachment_payload) attachment_file = download_attachment_file(attachment_payload)
@ -111,4 +113,19 @@ class Whatsapp::IncomingMessageBaseService
def download_attachment_file(attachment_payload) def download_attachment_file(attachment_payload)
Down.download(inbox.channel.media_url(attachment_payload[:id]), headers: inbox.channel.api_headers) Down.download(inbox.channel.media_url(attachment_payload[:id]), headers: inbox.channel.api_headers)
end end
def attach_location
return unless @processed_params[:messages].first[:type] == 'location'
location = @processed_params[:messages].first['location']
location_name = location['name'] ? "#{location['name']}, #{location['address']}" : ''
@message.attachments.new(
account_id: @message.account_id,
file_type: file_content_type(message_type),
coordinates_lat: location['latitude'],
coordinates_long: location['longitude'],
fallback_title: location_name,
external_url: location['url']
)
end
end end

View file

@ -66,7 +66,21 @@ unless Rails.env.production?
# sample email collect # sample email collect
Seeders::MessageSeeder.create_sample_email_collect_message conversation Seeders::MessageSeeder.create_sample_email_collect_message conversation
Message.create!(content: 'Hello', account: account, inbox: inbox, conversation: conversation, message_type: :incoming) Message.create!(content: 'Hello', account: account, inbox: inbox, conversation: conversation, sender: contact_inbox.contact,
message_type: :incoming)
# sample location message
#
location_message = Message.new(content: 'location', account: account, inbox: inbox, sender: contact_inbox.contact, conversation: conversation,
message_type: :incoming)
location_message.attachments.new(
account_id: account.id,
file_type: 'location',
coordinates_lat: 37.7893768,
coordinates_long: -122.3895553,
fallback_title: 'Bay Bridge, San Francisco, CA, USA'
)
location_message.save!
# sample card # sample card
Seeders::MessageSeeder.create_sample_cards_message conversation Seeders::MessageSeeder.create_sample_cards_message conversation

View file

@ -39,8 +39,8 @@ describe Whatsapp::IncomingMessageService do
end end
end end
context 'when ignores the message' do context 'when unsupported message types' do
it 'with message type is ephemeral' do it 'ignores type ephemeral' do
params = { params = {
'contacts' => [{ 'profile' => { 'name' => 'Sojan Jose' }, 'wa_id' => '2423423243' }], 'contacts' => [{ 'profile' => { 'name' => 'Sojan Jose' }, 'wa_id' => '2423423243' }],
'messages' => [{ 'from' => '2423423243', 'id' => 'SDFADSf23sfasdafasdfa', 'text' => { 'body' => 'Test' }, 'messages' => [{ 'from' => '2423423243', 'id' => 'SDFADSf23sfasdafasdfa', 'text' => { 'body' => 'Test' },
@ -53,7 +53,7 @@ describe Whatsapp::IncomingMessageService do
expect(whatsapp_channel.inbox.messages.count).to eq(0) expect(whatsapp_channel.inbox.messages.count).to eq(0)
end end
it 'with message type is unsupported' do it 'ignores type unsupported' do
params = { params = {
'contacts' => [{ 'profile' => { 'name' => 'Sojan Jose' }, 'wa_id' => '2423423243' }], 'contacts' => [{ 'profile' => { 'name' => 'Sojan Jose' }, 'wa_id' => '2423423243' }],
'messages' => [{ 'messages' => [{
@ -132,5 +132,30 @@ describe Whatsapp::IncomingMessageService do
expect(whatsapp_channel.inbox.messages.first.attachments.present?).to be true expect(whatsapp_channel.inbox.messages.first.attachments.present?).to be true
end end
end end
context 'when valid location message params' do
it 'creates appropriate conversations, message and contacts' do
params = {
'contacts' => [{ 'profile' => { 'name' => 'Sojan Jose' }, 'wa_id' => '2423423243' }],
'messages' => [{ 'from' => '2423423243', 'id' => 'SDFADSf23sfasdafasdfa',
'location' => { 'id' => 'b1c68f38-8734-4ad3-b4a1-ef0c10d683',
'address': 'San Francisco, CA, USA',
'latitude': 37.7893768,
'longitude': -122.3895553,
'name': 'Bay Bridge',
'url': 'http://location_url.test' },
'timestamp' => '1633034394', 'type' => 'location' }]
}.with_indifferent_access
described_class.new(inbox: whatsapp_channel.inbox, params: params).perform
expect(whatsapp_channel.inbox.conversations.count).not_to eq(0)
expect(Contact.all.first.name).to eq('Sojan Jose')
location_attachment = whatsapp_channel.inbox.messages.first.attachments.first
expect(location_attachment.file_type).to eq('location')
expect(location_attachment.fallback_title).to eq('Bay Bridge, San Francisco, CA, USA')
expect(location_attachment.coordinates_lat).to eq(37.7893768)
expect(location_attachment.coordinates_long).to eq(-122.3895553)
expect(location_attachment.external_url).to eq('http://location_url.test')
end
end
end end
end end