2020-06-12 17:42:47 +00:00
class Integrations :: Slack :: IncomingMessageBuilder
attr_reader :params
SUPPORTED_EVENT_TYPES = %w[ event_callback url_verification ] . freeze
SUPPORTED_EVENTS = %w[ message ] . freeze
SUPPORTED_MESSAGE_TYPES = %w[ rich_text ] . freeze
def initialize ( params )
@params = params
end
def perform
return unless valid_event?
if hook_verification?
verify_hook
elsif create_message?
create_message
end
end
private
def valid_event?
supported_event_type? && supported_event?
end
def supported_event_type?
SUPPORTED_EVENT_TYPES . include? ( params [ :type ] )
end
def supported_event?
hook_verification? || SUPPORTED_EVENTS . include? ( params [ :event ] [ :type ] )
end
def supported_message?
2022-04-27 19:44:03 +00:00
if message . present?
2022-05-09 13:48:30 +00:00
SUPPORTED_MESSAGE_TYPES . include? ( message [ :type ] ) && ! attached_file_message?
2022-04-27 19:44:03 +00:00
else
2022-05-09 18:24:45 +00:00
params [ :event ] [ :files ] . present? && ! attached_file_message?
2022-04-27 19:44:03 +00:00
end
2020-06-12 17:42:47 +00:00
end
def hook_verification?
params [ :type ] == 'url_verification'
end
2020-11-09 16:31:57 +00:00
def thread_timestamp_available?
params [ :event ] [ :thread_ts ] . present?
end
2020-06-12 17:42:47 +00:00
def create_message?
2020-11-09 16:31:57 +00:00
thread_timestamp_available? && supported_message? && integration_hook
2020-06-12 17:42:47 +00:00
end
def message
2020-06-22 07:49:26 +00:00
params [ :event ] [ :blocks ] & . first
2020-06-12 17:42:47 +00:00
end
def verify_hook
{
challenge : params [ :challenge ]
}
end
def integration_hook
2020-06-22 07:49:26 +00:00
@integration_hook || = Integrations :: Hook . find_by ( reference_id : params [ :event ] [ :channel ] )
2020-06-12 17:42:47 +00:00
end
def conversation
@conversation || = Conversation . where ( identifier : params [ :event ] [ :thread_ts ] ) . first
end
2020-06-22 07:49:26 +00:00
def sender
user_email = slack_client . users_info ( user : params [ :event ] [ :user ] ) [ :user ] [ :profile ] [ :email ]
conversation . account . users . find_by ( email : user_email )
end
def private_note?
2022-07-28 04:27:39 +00:00
params [ :event ] [ :text ] . strip . downcase . starts_with? ( 'note:' , 'private:' )
2020-06-22 07:49:26 +00:00
end
2020-06-12 17:42:47 +00:00
def create_message
return unless conversation
2022-09-13 12:10:06 +00:00
@message = conversation . messages . create! (
2020-06-22 07:49:26 +00:00
message_type : :outgoing ,
2020-06-12 17:42:47 +00:00
account_id : conversation . account_id ,
inbox_id : conversation . inbox_id ,
2021-07-09 12:15:02 +00:00
content : Slack :: Messages :: Formatting . unescape ( params [ :event ] [ :text ] || '' ) ,
2020-08-28 20:09:41 +00:00
external_source_id_slack : params [ :event ] [ :ts ] ,
2020-06-22 07:49:26 +00:00
private : private_note? ,
2020-06-27 16:04:53 +00:00
sender : sender
2020-06-12 17:42:47 +00:00
)
2021-09-17 19:19:01 +00:00
process_attachments ( params [ :event ] [ :files ] ) if params [ :event ] [ :files ] . present?
2020-06-12 17:42:47 +00:00
{ status : 'success' }
end
2020-06-22 07:49:26 +00:00
def slack_client
2020-06-25 18:05:16 +00:00
@slack_client || = Slack :: Web :: Client . new ( token : @integration_hook . access_token )
2020-06-22 07:49:26 +00:00
end
2021-09-17 19:19:01 +00:00
# TODO: move process attachment for facebook instagram and slack in one place
# https://api.slack.com/messaging/files
def process_attachments ( attachments )
attachments . each do | attachment |
tempfile = Down :: NetHttp . download ( attachment [ :url_private ] , headers : { 'Authorization' = > " Bearer #{ integration_hook . access_token } " } )
attachment_params = {
file_type : file_type ( attachment ) ,
account_id : @message . account_id ,
external_url : attachment [ :url_private ] ,
file : {
io : tempfile ,
filename : tempfile . original_filename ,
content_type : tempfile . content_type
}
}
attachment_obj = @message . attachments . new ( attachment_params )
attachment_obj . file . content_type = attachment [ :mimetype ]
attachment_obj . save!
end
end
def file_type ( attachment )
return if attachment [ :mimetype ] == 'text/plain'
case attachment [ :filetype ]
when 'png' , 'jpeg' , 'gif' , 'bmp' , 'tiff' , 'jpg'
:image
when 'pdf'
:file
end
end
2022-05-09 13:48:30 +00:00
# Ignoring the changes added here https://github.com/chatwoot/chatwoot/blob/5b5a6d89c0cf7f3148a1439d6fcd847784a79b94/lib/integrations/slack/send_on_slack_service.rb#L69
# This make sure 'Attached File!' comment is not visible on CW dashboard.
# This is showing because of https://github.com/chatwoot/chatwoot/pull/4494/commits/07a1c0da1e522d76e37b5f0cecdb4613389ab9b6 change.
# As now we consider the postback message with event[:files]
def attached_file_message?
params [ :event ] [ :text ] == 'Attached File!'
end
2020-06-12 17:42:47 +00:00
end