Class: FlowChat::Telegram::Middleware::ChoiceMapper

Inherits:
Object
  • Object
show all
Defined in:
lib/flow_chat/telegram/middleware/choice_mapper.rb

Overview

Maps a Telegram reply back to the choice key the flow branches on.

callback_data is 1-64 bytes, not characters, and carries no character restrictions - Telegram types it as a byte string. Two things followed from sizing it in characters instead:

  • a label with multibyte characters overflowed the field and was rejected by the API, because 64 characters of CJK or emoji is far more than 64 bytes;
  • two labels sharing their first 64 characters were cut to the same callback_data, which then matched neither key and failed the flow's own validation, so the choice could not be picked at all.

Both are gone once the titles are built to a byte budget and a set that would collide under that budget is numbered. Numbering is what keeps them apart, and it works here for the same reason it works everywhere else: a position prefix sits at the front and survives a cut from the right, where a suffix would be the first thing lost.

Constant Summary collapse

SESSION_KEY =
"telegram.choice_mapping"
POSITION_KEY =
"telegram.position_mapping"
CALLBACK_DATA_LIMIT =
64

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ ChoiceMapper

Returns a new instance of ChoiceMapper.



29
30
31
32
# File 'lib/flow_chat/telegram/middleware/choice_mapper.rb', line 29

def initialize(app)
  @app = app
  FlowChat.logger.debug { "Telegram::ChoiceMapper: Initialized" }
end

Instance Method Details

#call(context) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/flow_chat/telegram/middleware/choice_mapper.rb', line 34

def call(context)
  @context = context
  @session = context.session

  resolve_input

  response = @app.call(context)
  return response unless response

  type, prompt, choices, media = response
  choices = remember(choices) if choices.present?

  [type, prompt, choices, media]
end