Class: FlowChat::Messenger::Middleware::ChoiceMapper
- Inherits:
-
Object
- Object
- FlowChat::Messenger::Middleware::ChoiceMapper
- Defined in:
- lib/flow_chat/messenger/middleware/choice_mapper.rb
Overview
Maps a reply back to the choice key the flow used.
Two key spaces can be live at once. A tap sends the payload the renderer put on the button, which is the title shown on it, and a user who types what they read sends that same string - so both resolve through one map. Only when a number is genuinely on screen does a typed digit mean a position, which is the second space.
The title is the payload rather than a separately generated id because FlowChat::ChoiceTitles already guarantees the titles in a set are distinct, numbering the set when they would not be. A generated id needed its own uniqueness rule, and the one it had was lossy: it stripped punctuation, so "Yes!" produced the id "Yes", which was another choice's label exactly.
Direct Known Subclasses
Constant Summary collapse
- ID_KEY =
"messenger.choice_mapping"- POSITION_KEY =
"messenger.position_mapping"
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.
22 23 24 25 |
# File 'lib/flow_chat/messenger/middleware/choice_mapper.rb', line 22 def initialize(app) @app = app FlowChat.logger.debug { "#{self.class.name}: Initialized" } end |
Instance Method Details
#call(context) ⇒ Object
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 |
# File 'lib/flow_chat/messenger/middleware/choice_mapper.rb', line 27 def call(context) @context = context @session = context.session handle_choice_input if intercept? # 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_mappings immediately below repopulates them # whenever the app actually returns choices. # # An earlier version asked stale_mappings? 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 for # WhatsApp in Task 6 and once here 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_mappings type, prompt, choices, media = @app.call(context) choices = create_mappings(choices) if choices.present? [type, prompt, choices, media] end |