Class: CollavreSlack::SlackInboundMessageJob

Inherits:
ApplicationJob
  • Object
show all
Defined in:
app/jobs/collavre_slack/slack_inbound_message_job.rb

Instance Method Summary collapse

Instance Method Details

#perform(payload) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'app/jobs/collavre_slack/slack_inbound_message_job.rb', line 5

def perform(payload)
  data = payload.with_indifferent_access
  creative = Collavre::Creative.find(data[:creative_id])
  user = Collavre.user_class.find_by(id: data[:user_id])
  channel_link = SlackChannelLink.find_by(id: data[:slack_channel_link_id])

  return unless creative && channel_link

  comment_user = user
  slack_email = data[:slack_email]
  slack_display_name = data[:slack_display_name]

  # Case 1: User exists in Collavre but lacks permission
  if user && !creative.has_permission?(user, :feedback)
    grant_feedback_permission(creative: creative, user: user, granter: channel_link.created_by)
    Rails.logger.info("[CollavreSlack] Granted feedback permission to user #{user.id} on creative #{creative.id}")
  end

  # Case 2: User not in Collavre - invite by email
  unless user
    if slack_email.present?
      invite_user_by_email(
        creative: creative,
        email: slack_email,
        inviter: channel_link.created_by
      )
      Rails.logger.info("[CollavreSlack] Sent invitation to #{slack_email} for creative #{creative.id}")
    end

    # Use channel creator as fallback for comment
    comment_user = channel_link.created_by
  end

  # Create comment with appropriate user
  comment = Collavre::Comment.new(
    creative: creative,
    user: comment_user,
    content: format_comment_content(data[:content], user, slack_display_name)
  )

  # Mark this comment as coming from Slack to prevent loop
  comment.instance_variable_set(:@from_slack, true)

  response = Collavre::Comments::CommandProcessor.new(comment: comment, user: user).call
  if response.present?
    comment.content = "#{comment.content}\n\n#{response}"
    comment.skip_dispatch = true  # slash command responses should not trigger AI
  end
  comment.save!

  # Create link between Slack message and comment for reaction sync
  if data[:slack_channel_link_id].present? && data[:slack_message_ts].present?
    SlackCommentLink.create!(
      comment: comment,
      slack_channel_link_id: data[:slack_channel_link_id],
      message_ts: data[:slack_message_ts]
    )
  end
end