feat: Enable Slack Integration in all channels (#1175)

This commit is contained in:
Sojan Jose 2020-08-29 01:39:41 +05:30 committed by GitHub
parent 45cd949c40
commit 85ae6d92b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 48 additions and 21 deletions

View file

@ -2,21 +2,22 @@
# #
# Table name: messages # Table name: messages
# #
# id :integer not null, primary key # id :integer not null, primary key
# content :text # content :text
# content_attributes :json # content_attributes :json
# content_type :integer default("text") # content_type :integer default("text")
# message_type :integer not null # external_source_ids :jsonb
# private :boolean default(FALSE) # message_type :integer not null
# sender_type :string # private :boolean default(FALSE)
# status :integer default("sent") # sender_type :string
# created_at :datetime not null # status :integer default("sent")
# updated_at :datetime not null # created_at :datetime not null
# account_id :integer not null # updated_at :datetime not null
# conversation_id :integer not null # account_id :integer not null
# inbox_id :integer not null # conversation_id :integer not null
# sender_id :bigint # inbox_id :integer not null
# source_id :string # sender_id :bigint
# source_id :string
# #
# Indexes # Indexes
# #
@ -53,6 +54,8 @@ class Message < ApplicationRecord
# [:in_reply_to] : Used to reply to a particular tweet in threads # [: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 :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 # .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 :unread_since, ->(datetime) { where('EXTRACT(EPOCH FROM created_at) > (?)', datetime.to_i.succ) }
scope :chat, -> { where.not(message_type: :activity).where(private: false) } scope :chat, -> { where.not(message_type: :activity).where(private: false) }

View file

@ -35,8 +35,8 @@ class Base::SendOnChannelService
def outgoing_message_originated_from_channel? def outgoing_message_originated_from_channel?
# TODO: we need to refactor this logic as more integrations comes by # TODO: we need to refactor this logic as more integrations comes by
# chatwoot messages won't have source id at the moment # chatwoot messages won't have source id at the moment
# outgoing messages may be created in slack which should be send to the channel # TODO: migrate source_ids to external_source_ids and check the source id relevant to specific channel
message.source_id.present? && !message.source_id.starts_with?('slack_') message.source_id.present?
end end
def outgoing_message? def outgoing_message?

View file

@ -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

View file

@ -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: 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 # These are extensions that must be enabled in order to support this database
enable_extension "pg_stat_statements" enable_extension "pg_stat_statements"
@ -328,6 +328,7 @@ ActiveRecord::Schema.define(version: 2020_08_19_190629) do
t.json "content_attributes", default: {} t.json "content_attributes", default: {}
t.string "sender_type" t.string "sender_type"
t.bigint "sender_id" t.bigint "sender_id"
t.jsonb "external_source_ids", default: {}
t.index ["account_id"], name: "index_messages_on_account_id" t.index ["account_id"], name: "index_messages_on_account_id"
t.index ["conversation_id"], name: "index_messages_on_conversation_id" t.index ["conversation_id"], name: "index_messages_on_conversation_id"
t.index ["inbox_id"], name: "index_messages_on_inbox_id" t.index ["inbox_id"], name: "index_messages_on_inbox_id"

View file

@ -80,7 +80,7 @@ class Integrations::Slack::IncomingMessageBuilder
account_id: conversation.account_id, account_id: conversation.account_id,
inbox_id: conversation.inbox_id, inbox_id: conversation.inbox_id,
content: params[:event][:text], content: params[:event][:text],
source_id: "slack_#{params[:event][:ts]}", external_source_id_slack: params[:event][:ts],
private: private_note?, private: private_note?,
sender: sender sender: sender
) )

View file

@ -4,9 +4,9 @@ class Integrations::Slack::SendOnSlackService < Base::SendOnChannelService
def perform def perform
# overriding the base class logic since the validations are different in this case. # 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 # 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 # 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 # we don't want to start slack thread from agent conversation as of now
return if message.outgoing? && conversation.identifier.blank? return if message.outgoing? && conversation.identifier.blank?
@ -15,6 +15,13 @@ class Integrations::Slack::SendOnSlackService < Base::SendOnChannelService
private 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 def perform_reply
send_message send_message
update_reference_id update_reference_id