chore: Improve location display in sidebar (#1509)

- Log IP Address on widget load
- Save country code to contact
This commit is contained in:
Pranav Raj S
2020-12-13 22:23:56 +05:30
committed by GitHub
parent 060ef4a427
commit edb09d5a9c
10 changed files with 57 additions and 33 deletions

View File

@@ -35,7 +35,6 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController
def create def create
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
@contact = Current.account.contacts.new(contact_params) @contact = Current.account.contacts.new(contact_params)
set_ip
@contact.save! @contact.save!
@contact_inbox = build_contact_inbox @contact_inbox = build_contact_inbox
end end
@@ -43,7 +42,6 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController
def update def update
@contact.assign_attributes(contact_update_params) @contact.assign_attributes(contact_update_params)
set_ip
@contact.save! @contact.save!
rescue ActiveRecord::RecordInvalid => e rescue ActiveRecord::RecordInvalid => e
render json: { render json: {
@@ -99,11 +97,4 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController
def fetch_contact def fetch_contact
@contact = Current.account.contacts.includes(contact_inboxes: [:inbox]).find(params[:id]) @contact = Current.account.contacts.includes(contact_inboxes: [:inbox]).find(params[:id])
end end
def set_ip
return if @contact.account.feature_enabled?('ip_lookup')
@contact[:additional_attributes][:created_at_ip] ||= request.remote_ip
@contact[:additional_attributes][:updated_at_ip] = request.remote_ip
end
end end

View File

@@ -41,13 +41,21 @@ class WidgetsController < ActionController::Base
def build_contact def build_contact
return if @contact.present? return if @contact.present?
contact_inbox = @web_widget.create_contact_inbox contact_inbox = @web_widget.create_contact_inbox(additional_attributes)
@contact = contact_inbox.contact @contact = contact_inbox.contact
payload = { source_id: contact_inbox.source_id, inbox_id: @web_widget.inbox.id } payload = { source_id: contact_inbox.source_id, inbox_id: @web_widget.inbox.id }
@token = ::Widget::TokenService.new(payload: payload).generate_token @token = ::Widget::TokenService.new(payload: payload).generate_token
end end
def additional_attributes
if @web_widget.inbox.account.feature_enabled?('ip_lookup')
{ created_at_ip: request.remote_ip }
else
{}
end
end
def permitted_params def permitted_params
params.permit(:website_token, :cw_conversation) params.permit(:website_token, :cw_conversation)
end end

View File

@@ -5,6 +5,12 @@
</span> </span>
<contact-info :contact="contact" :channel-type="channelType" /> <contact-info :contact="contact" :channel-type="channelType" />
<div v-if="browser.browser_name" class="conversation--details"> <div v-if="browser.browser_name" class="conversation--details">
<contact-details-item
v-if="location"
:title="$t('EDIT_CONTACT.FORM.LOCATION.LABEL')"
:value="location"
icon="ion-map"
/>
<contact-details-item <contact-details-item
v-if="browser.browser_name" v-if="browser.browser_name"
:title="$t('CONTACT_PANEL.BROWSER')" :title="$t('CONTACT_PANEL.BROWSER')"
@@ -51,6 +57,7 @@ import ContactDetailsItem from './ContactDetailsItem.vue';
import ContactInfo from './contact/ContactInfo'; import ContactInfo from './contact/ContactInfo';
import ConversationLabels from './labels/LabelBox.vue'; import ConversationLabels from './labels/LabelBox.vue';
import ContactCustomAttributes from './ContactCustomAttributes'; import ContactCustomAttributes from './ContactCustomAttributes';
import flag from 'country-code-emoji';
export default { export default {
components: { components: {
@@ -99,6 +106,22 @@ export default {
return `${this.browser.browser_name || ''} ${this.browser return `${this.browser.browser_name || ''} ${this.browser
.browser_version || ''}`; .browser_version || ''}`;
}, },
location() {
const {
additional_attributes: {
country = '',
city = '',
country_code: countryCode,
},
} = this.contact;
const cityAndCountry = [city, country].filter(item => !!item).join(', ');
if (!cityAndCountry) {
return '';
}
const countryFlag = countryCode ? flag(countryCode) : '🌎';
return `${countryFlag} ${cityAndCountry}`;
},
platformName() { platformName() {
const { const {
platform_name: platformName, platform_name: platformName,

View File

@@ -13,8 +13,8 @@
<div class="contact--name"> <div class="contact--name">
{{ contact.name }} {{ contact.name }}
</div> </div>
<div v-if="additionalAttibutes.description" class="contact--bio"> <div v-if="additionalAttributes.description" class="contact--bio">
{{ additionalAttibutes.description }} {{ additionalAttributes.description }}
</div> </div>
<social-icons :social-profiles="socialProfiles" /> <social-icons :social-profiles="socialProfiles" />
<div class="contact--metadata"> <div class="contact--metadata">
@@ -33,12 +33,13 @@
:title="$t('CONTACT_PANEL.PHONE_NUMBER')" :title="$t('CONTACT_PANEL.PHONE_NUMBER')"
/> />
<contact-info-row <contact-info-row
:value="additionalAttibutes.location" v-if="additionalAttributes.location"
:value="additionalAttributes.location"
icon="ion-map" icon="ion-map"
:title="$t('CONTACT_PANEL.LOCATION')" :title="$t('CONTACT_PANEL.LOCATION')"
/> />
<contact-info-row <contact-info-row
:value="additionalAttibutes.company_name" :value="additionalAttributes.company_name"
icon="ion-briefcase" icon="ion-briefcase"
:title="$t('CONTACT_PANEL.COMPANY')" :title="$t('CONTACT_PANEL.COMPANY')"
/> />
@@ -89,14 +90,14 @@ export default {
}; };
}, },
computed: { computed: {
additionalAttibutes() { additionalAttributes() {
return this.contact.additional_attributes || {}; return this.contact.additional_attributes || {};
}, },
socialProfiles() { socialProfiles() {
const { const {
social_profiles: socialProfiles, social_profiles: socialProfiles,
screen_name: twitterScreenName, screen_name: twitterScreenName,
} = this.additionalAttibutes; } = this.additionalAttributes;
return { twitter: twitterScreenName, ...(socialProfiles || {}) }; return { twitter: twitterScreenName, ...(socialProfiles || {}) };
}, },

View File

@@ -49,13 +49,6 @@
:label="$t('EDIT_CONTACT.FORM.PHONE_NUMBER.LABEL')" :label="$t('EDIT_CONTACT.FORM.PHONE_NUMBER.LABEL')"
:placeholder="$t('EDIT_CONTACT.FORM.PHONE_NUMBER.PLACEHOLDER')" :placeholder="$t('EDIT_CONTACT.FORM.PHONE_NUMBER.PLACEHOLDER')"
/> />
<woot-input
v-model.trim="location"
class="medium-6 columns"
:label="$t('EDIT_CONTACT.FORM.LOCATION.LABEL')"
:placeholder="$t('EDIT_CONTACT.FORM.LOCATION.PLACEHOLDER')"
/>
</div> </div>
<woot-input <woot-input
v-model.trim="companyName" v-model.trim="companyName"
@@ -121,7 +114,6 @@ export default {
companyName: '', companyName: '',
description: '', description: '',
email: '', email: '',
location: '',
name: '', name: '',
phoneNumber: '', phoneNumber: '',
socialProfileUserNames: { socialProfileUserNames: {
@@ -144,7 +136,6 @@ export default {
email: {}, email: {},
companyName: {}, companyName: {},
phoneNumber: {}, phoneNumber: {},
location: {},
bio: {}, bio: {},
}, },
computed: { computed: {
@@ -171,7 +162,6 @@ export default {
this.name = name || ''; this.name = name || '';
this.email = email || ''; this.email = email || '';
this.phoneNumber = phoneNumber || ''; this.phoneNumber = phoneNumber || '';
this.location = additionalAttributes.location || '';
this.companyName = additionalAttributes.company_name || ''; this.companyName = additionalAttributes.company_name || '';
this.description = additionalAttributes.description || ''; this.description = additionalAttributes.description || '';
const { const {
@@ -193,7 +183,6 @@ export default {
additional_attributes: { additional_attributes: {
...this.contact.additional_attributes, ...this.contact.additional_attributes,
description: this.description, description: this.description,
location: this.location,
company_name: this.companyName, company_name: this.companyName,
social_profiles: this.socialProfileUserNames, social_profiles: this.socialProfileUserNames,
}, },

View File

@@ -24,8 +24,12 @@ class ContactIpLookupJob < ApplicationJob
ip = get_contact_ip(contact) ip = get_contact_ip(contact)
return if ip.blank? return if ip.blank?
contact.additional_attributes['city'] = Geocoder.search(ip).first.city geocoder_result = Geocoder.search(ip).first
contact.additional_attributes['country'] = Geocoder.search(ip).first.country return unless geocoder_result
contact.additional_attributes['city'] = geocoder_result.city
contact.additional_attributes['country'] = geocoder_result.country
contact.additional_attributes['country_code'] = geocoder_result.country_code
contact.save! contact.save!
end end

View File

@@ -62,9 +62,12 @@ class Channel::WebWidget < ApplicationRecord
" "
end end
def create_contact_inbox def create_contact_inbox(additional_attributes = {})
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
contact = inbox.account.contacts.create!(name: ::Haikunator.haikunate(1000)) contact = inbox.account.contacts.create!(
name: ::Haikunator.haikunate(1000),
additional_attributes: additional_attributes
)
contact_inbox = ::ContactInbox.create!( contact_inbox = ::ContactInbox.create!(
contact_id: contact.id, contact_id: contact.id,
inbox_id: inbox.id, inbox_id: inbox.id,

View File

@@ -38,9 +38,8 @@ class Contact < ApplicationRecord
has_many :messages, as: :sender, dependent: :destroy has_many :messages, as: :sender, dependent: :destroy
before_validation :prepare_email_attribute before_validation :prepare_email_attribute
after_create_commit :dispatch_create_event after_create_commit :dispatch_create_event, :ip_lookup
after_update_commit :dispatch_update_event after_update_commit :dispatch_update_event
after_commit :ip_lookup
def get_source_id(inbox_id) def get_source_id(inbox_id)
contact_inboxes.find_by!(inbox_id: inbox_id).source_id contact_inboxes.find_by!(inbox_id: inbox_id).source_id

View File

@@ -21,6 +21,7 @@
"chart.js": "~2.5.0", "chart.js": "~2.5.0",
"copy-text-to-clipboard": "^2.1.1", "copy-text-to-clipboard": "^2.1.1",
"core-js": "3", "core-js": "3",
"country-code-emoji": "^1.0.0",
"date-fns": "^2.16.1", "date-fns": "^2.16.1",
"dotenv": "^8.0.0", "dotenv": "^8.0.0",
"foundation-sites": "~6.5.3", "foundation-sites": "~6.5.3",

View File

@@ -3213,6 +3213,11 @@ cosmiconfig@^6.0.0:
path-type "^4.0.0" path-type "^4.0.0"
yaml "^1.7.2" yaml "^1.7.2"
country-code-emoji@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/country-code-emoji/-/country-code-emoji-1.0.0.tgz#7c77791839c9e9921beec08ef080caa7cfb8b40c"
integrity sha512-fBM5A49oZkOxOVb0bx7q7Hanlfh8e3z/r6/ZnFhbL57JXGIgWPC2HYrjXEyiGML7OFftDV/WfAlJdDkoAbj1Rg==
create-ecdh@^4.0.0: create-ecdh@^4.0.0:
version "4.0.3" version "4.0.3"
resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff"