Class: FlowChat::Whatsapp::Middleware::ChoiceMapper
- Inherits:
-
Object
- Object
- FlowChat::Whatsapp::Middleware::ChoiceMapper
- Defined in:
- lib/flow_chat/whatsapp/middleware/choice_mapper.rb
Overview
Maps what WhatsApp sends back to the choice key the flow branches on.
The value on the wire is the title the user was shown, so a tap and a user typing what they read arrive as the same string and resolve through the same map.
Flow:
- Flow returns choices with original keys (=> "Create Account")
- This middleware asks FlowChat::ChoiceTitles for each displayed title
- It re-keys the choices by title and stores title => original key
- Renderer receives the re-keyed choices and renders them
- User taps a button, or types the title on it
- This middleware resolves either back to the original key
A title is truncated to the rung's cap (see FlowChat::Whatsapp::Renderer::BUTTON_TITLE_LENGTH / LIST_ROW_TITLE_LENGTH). When truncation, or a duplicate label, would leave two titles indistinguishable, FlowChat::ChoiceTitles numbers every title in the set instead - which is what keeps them distinct, and why nothing here has to check for collisions itself. See its docs for why that decision is made once for the whole set.
Instance Method Summary collapse
- #call(context) ⇒ Object
-
#initialize(app) ⇒ ChoiceMapper
constructor
A new instance of ChoiceMapper.
Constructor Details
#initialize(app) ⇒ ChoiceMapper
Returns a new instance of ChoiceMapper.
37 38 39 40 |
# File 'lib/flow_chat/whatsapp/middleware/choice_mapper.rb', line 37 def initialize(app) @app = app FlowChat.logger.debug { "Whatsapp::ChoiceMapper: Initialized WhatsApp choice mapping middleware" } end |
Instance Method Details
#call(context) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/flow_chat/whatsapp/middleware/choice_mapper.rb', line 42 def call(context) @context = context @session = context.session session_id = context["session.id"] FlowChat.logger.debug { "Whatsapp::ChoiceMapper: Processing request for session #{session_id}" } if intercept? FlowChat.logger.info { "Whatsapp::ChoiceMapper: Intercepting request for choice resolution - session #{session_id}" } handle_choice_input end # The maps belong to exactly one screen: this turn's, if it had a # resolvable answer, or one that already fell out of use otherwise. # Either way nothing here is still owed to the next screen, so they # are cleared unconditionally rather than asked whether they still # look "live" - create_id_mapping immediately below repopulates # them whenever the app actually returns choices. # # An earlier version asked should_clear_for_new_flow? that question # after handle_choice_input had already rewritten @context.input to # the *resolved* value, which can equal one of the map's own keys # (an Array choice's key is its label, and the wire value is the # title built from that label), so the check answered # "still live" about a value that was never a fresh reply. That let # the maps survive into a free-text screen and reinterpret a typed # answer there as the previous menu's choice. This was fixed once # here in Task 6 and once for Messenger in Task 13; both fixes had # the same shape and the same blind spot, which is why the guard is # gone rather than patched a third time. clear_choice_state # Call the app (executor -> flow) type, prompt, choices, media = @app.call(context) # Transform choices if present (like USSD does) if choices.present? FlowChat.logger.debug { "Whatsapp::ChoiceMapper: Found choices, creating ID mapping" } choices = create_id_mapping(choices) end [type, prompt, choices, media] end |