Class: Hg::PostbackWorker

Inherits:
Workers::Base show all
Includes:
Sidekiq::Worker
Defined in:
app/workers/hg/postback_worker.rb

Overview

Handles processing postbacks. A postback is any structured request from any platform (i.e. button and quick replies, which send hash payloads).

Instance Method Summary collapse

Instance Method Details

#perform(user_id, redis_namespace, bot_class_name)

This method returns an undefined value.

Process an inbound postback.

Parameters:

  • user_id (String, Integer)

    The ID representing the user on this platform

  • redis_namespace (String)

    The redis namespace under which the postback to process is nested.

  • bot_class_name (String)

    The string version of the bot's class name



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
64
# File 'app/workers/hg/postback_worker.rb', line 17

def perform(user_id, redis_namespace, bot_class_name)
  # Retrieve the latest postback for this user
  raw_postback = pop_raw_postback(user_id, redis_namespace)

  # Do nothing if no postback available. This could be due to multiple
  # execution on the part of Sidekiq. This ensures idempotence. We loop
  # here to ensure that this worker attempts to drain the queue for
  # the user.
  until raw_postback.empty?
    # Locate the class representing the bot.
    bot = Kernel.const_get(bot_class_name)

    # Fetch the User representing the message's sender
    # TODO: pass in a `user_id_field` to indicate how to find user in order to
    # make this platform agnostic
    user = find_bot_user(bot, user_id)

    request =
      # Handle referral postback
      if raw_postback['referral']
        # Extract payload from referral
        @referral = Facebook::Messenger::Incoming::Referral.new(raw_postback)
        # Build request object
        build_referral_request @referral, user
      # Handle postback
      else
        # Extract the payload from the postback.
        @postback = Facebook::Messenger::Incoming::Postback.new(raw_postback)
        # Build the request object
        build_payload_request @postback.payload, user
      end

    # Send to Chatbase if env var present
    # Use the action, because it's a postback.
    send_user_message(
      intent: request.action,
      text: request.action,
      not_handled: false,
      message: @postback || @referral
    ) if ENV['CHATBASE_API_KEY']

    # Send the request to the bot's router.
    bot.router.handle(request)

    # Attempt to pop another postback from the queue for processing.
    raw_postback = pop_raw_postback(user_id, redis_namespace)
  end
end