diff --git a/app/models/message.rb b/app/models/message.rb index 1e3bb8dd7..b61a660f3 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -2,21 +2,22 @@ # # Table name: messages # -# id :integer not null, primary key -# content :text -# content_attributes :json -# content_type :integer default("text") -# message_type :integer not null -# private :boolean default(FALSE) -# sender_type :string -# status :integer default("sent") -# created_at :datetime not null -# updated_at :datetime not null -# account_id :integer not null -# conversation_id :integer not null -# inbox_id :integer not null -# sender_id :bigint -# source_id :string +# id :integer not null, primary key +# content :text +# content_attributes :json +# content_type :integer default("text") +# external_source_ids :jsonb +# message_type :integer not null +# private :boolean default(FALSE) +# sender_type :string +# status :integer default("sent") +# created_at :datetime not null +# updated_at :datetime not null +# account_id :integer not null +# conversation_id :integer not null +# inbox_id :integer not null +# sender_id :bigint +# source_id :string # # Indexes # @@ -53,6 +54,8 @@ class Message < ApplicationRecord # [:in_reply_to] : Used to reply to a particular tweet in threads store :content_attributes, accessors: [:submitted_email, :items, :submitted_values, :email, :in_reply_to], coder: JSON + store :external_source_ids, accessors: [:slack], coder: JSON, prefix: :external_source_id + # .succ is a hack to avoid https://makandracards.com/makandra/1057-why-two-ruby-time-objects-are-not-equal-although-they-appear-to-be scope :unread_since, ->(datetime) { where('EXTRACT(EPOCH FROM created_at) > (?)', datetime.to_i.succ) } scope :chat, -> { where.not(message_type: :activity).where(private: false) } diff --git a/app/services/base/send_on_channel_service.rb b/app/services/base/send_on_channel_service.rb index 2aeb2df09..298f60962 100644 --- a/app/services/base/send_on_channel_service.rb +++ b/app/services/base/send_on_channel_service.rb @@ -35,8 +35,8 @@ class Base::SendOnChannelService def outgoing_message_originated_from_channel? # TODO: we need to refactor this logic as more integrations comes by # chatwoot messages won't have source id at the moment - # outgoing messages may be created in slack which should be send to the channel - message.source_id.present? && !message.source_id.starts_with?('slack_') + # TODO: migrate source_ids to external_source_ids and check the source id relevant to specific channel + message.source_id.present? end def outgoing_message? diff --git a/db/migrate/20200828175931_add_external_source_ids_to_messages.rb b/db/migrate/20200828175931_add_external_source_ids_to_messages.rb new file mode 100644 index 000000000..772a18364 --- /dev/null +++ b/db/migrate/20200828175931_add_external_source_ids_to_messages.rb @@ -0,0 +1,16 @@ +class AddExternalSourceIdsToMessages < ActiveRecord::Migration[6.0] + def change + add_column :messages, :external_source_ids, :jsonb, default: {} + migrate_slack_external_source_ids + end + + def migrate_slack_external_source_ids + Message.where('source_id LIKE ?', 'slack_%').find_in_batches do |message_batch| + message_batch.each do |message| + message.external_source_id_slack = message.source_id.split('slack_')[1] + message.source_id = nil + message.save! + end + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 68d1b0a73..fa9bf8959 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_08_19_190629) do +ActiveRecord::Schema.define(version: 2020_08_28_175931) do # These are extensions that must be enabled in order to support this database enable_extension "pg_stat_statements" @@ -328,6 +328,7 @@ ActiveRecord::Schema.define(version: 2020_08_19_190629) do t.json "content_attributes", default: {} t.string "sender_type" t.bigint "sender_id" + t.jsonb "external_source_ids", default: {} t.index ["account_id"], name: "index_messages_on_account_id" t.index ["conversation_id"], name: "index_messages_on_conversation_id" t.index ["inbox_id"], name: "index_messages_on_inbox_id" diff --git a/lib/integrations/slack/incoming_message_builder.rb b/lib/integrations/slack/incoming_message_builder.rb index e7ebd735f..acd4ca12d 100644 --- a/lib/integrations/slack/incoming_message_builder.rb +++ b/lib/integrations/slack/incoming_message_builder.rb @@ -80,7 +80,7 @@ class Integrations::Slack::IncomingMessageBuilder account_id: conversation.account_id, inbox_id: conversation.inbox_id, content: params[:event][:text], - source_id: "slack_#{params[:event][:ts]}", + external_source_id_slack: params[:event][:ts], private: private_note?, sender: sender ) diff --git a/lib/integrations/slack/send_on_slack_service.rb b/lib/integrations/slack/send_on_slack_service.rb index 4c5bb46c6..c7c1fd7a4 100644 --- a/lib/integrations/slack/send_on_slack_service.rb +++ b/lib/integrations/slack/send_on_slack_service.rb @@ -4,9 +4,9 @@ class Integrations::Slack::SendOnSlackService < Base::SendOnChannelService def perform # overriding the base class logic since the validations are different in this case. # FIXME: for now we will only send messages from widget to slack - return unless channel.is_a?(Channel::WebWidget) + return unless valid_channel_for_slack? # we don't want message loop in slack - return if message.source_id.try(:starts_with?, 'slack_') + return if message.external_source_id_slack.present? # we don't want to start slack thread from agent conversation as of now return if message.outgoing? && conversation.identifier.blank? @@ -15,6 +15,13 @@ class Integrations::Slack::SendOnSlackService < Base::SendOnChannelService private + def valid_channel_for_slack? + # slack wouldn't be an idean interface to reply to tweets, hence disabling that case + return false if channel.is_a?(Channel::TwitterProfile) && conversation.additional_attributes['type'] == 'tweet' + + true + end + def perform_reply send_message update_reference_id