class BotFramework::Session

Attributes

conversation_data[RW]
dialog_state[RW]
library[RW]
localizer[RW]
message[RW]
private_conversation_data[RW]
session_state[RW]
user_data[RW]

Public Class Methods

active_dialog_stack_entry(stack) click to toggle source

Returns a active stack entry or nil

# File lib/bot_framework/session.rb, line 331
def self.active_dialog_stack_entry(stack)
  stack.last || nil
end
findEachDialogStackEntry(stack, dialog_id) click to toggle source

Searches a dialog stack for a specific dialog, in either a forward or reverse direction, returning its index.

# File lib/bot_framework/session.rb, line 323
def self.findEachDialogStackEntry(stack, dialog_id)
  stack.each_with_index do |item, index|
    return index if item[:id] = dialog_id
  end
  -1
end
forEachDialogStackEntry(stack) { |item| ... } click to toggle source

Enumerates all a stacks dialog entries in either a forward or reverse direction.

# File lib/bot_framework/session.rb, line 318
def self.forEachDialogStackEntry(stack)
  stack.each { |item| yield(item) }
end
new(options) click to toggle source
Calls superclass method
# File lib/bot_framework/session.rb, line 5
def initialize(options)
  super
  @library = options[:library]
  @localizer = options[:localizer]
  @msg_sent = false
  @is_reset = false
  @last_send_time = Time.now # TODO: Move to proc?
  @batch = []
  @batch_timer = Timers::Group.new
  @batch_started = false
  @sending_batch = false
  @in_middleware = false
  @_locale = nil

  @options = options || {
    on_save: nil,
    on_send: nil,
    library: nil,
    localizer: nil,
    middleware: nil,
    dialog_id: nil,
    dialog_args: nil,
    auto_batch_delay: nil,
    dialog_error_message: nil,
    actions: nil
  }
  @auto_batch_delay = 250 unless options[:auto_batch_delay].is_a? Integer
  @timers = Timers::Group.new
end
pop_dialog_stack_entry(stack) click to toggle source

Pop active dialog out of the stack

# File lib/bot_framework/session.rb, line 344
def self.pop_dialog_stack_entry(stack)
  stack.pop if stack
  Session.active_dialog_stack_entry(stack)
end
prune_dialog_stack(_stack, _start) click to toggle source

Deletes all dialog stack entries starting with the specified index and returns the new active dialog.

# File lib/bot_framework/session.rb, line 350
def self.prune_dialog_stack(_stack, _start)
end
push_dialog_stack_entry(statck, entry) click to toggle source

Pushes a new dialog into stack and return it as active dialog

# File lib/bot_framework/session.rb, line 336
def self.push_dialog_stack_entry(statck, entry)
  entry[:state] ||= {}
  statck ||= []
  stack.push(entry)
  entry
end
validate_dialog_stack(_stack, _root) click to toggle source

Ensures that all of the entries on a dialog stack reference valid dialogs within a library hierarchy.

# File lib/bot_framework/session.rb, line 354
def self.validate_dialog_stack(_stack, _root)
end

Public Instance Methods

begin_dialog(id, args = nil) click to toggle source

Begin a new dialog

# File lib/bot_framework/session.rb, line 188
def begin_dialog(id, args = nil)
  logger.info "Beginning new dialog #{id}"
  id = resolve_dialog_id(id)
  dialog = find_dialog(id)
  raise "Dialog #{id} Not found" unless dialog
  push_dialog(id: id, state: {})
  start_batch
  dialog.begin(self, args)
  self
end
cancel_dialog() click to toggle source
# File lib/bot_framework/session.rb, line 290
def cancel_dialog; end
clear_dialog_stack() click to toggle source

Clears the current Dialog stack

# File lib/bot_framework/session.rb, line 312
def clear_dialog_stack
  @session_state[:call_stack] = []
  @dialog_data = nil
end
dialog_stack(new_stack = nil) click to toggle source

Gets and Sets current dialog stack

# File lib/bot_framework/session.rb, line 297
def dialog_stack(new_stack = nil)
  if new_stack
    # Update stack and dialog data

    stack = @session_state[:call_stack] = new_stack || []
    @dialog_data = stack.empty? nil || stack.last
  else
    # Copy over dialog data to slack
    stack = @session_state[:call_stack] || []
    stack.last.state = @dialog_data || {}
  end
  stack
end
dispatch(session_state, message) click to toggle source
# File lib/bot_framework/session.rb, line 50
def dispatch(session_state, message)
  index = 0
  session = self
  now = Time.now
  middleware = @options[:middleware] || []

  _next = lambda do
    handler = middleware[index] if index < middleware.length
    if handler
      index += 1
      handler(session, _next)
    else
      @in_middleware = false
      @session_state[:last_acess] = now
      done
    end
  end
  session_state ||= { call_stack: [], last_acess: Time.now, version: 0.0 }
  # Making sure that dialog is properly initialized
  cur = cur_dialog
  self.dialog_data = cur.state if cur
  # Dispatch message
  message ||= { text: '' }
  message[:type] ||= 'message'
  # Ensure that localized prompts are loaded
  # TODO
  self
end
end_conversation(message = nil, _args = {}) click to toggle source

End conversation with the user

# File lib/bot_framework/session.rb, line 214
def end_conversation(message = nil, _args = {})
  if message
    # TODO: sent message
  end
  # Clear private conversation data
  @private_conversation_data = {}

  # Clear stack and save
  logger.info 'End conversation'
  ss = @session_state
  ss.call_stack = []
  send_batch
  self
end
end_dialog(message = nil, args = {}) click to toggle source
# File lib/bot_framework/session.rb, line 229
def end_dialog(message = nil, args = {})
  if message
    # TODO: end_dialog_with_result
  end
  cur = cur_dialog
  if cur
    if message
      m = if (message.is_a? String) || (message.is_a? Array)
            create_message(cur_library_name, message, args)
          else
            message
          end
      @msg_sent = true
      prepare_message(m)
      @batch.push(m)
    end

    # Pop the dialog of the stack and resume the parent
    logger.info 'Session.end_dialog'
    child_id = cur.id
    cur = pop_dialog
    start_batch
    if cur
      dialog = find_dialog(cur.id)
      if dialog
        dialog.dialog_resumed(self, resumed: :completed, response: true, child_id: child_id)
      else
        # Bad dialog !! , we should never reach here
        raise "Can't resume , missing parent"
      end
    end
  end
end
end_dialog_with_result(result) click to toggle source

Ends current dialog and returns a value to the caller

# File lib/bot_framework/session.rb, line 264
def end_dialog_with_result(result)
  # Validate call stack
  cur = cur_dialog
  if cur
    # Validate the result
    result ||= {}
    result[:resumed] ||= :completed
    result.child_id = cur.id
    logger.info 'Session.end_dialog_with_result'

    # Pop dialog of the stack and resume parent dialog
    cur = pop_dialog
    start_batch
    if cur
      dialog = find_dialog(cur.id)
      if dialog
        dialog.dialog_resumed(self, result)
      else
        # Bad dialog state
        raise "Can't resume , missing parent dialog"
      end
    end
  end
  self
end
error(_error) click to toggle source
# File lib/bot_framework/session.rb, line 79
def error(_error)
  logger.info 'Session error'
  if options[:dialog_error_message]
    end_conversation(options[:dialog_error_message])
  else
    # TODO: Add localisation
    locale = preferred_locale
    end_conversation 'Error in conversation'
  end

  # TODO: Log error
end
gettext(message_id, options = {}) click to toggle source

Gets and formats localized text string

# File lib/bot_framework/session.rb, line 110
def gettext(message_id, options = {})
  # TODO
  # stub
end
ngettext(message_id, message_id_plural, count) click to toggle source

Gets and formats the singular/plural form of a localized text string.

# File lib/bot_framework/session.rb, line 116
def ngettext(message_id, message_id_plural, count); end
preferred_locale(locale = nil) click to toggle source
# File lib/bot_framework/session.rb, line 92
def preferred_locale(locale = nil)
  if locale
    @_locale = locale
    @user_data['BotBuilder.Data.PreferredLocale'] = locale if @user_data
    @localizer.load if @localizer # TODO
  elsif !@_locale
    if @user_data && @user_data['BotBuilder.Data.PreferredLocale']
      @_locale = @user_data['BotBuilder.Data.PreferredLocale']
    elsif @message && @message[:text_locale]
      @_locale = @message[:text_locale]
    elsif @localizer
      @_locale = @localizer[:default_locale]
    end
  end
  @_locale
end
replace_dialog(id, args = nil) click to toggle source
# File lib/bot_framework/session.rb, line 199
def replace_dialog(id, args = nil)
  logger.info "Session replace dialog #{id}"
  id = resolve_dialog_id(id)
  dialog = find_dialog(id)
  raise "Dialog #{id} Not found" unless dialog

  # Update the stack and start dialog
  pop_dialog
  push_dialog(id: id, state: {})
  start_batch
  dialog.begin(self, args)
  self
end
reset() click to toggle source
# File lib/bot_framework/session.rb, line 292
def reset; end
route_to_active_dialog() click to toggle source

Dispatches handling of the current message to the active dialog stack entry.

# File lib/bot_framework/session.rb, line 361
def route_to_active_dialog; end
save() click to toggle source

Manually save current session state

# File lib/bot_framework/session.rb, line 119
def save
  logger.info 'Session.save'
  start_batch
  self
end
send(message, args = []) click to toggle source
# File lib/bot_framework/session.rb, line 125
def send(message, args = [])
  args.unshift(@cur_library_name, message)
  send_localized(args, message)
end
send_batch() { |err| ... } click to toggle source
# File lib/bot_framework/session.rb, line 149
def send_batch
  logger.info "Sending batch with elements #{@batch.count}"
  return if sending_batch?
  # TODO: timer
  @batch_timer = nil
  batch = @batch
  @batch_started = false
  @sending_batch = true
  cur = cur_dialog
  cur.state = @dialog_data
  options[:on_save] = proc do |err|
    if err
      @sending_batch = false
      case (err.code || '')
      when 'EBADMSG'
      when 'EMSGSIZE'
        # Something went wrong , let's reset everything
        @user_data = {}
        @batch = []
        end_conversation(@options[:dialog_error_message] || 'Something went wrong and we need to startover')
      end
      yield(err) if block_given?
    else
      if batch.length
        options[:on_send].call(batch) do |err|
          @sending_batch = false
          start_batch if @batch_started # What is this :o
          yield(err) if block_given?
        end
      else
        @sending_batch = false
        start_batch if @batch_started
        yield(err) if block_given?
      end
    end
  end
end
send_localized(_localization_namspace, message, _args = []) click to toggle source
# File lib/bot_framework/session.rb, line 130
def send_localized(_localization_namspace, message, _args = [])
  # TODO: Incomplete
  @msg_sent = true
  m = { text: message }
  prepare_message(m)
  @batch << m
  self
end
send_typing() click to toggle source

Sends a typing indicator to the user

# File lib/bot_framework/session.rb, line 140
def send_typing
  @msg_sent = true
  m = { type: 'typing' }
  m = prepare_message(m)
  @batch.push(m)
  logger.info 'Send Typing'
  send_batch
end
to_recognize_context() click to toggle source
# File lib/bot_framework/session.rb, line 35
def to_recognize_context
  {
    message: message,
    user_data: user_data,
    conversation_data: conversation_data,
    private_conversation_data: private_conversation_data,
    localizer: localizer,
    dialog_stack: dialog_stack,
    preferred_locale: preferred_locale,
    get_text: get_text,
    nget_text: nget_text,
    locale: preferred_locale
  }
end

Private Instance Methods

create_message() click to toggle source
# File lib/bot_framework/session.rb, line 376
def create_message; end
cur_dialog() click to toggle source
# File lib/bot_framework/session.rb, line 401
def cur_dialog
  ss = @session_sate
  cur = ss.call_stack.last unless ss.call_stack.empty?
  cur
end
cur_library_name() click to toggle source
# File lib/bot_framework/session.rb, line 391
def cur_library_name; end
delete_dialogs() click to toggle source
# File lib/bot_framework/session.rb, line 399
def delete_dialogs; end
find_dialog() click to toggle source
# File lib/bot_framework/session.rb, line 393
def find_dialog; end
pop_dialog() click to toggle source
# File lib/bot_framework/session.rb, line 397
def pop_dialog; end
prepare_message(msg) click to toggle source
# File lib/bot_framework/session.rb, line 378
def prepare_message(msg)
  msg[:type] ||= 'message'
  msg[:address] ||= message[:address]
  msg[:text_locale] ||= message[:text_locale]
  msg
end
push_dialog() click to toggle source
# File lib/bot_framework/session.rb, line 395
def push_dialog; end
resolve_dialog_id() click to toggle source
# File lib/bot_framework/session.rb, line 389
def resolve_dialog_id; end
start_batch() click to toggle source
# File lib/bot_framework/session.rb, line 365
def start_batch
  @batch_started = true
  unless @sending_batch
    @batch_timer.cancel if @batch_timer
    # TODO: send_batch after config[:auto_batch_delay] seconds
    @batch_timer = @timers.after(config[:auto_batch_delay]) do
      send_batch
    end
  end
end
validate_call_stack() click to toggle source
# File lib/bot_framework/session.rb, line 387
def validate_call_stack; end
vget_text() click to toggle source
# File lib/bot_framework/session.rb, line 385
def vget_text; end