Class: InstagramConnect::SendMessageJob

Inherits:
ApplicationJob
  • Object
show all
Defined in:
app/jobs/instagram_connect/send_message_job.rb

Overview

Sends one pending outbound Message via the Graph API, exactly once.

The claim is an atomic UPDATE from pending to sending, so a duplicate enqueue cannot double-send. Everything after it keeps an at-most-once bias: on any doubt the message is marked failed for an operator to retry deliberately, never resent automatically. A duplicate message reaching a customer is worse than a visible failure.

Instance Method Summary collapse

Instance Method Details

#perform(message_id) ⇒ Object



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
# File 'app/jobs/instagram_connect/send_message_job.rb', line 12

def perform(message_id)
  claimed = Message.where(id: message_id, status: "pending")
                   .update_all(status: "sending", updated_at: Time.current)
  return unless claimed == 1

  message = Message.find(message_id)
  # The claim was callback-free, so a host rendering this thread live needs
  # telling before the send starts rather than after it finishes.
  message.broadcast_refresh

  conversation = message.conversation

  # Meta rejects a send on a thread another app owns, and the error it
  # returns says nothing useful about why. Refusing here names the reason.
  if conversation.controlled_elsewhere?
    return fail_message(message, "thread_controlled_elsewhere",
                        "Another app currently has control of this conversation.")
  end

  tag = MessagingWindow.new(last_inbound_at: conversation.last_inbound_at).send_tag
  if tag == :blocked
    return fail_message(message, "outside_messaging_window",
                        "The reply window has closed; the customer must message again.")
  end

  deliver(message, conversation, tag)
end