Merge branch 'develop' into feat/docker-multiarch
|
@ -15,7 +15,7 @@ class Api::V1::Accounts::CallbacksController < Api::V1::Accounts::BaseController
|
||||||
set_instagram_id(page_access_token, facebook_channel)
|
set_instagram_id(page_access_token, facebook_channel)
|
||||||
set_avatar(@facebook_inbox, page_id)
|
set_avatar(@facebook_inbox, page_id)
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
Rails.logger.info e
|
Sentry.capture_exception(e)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -55,8 +55,13 @@ class Api::V1::Accounts::CallbacksController < Api::V1::Accounts::BaseController
|
||||||
|
|
||||||
def update_fb_page(fb_page_id, access_token)
|
def update_fb_page(fb_page_id, access_token)
|
||||||
fb_page = get_fb_page(fb_page_id)
|
fb_page = get_fb_page(fb_page_id)
|
||||||
fb_page&.update!(user_access_token: @user_access_token, page_access_token: access_token)
|
ActiveRecord::Base.transaction do
|
||||||
fb_page&.reauthorized!
|
fb_page&.update!(user_access_token: @user_access_token, page_access_token: access_token)
|
||||||
|
set_instagram_id(access_token, fb_page)
|
||||||
|
fb_page&.reauthorized!
|
||||||
|
rescue StandardError => e
|
||||||
|
Sentry.capture_exception(e)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_fb_page(fb_page_id)
|
def get_fb_page(fb_page_id)
|
||||||
|
|
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 12 KiB |
|
@ -19,56 +19,56 @@
|
||||||
id="badge"
|
id="badge"
|
||||||
class="source-badge"
|
class="source-badge"
|
||||||
:style="badgeStyle"
|
:style="badgeStyle"
|
||||||
src="~dashboard/assets/images/instagram_direct.png"
|
src="/integrations/channels/badges/instagram-dm.png"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
v-if="badge === 'Channel::FacebookPage'"
|
v-else-if="badge === 'facebook'"
|
||||||
id="badge"
|
id="badge"
|
||||||
class="source-badge"
|
class="source-badge"
|
||||||
:style="badgeStyle"
|
:style="badgeStyle"
|
||||||
src="~dashboard/assets/images/messenger_direct.png"
|
src="/integrations/channels/badges/messenger.png"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
v-if="badge === 'twitter-tweet'"
|
v-else-if="badge === 'twitter-tweet'"
|
||||||
id="badge"
|
id="badge"
|
||||||
class="source-badge"
|
class="source-badge"
|
||||||
:style="badgeStyle"
|
:style="badgeStyle"
|
||||||
src="~dashboard/assets/images/twitter-badge.png"
|
src="/integrations/channels/badges/twitter-tweet.png"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
v-if="badge === 'twitter-chat'"
|
v-else-if="badge === 'twitter-dm'"
|
||||||
id="badge"
|
id="badge"
|
||||||
class="source-badge"
|
class="source-badge"
|
||||||
:style="badgeStyle"
|
:style="badgeStyle"
|
||||||
src="~dashboard/assets/images/twitter-chat-badge.png"
|
src="/integrations/channels/badges/twitter-dm.png"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
v-if="badge === 'whatsapp'"
|
v-else-if="badge === 'whatsapp'"
|
||||||
id="badge"
|
id="badge"
|
||||||
class="source-badge"
|
class="source-badge"
|
||||||
:style="badgeStyle"
|
:style="badgeStyle"
|
||||||
src="~dashboard/assets/images/channels/whatsapp.png"
|
src="/integrations/channels/badges/whatsapp.png"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
v-if="badge === 'sms'"
|
v-else-if="badge === 'sms'"
|
||||||
id="badge"
|
id="badge"
|
||||||
class="source-badge"
|
class="source-badge"
|
||||||
:style="badgeStyle"
|
:style="badgeStyle"
|
||||||
src="~dashboard/assets/images/channels/sms.png"
|
src="/integrations/channels/badges/sms.png"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
v-if="badge === 'Channel::Line'"
|
v-else-if="badge === 'Channel::Line'"
|
||||||
id="badge"
|
id="badge"
|
||||||
class="source-badge"
|
class="source-badge"
|
||||||
:style="badgeStyle"
|
:style="badgeStyle"
|
||||||
src="~dashboard/assets/images/channels/line.png"
|
src="/integrations/channels/badges/line.png"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
v-if="badge === 'Channel::Telegram'"
|
v-else-if="badge === 'Channel::Telegram'"
|
||||||
id="badge"
|
id="badge"
|
||||||
class="source-badge"
|
class="source-badge"
|
||||||
:style="badgeStyle"
|
:style="badgeStyle"
|
||||||
src="~dashboard/assets/images/channels/telegram.png"
|
src="/integrations/channels/badges/telegram.png"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
v-if="showStatusIndicator"
|
v-if="showStatusIndicator"
|
||||||
|
@ -130,8 +130,10 @@ export default {
|
||||||
return Number(this.size.replace(/\D+/g, ''));
|
return Number(this.size.replace(/\D+/g, ''));
|
||||||
},
|
},
|
||||||
badgeStyle() {
|
badgeStyle() {
|
||||||
const badgeSize = `${this.avatarSize / 3}px`;
|
const size = Math.floor(this.avatarSize / 3);
|
||||||
return { width: badgeSize, height: badgeSize };
|
const badgeSize = `${size + 2}px`;
|
||||||
|
const borderRadius = `${size / 2}px`;
|
||||||
|
return { width: badgeSize, height: badgeSize, borderRadius };
|
||||||
},
|
},
|
||||||
statusStyle() {
|
statusStyle() {
|
||||||
const statusSize = `${this.avatarSize / 4}px`;
|
const statusSize = `${this.avatarSize / 4}px`;
|
||||||
|
@ -181,8 +183,12 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.source-badge {
|
.source-badge {
|
||||||
|
background: white;
|
||||||
|
border-radius: var(--border-radius-small);
|
||||||
bottom: -$space-micro;
|
bottom: -$space-micro;
|
||||||
|
box-shadow: var(--shadow-small);
|
||||||
height: $space-slab;
|
height: $space-slab;
|
||||||
|
padding: var(--space-micro);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: $zero;
|
right: $zero;
|
||||||
width: $space-slab;
|
width: $space-slab;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<thumbnail
|
<thumbnail
|
||||||
v-if="!hideThumbnail"
|
v-if="!hideThumbnail"
|
||||||
:src="currentContact.thumbnail"
|
:src="currentContact.thumbnail"
|
||||||
:badge="chatBadge"
|
:badge="inboxBadge"
|
||||||
class="columns"
|
class="columns"
|
||||||
:username="currentContact.name"
|
:username="currentContact.name"
|
||||||
:status="currentContact.availability_status"
|
:status="currentContact.availability_status"
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
<div class="conversation--metadata">
|
<div class="conversation--metadata">
|
||||||
<inbox-name v-if="showInboxName" :inbox="inbox" />
|
<inbox-name v-if="showInboxName" :inbox="inbox" />
|
||||||
<span
|
<span
|
||||||
v-if="showAssignee && assignee"
|
v-if="showAssignee && assignee.name"
|
||||||
class="label assignee-label text-truncate"
|
class="label assignee-label text-truncate"
|
||||||
>
|
>
|
||||||
<i class="ion-person" />
|
<i class="ion-person" />
|
||||||
|
@ -119,10 +119,6 @@ export default {
|
||||||
accountId: 'getCurrentAccountId',
|
accountId: 'getCurrentAccountId',
|
||||||
}),
|
}),
|
||||||
|
|
||||||
chatExtraAttributes() {
|
|
||||||
return this.chat.additional_attributes;
|
|
||||||
},
|
|
||||||
|
|
||||||
chatMetadata() {
|
chatMetadata() {
|
||||||
return this.chat.meta || {};
|
return this.chat.meta || {};
|
||||||
},
|
},
|
||||||
|
@ -131,14 +127,6 @@ export default {
|
||||||
return this.chatMetadata.assignee || {};
|
return this.chatMetadata.assignee || {};
|
||||||
},
|
},
|
||||||
|
|
||||||
chatBadge() {
|
|
||||||
if(this.chatExtraAttributes['type']){
|
|
||||||
return this.chatExtraAttributes['type']
|
|
||||||
} else {
|
|
||||||
return this.chatMetadata.channel
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
currentContact() {
|
currentContact() {
|
||||||
return this.$store.getters['contacts/getContact'](
|
return this.$store.getters['contacts/getContact'](
|
||||||
this.chatMetadata.sender.id
|
this.chatMetadata.sender.id
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<Thumbnail
|
<Thumbnail
|
||||||
:src="currentContact.thumbnail"
|
:src="currentContact.thumbnail"
|
||||||
size="40px"
|
size="40px"
|
||||||
:badge="chatBadge"
|
:badge="inboxBadge"
|
||||||
:username="currentContact.name"
|
:username="currentContact.name"
|
||||||
:status="currentContact.availability_status"
|
:status="currentContact.availability_status"
|
||||||
/>
|
/>
|
||||||
|
@ -74,22 +74,10 @@ export default {
|
||||||
currentChat: 'getSelectedChat',
|
currentChat: 'getSelectedChat',
|
||||||
}),
|
}),
|
||||||
|
|
||||||
chatExtraAttributes() {
|
|
||||||
return this.chat.additional_attributes;
|
|
||||||
},
|
|
||||||
|
|
||||||
chatMetadata() {
|
chatMetadata() {
|
||||||
return this.chat.meta;
|
return this.chat.meta;
|
||||||
},
|
},
|
||||||
|
|
||||||
chatBadge() {
|
|
||||||
if(this.chatExtraAttributes['type']){
|
|
||||||
return this.chatExtraAttributes['type']
|
|
||||||
} else {
|
|
||||||
return this.chatMetadata.channel
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
currentContact() {
|
currentContact() {
|
||||||
return this.$store.getters['contacts/getContact'](
|
return this.$store.getters['contacts/getContact'](
|
||||||
this.chat.meta.sender.id
|
this.chat.meta.sender.id
|
||||||
|
|
|
@ -47,23 +47,29 @@ export default {
|
||||||
const { medium: medium = '' } = this.inbox;
|
const { medium: medium = '' } = this.inbox;
|
||||||
return this.isATwilioChannel && medium === 'whatsapp';
|
return this.isATwilioChannel && medium === 'whatsapp';
|
||||||
},
|
},
|
||||||
|
chatAdditionalAttributes() {
|
||||||
|
const { additional_attributes: additionalAttributes } = this.chat || {};
|
||||||
|
return additionalAttributes || {};
|
||||||
|
},
|
||||||
isTwitterInboxTweet() {
|
isTwitterInboxTweet() {
|
||||||
return (
|
return this.chatAdditionalAttributes.type === 'tweet';
|
||||||
this.chat &&
|
|
||||||
this.chat.additional_attributes &&
|
|
||||||
this.chat.additional_attributes.type === 'tweet'
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
twilioBadge() {
|
twilioBadge() {
|
||||||
return `${this.isATwilioSMSChannel ? 'sms' : 'whatsapp'}`;
|
return `${this.isATwilioSMSChannel ? 'sms' : 'whatsapp'}`;
|
||||||
},
|
},
|
||||||
twitterBadge() {
|
twitterBadge() {
|
||||||
return `${this.isTwitterInboxTweet ? 'twitter-tweet' : 'twitter-chat'}`;
|
return `${this.isTwitterInboxTweet ? 'twitter-tweet' : 'twitter-dm'}`;
|
||||||
|
},
|
||||||
|
facebookBadge() {
|
||||||
|
return this.chatAdditionalAttributes.type || 'facebook';
|
||||||
},
|
},
|
||||||
inboxBadge() {
|
inboxBadge() {
|
||||||
if (this.isATwitterInbox) {
|
if (this.isATwitterInbox) {
|
||||||
return this.twitterBadge;
|
return this.twitterBadge;
|
||||||
}
|
}
|
||||||
|
if (this.isAFacebookInbox) {
|
||||||
|
return this.facebookBadge;
|
||||||
|
}
|
||||||
if (this.isATwilioChannel) {
|
if (this.isATwilioChannel) {
|
||||||
return this.twilioBadge;
|
return this.twilioBadge;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,9 @@ class Facebook::SendOnFacebookService < Base::SendOnChannelService
|
||||||
send_message_to_facebook fb_text_message_params if message.content.present?
|
send_message_to_facebook fb_text_message_params if message.content.present?
|
||||||
send_message_to_facebook fb_attachment_message_params if message.attachments.present?
|
send_message_to_facebook fb_attachment_message_params if message.attachments.present?
|
||||||
rescue Facebook::Messenger::FacebookError => e
|
rescue Facebook::Messenger::FacebookError => e
|
||||||
Rails.logger.info e
|
Sentry.capture_exception(e)
|
||||||
channel.authorization_error!
|
# TODO : handle specific errors or else page will get disconnected
|
||||||
|
# channel.authorization_error!
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_message_to_facebook(delivery_params)
|
def send_message_to_facebook(delivery_params)
|
||||||
|
|
|
@ -18,7 +18,8 @@ class Instagram::SendOnInstagramService < Base::SendOnChannelService
|
||||||
send_to_facebook_page message_params
|
send_to_facebook_page message_params
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
Sentry.capture_exception(e)
|
Sentry.capture_exception(e)
|
||||||
channel.authorization_error!
|
# TODO : handle specific errors or else page will get disconnected
|
||||||
|
# channel.authorization_error!
|
||||||
end
|
end
|
||||||
|
|
||||||
def message_params
|
def message_params
|
||||||
|
|
12
db/schema.rb
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2021_09_23_132659) do
|
ActiveRecord::Schema.define(version: 2021_09_29_150415) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "pg_stat_statements"
|
enable_extension "pg_stat_statements"
|
||||||
|
@ -61,6 +61,14 @@ ActiveRecord::Schema.define(version: 2021_09_23_132659) do
|
||||||
t.index ["message_id", "message_checksum"], name: "index_action_mailbox_inbound_emails_uniqueness", unique: true
|
t.index ["message_id", "message_checksum"], name: "index_action_mailbox_inbound_emails_uniqueness", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "actions", force: :cascade do |t|
|
||||||
|
t.string "name", null: false
|
||||||
|
t.jsonb "execution_list", default: {}, null: false
|
||||||
|
t.datetime "created_at", precision: 6, null: false
|
||||||
|
t.datetime "updated_at", precision: 6, null: false
|
||||||
|
t.index ["name"], name: "index_actions_on_name"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "active_storage_attachments", force: :cascade do |t|
|
create_table "active_storage_attachments", force: :cascade do |t|
|
||||||
t.string "name", null: false
|
t.string "name", null: false
|
||||||
t.string "record_type", null: false
|
t.string "record_type", null: false
|
||||||
|
@ -300,7 +308,7 @@ ActiveRecord::Schema.define(version: 2021_09_23_132659) do
|
||||||
t.datetime "agent_last_seen_at"
|
t.datetime "agent_last_seen_at"
|
||||||
t.jsonb "additional_attributes", default: {}
|
t.jsonb "additional_attributes", default: {}
|
||||||
t.bigint "contact_inbox_id"
|
t.bigint "contact_inbox_id"
|
||||||
t.uuid "uuid", default: -> { "gen_random_uuid()" }, null: false
|
t.uuid "uuid", default: -> { "public.gen_random_uuid()" }, null: false
|
||||||
t.string "identifier"
|
t.string "identifier"
|
||||||
t.datetime "last_activity_at", default: -> { "CURRENT_TIMESTAMP" }, null: false
|
t.datetime "last_activity_at", default: -> { "CURRENT_TIMESTAMP" }, null: false
|
||||||
t.bigint "team_id"
|
t.bigint "team_id"
|
||||||
|
|
BIN
public/integrations/channels/badges/instagram-dm.png
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
public/integrations/channels/badges/line.png
Normal file
After Width: | Height: | Size: 715 B |
BIN
public/integrations/channels/badges/messenger.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
public/integrations/channels/badges/sms.png
Normal file
After Width: | Height: | Size: 632 B |
BIN
public/integrations/channels/badges/telegram.png
Normal file
After Width: | Height: | Size: 947 B |
BIN
public/integrations/channels/badges/twitter-dm.png
Normal file
After Width: | Height: | Size: 642 B |
BIN
public/integrations/channels/badges/twitter-tweet.png
Normal file
After Width: | Height: | Size: 664 B |
BIN
public/integrations/channels/badges/whatsapp.png
Normal file
After Width: | Height: | Size: 1.3 KiB |