bot_platform 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d96e8445f9a9c0076abb76466b1d303585f1c013604c04cce1455a5d008eeabd
4
- data.tar.gz: 755fb77055dd2f6a325ece4f24b4e9892f9500b947586f16c81c8cc22139bc94
3
+ metadata.gz: 0c7889efb278cdccac2f362eba726567c20523b0f71295fd99dcf02c599dde66
4
+ data.tar.gz: 50eae5a0a56f0d024adaded78b83761b7a88a2ae03162bc573582f5d97863c0e
5
5
  SHA512:
6
- metadata.gz: 85b765ba89d4e1b353d9b69619672cf9f9438d6ac035013beb6446b9cd23cab91d1e7cff70f320ef9f2b216c0a11bc20a0d989022d74323d88c3f5e47ac66306
7
- data.tar.gz: 54ab28dbb708871b12ce01db343e3c42bf7a458d1f0b8c5a7cd629a138ae1da79eb2574aae2db5934492a9579f3ec470ceaf04dd86734d264a1359264f5ff03c
6
+ metadata.gz: e69556208d3f547699c078223e8d5669c87af5224f42ffb8d98adc063172a6bdf42d8094ee25168de1f24c037c8ddb55e9972b7b346d5cc988ecb908f1267d5f
7
+ data.tar.gz: 3a2b1ef5b894d09c0f1e1a222363db7af962bc4dd2bb92bb23c02374fb50485d89b9c928b91d32834f8a30b2228827b2e5b84901061c68a3a1fe06915ac97ba3
data/.gitignore CHANGED
@@ -7,6 +7,8 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
 
10
+ .DS_Store
11
+
10
12
  vendor/bundle
11
13
 
12
14
  # rspec failure tracking
data/CHANGELOG.md CHANGED
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.0] - 2021-09-06
11
+
12
+ ### Added
13
+ - Waterfall dialog support
14
+ - Waterfall sample
15
+ - user_state
16
+
17
+ ### Fixed
18
+ - end_of_turn response
19
+
10
20
  ## [0.2.2-0.2.3] - 2021-09-06
11
21
 
12
22
  ### Added
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bot_platform (0.2.3)
4
+ bot_platform (0.3.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  ##
2
2
  *This Project is still underconstruction.*
3
3
 
4
+ ![One Bot, Multiple Channels!](https://github.com/Lifevar/bot-platform/blob/main/images/bot-platform.png)
5
+
4
6
  # Bot Platform (Ruby Version)
5
7
 
6
8
  A ruby based Bot platform to let developers to focus on bot's business logic ONLY. You can connect your bot to channels such as slack, teams, lineworks, chatwork and etc within only a few steps of settings(without coding) to use the same bot's logic. check the [supported bot channels](https://github.com/lifevar/bot-platform/blob/main/docs/channels.md#supported).
@@ -27,20 +29,49 @@ And then execute:
27
29
 
28
30
  Or install it yourself as:
29
31
 
30
- $ gem install bot_platform
32
+ ```bash
33
+ $ gem install bot_platform
34
+ ```
31
35
 
32
36
  ## Usage
33
37
 
34
- $ bin/cli samples/echo.rb
38
+ Documents are under-construction.
39
+
40
+ ## Demos
41
+
42
+ ### CLI
35
43
 
44
+ Clone this repository first. Go to the root directory and run:
36
45
 
37
- or
46
+ ```bash
47
+ bin/cli [bot-script]
48
+ ```
49
+
50
+ echo sample:
51
+
52
+ ```bash
53
+ $ bin/cli samples/echo.rb
54
+ ```
38
55
 
39
- $ bin/cli samples/dialogs/dialog_simple.rb
56
+ simple dialog sample:
57
+
58
+ ```bash
59
+ $ bin/cli samples/dialogs/dialog_simple.rb
60
+ ```
61
+
62
+ waterfall dialog sample:
63
+
64
+ ```bash
65
+ $ bin/cli samples/dialogs/waterfall_dialogs.rb
66
+ ```
67
+
68
+ You can use 'exit' to quit bot shell. You can write your own bot scripts, be careful the file's name should be snake format.(We guess the class name from the file's name)
40
69
 
41
70
  ## Development
42
71
 
43
- We're working on both console bot and Line Works bot nowtime.
72
+ We're working on both console bot and Line Works bot nowtime and has plan to develop to other channels.
73
+
74
+ It's welcome to share your channel's code to us.
44
75
 
45
76
  ## Contributing
46
77
 
Binary file
@@ -34,6 +34,10 @@ module BotPlatform
34
34
  raise "dialog is aready added" if !hash[id.to_sym].nil?
35
35
  end
36
36
 
37
+ def assert_waterfall_step_context_is_valid(ctx)
38
+ raise "Waterfall Step Context is not valid" if ctx.nil? || !(ctx.is_a? Dialogs::WaterfallStepContext)
39
+ end
40
+
37
41
  def assert_activity_is_not_null(activity)
38
42
  raise "activity cannot be null" if activity.nil?
39
43
  end
@@ -52,15 +52,20 @@ module BotPlatform
52
52
  return DialogResult.new :empty
53
53
  end
54
54
 
55
- def stop_dialog(result)
55
+ def stop_dialog(result=nil)
56
+
56
57
  if @dialog_stack.any?
57
58
  @dialog_stack.pop
58
59
  end
59
- dialog = active_dialog
60
+
61
+ instance = active_dialog
60
62
 
61
63
  #previous dialog
62
- if dialog
63
- dialog.resume self
64
+ if !instance.nil?
65
+ dialog = @dialogs.find instance.dialog_id
66
+ if dialog
67
+ return dialog.resume self, DialogReason::END_CALLED, result
68
+ end
64
69
  else
65
70
  return DialogResult.new :complete, result
66
71
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BotPlatform
4
+ module Dialogs
5
+ class DialogReason
6
+ BEGIN_CALLED = 1
7
+ CONTINUE_CALLED = 2
8
+ CANCEL_CALLED = 3
9
+ END_CALLED = 4
10
+ REPLACE_CALLED = 5
11
+ NEXT_CALLED = 6
12
+ end
13
+ end
14
+ end
@@ -7,6 +7,7 @@ module BotPlatform
7
7
  :empty => 0,
8
8
  :complete => 1,
9
9
  :canceled => 2,
10
+ :end_of_turn => 3,
10
11
  }
11
12
 
12
13
  attr_reader :status, :result
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BotPlatform
2
4
  module Dialogs
3
5
  class DialogState
4
6
  attr_accessor :dialog_stack
5
7
 
6
- def initialize
7
- @dialog_stack = []
8
+ def initialize(state = [])
9
+ @dialog_stack = state
8
10
  end
9
11
  end
10
12
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BotPlatform
4
+ module Dialogs
5
+ module Prompts
6
+ class ConfirmPrompt < Prompt
7
+ attr_reader :choice_options, :confirm_choices, :choice_defaults, :default_locale
8
+
9
+ def initialize(dialog_id, validator=nil, default_locale=nil)
10
+ super(dialog_id, validator)
11
+ @default_locale = default_locale
12
+ end
13
+
14
+ def on_prompt(ctx, state, options, is_retry)
15
+ assert_turn_context_is_valid ctx
16
+ #assert_dialog_instance_state_is_valid state
17
+ assert_prompt_options_is_valid options
18
+
19
+ if is_retry && !options.retry_prompt.nil?
20
+ ctx.send_activity options.retry_prompt
21
+ else
22
+ ctx.send_activity options.prompt
23
+ end
24
+
25
+ end
26
+
27
+ def on_recognize(ctx, state, options)
28
+ assert_turn_context_is_valid ctx
29
+
30
+ result = PromptRecognizerResult.new
31
+ if ctx.activity.type == BotPlatform::Activity::TYPES[:message]
32
+ message = ctx.activity.text
33
+ if !message.nil? && !message.empty?
34
+ case message.downcase
35
+ when 'y','yes','yeah', 'ok', 'okay'
36
+ result.succeeded = true
37
+ result.value = true
38
+ else
39
+ result.succeeded = true
40
+ result.value = false
41
+ end
42
+ end
43
+ end
44
+
45
+ return result
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BotPlatform
4
+ module Dialogs
5
+ module Prompts
6
+ class NumberPrompt < Prompt
7
+ attr_reader :default_locale
8
+
9
+ def initialize(dialog_id, validator=nil, default_locale=nil)
10
+ super(dialog_id, validator)
11
+ @default_locale = default_locale
12
+ end
13
+
14
+ def on_prompt(ctx, state, options, is_retry)
15
+ assert_turn_context_is_valid ctx
16
+ #assert_dialog_instance_state_is_valid state
17
+ assert_prompt_options_is_valid options
18
+
19
+ if is_retry && !options.retry_prompt.nil?
20
+ ctx.send_activity options.retry_prompt
21
+ else
22
+ ctx.send_activity options.prompt
23
+ end
24
+ end
25
+
26
+ def on_recognize(ctx, state, options)
27
+ assert_turn_context_is_valid ctx
28
+
29
+ result = PromptRecognizerResult.new
30
+ if ctx.activity.type == BotPlatform::Activity::TYPES[:message]
31
+ message = ctx.activity.text
32
+ if !message.nil? && !message.empty? && message =~ /\A[-+]?[0-9]*\.?[0-9]+\Z/
33
+ result.succeeded = true
34
+ result.value = message.to_i
35
+ end
36
+ end
37
+
38
+ return result
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -20,7 +20,7 @@ module BotPlatform
20
20
  state[:state] = {}
21
21
 
22
22
  on_prompt(dc.turn_context, state[:state], state[:options], false)
23
- return BotPlatform::Dialogs::DialogResult.new :complete
23
+ return BotPlatform::Dialogs::DialogResult.new :end_of_turn
24
24
  end
25
25
 
26
26
  def continue(dc)
@@ -49,15 +49,17 @@ module BotPlatform
49
49
  if is_valid
50
50
  return dc.stop_dialog(recognized.value)
51
51
  else
52
- return on_prompt(dc.turn_context, state, options, true)
52
+ on_prompt(dc.turn_context, state, options, true)
53
53
  end
54
+
55
+ return BotPlatform::Dialogs::DialogResult.new :end_of_turn
54
56
  end
55
57
 
56
58
  def resume(dc, result=null)
57
59
  assert_dialog_context_is_valid dc
58
60
 
59
61
  reprompt(dc.turn_context, dc.active_dialog)
60
- return BotPlatform::Dialogs::DialogResult.new :complete
62
+ return BotPlatform::Dialogs::DialogResult.new :end_of_turn
61
63
  end
62
64
 
63
65
  def repromp(ttx, instance)
@@ -6,6 +6,9 @@ module BotPlatform
6
6
  class PromptOptions
7
7
  attr_accessor :prompt, :retry_prompt, :choices, :validations
8
8
 
9
+ def initialize(prompt:nil)
10
+ @prompt = prompt
11
+ end
9
12
  end
10
13
  end
11
14
  end
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+ require 'logger'
5
+
6
+ module BotPlatform
7
+ module Dialogs
8
+ class WaterfallDialog < Dialog
9
+ include BotPlatform::Asserts
10
+
11
+ LOGLEVELS = %w[DEBUG INFO WARN ERROR FATAL UNKNOWN].freeze
12
+ attr_reader :steps
13
+
14
+ def initialize(dialog_id, actions)
15
+ super(dialog_id)
16
+ @steps = actions.nil? ? [] : actions
17
+ @logger = Logger.new(STDOUT)
18
+
19
+ level ||= LOGLEVELS.index ENV.fetch("BOT_LOG_LEVEL","WARN")
20
+ level ||= Logger::WARN
21
+ @logger.level = level
22
+ end
23
+
24
+ def version
25
+ return "#{@id}:#{@steps.count}"
26
+ end
27
+
28
+ def add_step(step)
29
+ @steps.push step
30
+ return self
31
+ end
32
+
33
+ def start(dc, options=nil)
34
+ assert_dialog_context_is_valid dc
35
+
36
+ state = dc.active_dialog.state
37
+ instance_id = SecureRandom.uuid
38
+
39
+ state[:options] = options
40
+ state[:values] = {}
41
+ state[:instace_id] = instance_id
42
+
43
+ # first step
44
+ run_step(dc, 0, DialogReason::BEGIN_CALLED, nil)
45
+ end
46
+
47
+ def continue(dc)
48
+ @logger.debug "continue dc:#{dc.inspect}"
49
+ assert_dialog_context_is_valid dc
50
+
51
+ if dc.turn_context.activity.type != Activity::TYPES[:message]
52
+ return DialogResult.new :complete
53
+ end
54
+
55
+ return resume(dc, DialogReason::CONTINUE_CALLED, dc.turn_context.activity.text)
56
+ end
57
+
58
+ def resume(dc, reason, result)
59
+ assert_dialog_context_is_valid dc
60
+
61
+ state = dc.active_dialog.state
62
+
63
+ index = state[:step_index]
64
+ run_step(dc, index+1, reason, result)
65
+ end
66
+
67
+ def stop(turn_ctx, instance, reason)
68
+ assert_turn_context_is_valid turn_ctx
69
+ assert_dialog_instance_is_valid instance
70
+ assert_dialog_reason_is_valid reason
71
+
72
+ if reason == DialogReason::CANCEL_CALLED
73
+ state = instance.state.dup
74
+ index = state[:step_index]
75
+ step_name = waterfall_step_name(index)
76
+ instance_id = state[:instance_id]
77
+
78
+ logger.debug {dialog_id:@id, step_name:step_name, instance_id:instance_id}.to_json
79
+ elsif reason == DialogReason::END_CALLED
80
+ state = instance.state.dup
81
+ index = state[:step_index]
82
+ instance_id = state[:instance_id]
83
+
84
+ logger.debug {dialog_id:@id, instance_id:instance_id}.to_json
85
+ end
86
+
87
+ end
88
+
89
+ def on_step(step_ctx)
90
+ step_name = waterfall_step_name(step_ctx.index)
91
+ instance_id = step_ctx.active_dialog.state[:instance_id]
92
+ return @steps[step_ctx.index][:method].call step_ctx
93
+ end
94
+
95
+ def run_step(dc, index, reason, result)
96
+ assert_dialog_context_is_valid dc
97
+
98
+ if index < @steps.count
99
+ state = dc.active_dialog.state
100
+ state[:step_index] = index
101
+
102
+ options = state[:options]
103
+ values = state[:values]
104
+ step_context = WaterfallStepContext.new self, dc, options, values, index, reason, result
105
+
106
+ return on_step(step_context)
107
+ end
108
+
109
+ return dc.end_dialog(result)
110
+ end
111
+
112
+ def waterfall_step_name(index)
113
+ step_name = @steps[index][:name]
114
+
115
+ if step_name.nil? || step_name.empty? || step_name.include?("<")
116
+ step_name = "Step#{index+1}of#{@steps.count}"
117
+ end
118
+
119
+ step_name
120
+ end
121
+
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BotPlatform
4
+ module Dialogs
5
+ # a delegate class
6
+ class WaterfallStep
7
+
8
+ def initialize(&step)
9
+ @step = step
10
+ end
11
+
12
+ def do_step(step_ctx)
13
+ @step.call step_ctx
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BotPlatform
4
+ module Dialogs
5
+ class WaterfallStepContext < DialogContext
6
+ attr_reader :parent_waterfall_dialog, :index, :options,:result, :reason, :values
7
+ attr_accessor :next_called
8
+
9
+ def initialize(parent, dc, options, values, index, reason, result)
10
+ super(dc.dialogs, dc.turn_context, DialogState.new(dc.dialog_stack))
11
+ @parent_waterfall_dialog = parent
12
+ @next_called = false
13
+ @options = options
14
+ @index = index
15
+ @reason = reason
16
+ @result = result
17
+ @values = values
18
+ end
19
+
20
+ def next(result=nil)
21
+ raise "cannot use next() twice." if @next_called
22
+
23
+ @next_called = true
24
+ return @parent_waterfall_dialog.resume(self, DialogReason::NEXT_CALLED, result)
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -4,12 +4,21 @@ require_relative 'dialogs/dialog_instance'
4
4
  require_relative 'dialogs/dialog_result'
5
5
  require_relative 'dialogs/dialog_set'
6
6
  require_relative 'dialogs/dialog_state'
7
+ require_relative 'dialogs/dialog_reason'
7
8
 
8
9
  require_relative 'dialogs/prompts/prompt'
9
10
  require_relative 'dialogs/prompts/prompt_options'
11
+ require_relative 'dialogs/prompts/confirm_prompt'
12
+ require_relative 'dialogs/prompts/number_prompt'
10
13
  require_relative 'dialogs/prompts/text_prompt'
11
14
  require_relative 'dialogs/prompts/prompt_recognizer_result'
12
15
 
16
+
17
+ require_relative 'dialogs/waterfall_dialog'
18
+ require_relative 'dialogs/waterfall_step'
19
+ require_relative 'dialogs/waterfall_step_context'
20
+
21
+
13
22
  module BotPlatform
14
23
  module Dialogs
15
24
 
@@ -11,6 +11,15 @@ module BotPlatform
11
11
  @service_key = service_key
12
12
  end
13
13
 
14
+ def create_property(key)
15
+ @storage.data[key.to_sym] = {}
16
+ return @storage.data[key.to_sym]
17
+ end
18
+
19
+ def get_property(key)
20
+ return @storage.data[key.to_sym]
21
+ end
22
+
14
23
  def save_changes(turn_context, force=false)
15
24
  assert_turn_context_is_valid turn_context
16
25
 
@@ -1 +1,17 @@
1
1
  # frozen_string_literal: true
2
+
3
+ module BotPlatform
4
+ module State
5
+ class UserState < BotState
6
+ def initialize(storage)
7
+ super(storage, "user_state")
8
+ end
9
+
10
+ def get_storage_key(turn_context)
11
+ channel_id = turn_context.activity.channel_id
12
+ user_id = turn_context.from.user_id
13
+ "#{channel_id}/users/#{user_id}"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BotPlatform
4
- VERSION = "0.2.3"
4
+ VERSION = "0.3.0"
5
5
  end
data/lib/bot_platform.rb CHANGED
@@ -12,6 +12,7 @@ require_relative "bot_platform/storage/storageable"
12
12
  require_relative "bot_platform/storage/memory_storage"
13
13
  require_relative "bot_platform/state/bot_state"
14
14
  require_relative "bot_platform/state/conversation_state"
15
+ require_relative "bot_platform/state/user_state"
15
16
 
16
17
  module BotPlatform
17
18
  class Error < StandardError; end
@@ -12,12 +12,13 @@ class DialogSimple
12
12
  def on_turn(ctx)
13
13
  dialog_ctx = @dialogs.create_dialog_context(ctx)
14
14
  results = dialog_ctx.continue_dialog
15
- options = BotPlatform::Dialogs::Prompts::PromptOptions.new
16
- options.prompt = BotPlatform::MessageFactory.Text("Input your name please:")
15
+
17
16
  if results.status == :empty
18
17
  dialog_ctx.prompt(
19
18
  "name",
20
- options
19
+ BotPlatform::Dialogs::Prompts::PromptOptions.new(
20
+ prompt: BotPlatform::MessageFactory.Text("Input your name please:")
21
+ )
21
22
  )
22
23
  elsif results.status == :complete
23
24
  unless results.result.nil?
@@ -0,0 +1,46 @@
1
+ require_relative 'waterfall_steps'
2
+ class WaterfallDialogs
3
+ include Waterfall::Steps
4
+
5
+ attr_accessor :dialogs
6
+
7
+ def initialize
8
+ storage = BotPlatform::Storage::MemoryStorage.instance
9
+ @user_state = BotPlatform::State::UserState.new storage
10
+ profile = @user_state.create_property("user_profile")
11
+ @dialogs = BotPlatform::Dialogs::DialogSet.new
12
+ steps = [
13
+ {name:'request-name', method:->(ctx) { request_name_step(ctx) }},
14
+ {name: 'confirm_asking_age_step', method:->(ctx) { confirm_asking_age_step(ctx, profile) }},
15
+ {name: 'request_age_step', method:->(ctx) { request_age_step(ctx) }},
16
+ {name: 'confirm_register_step', method: ->(ctx) { confirm_register_step(ctx, profile) }},
17
+ {name: 'summary', method: ->(ctx) { summary_step(ctx) }},
18
+ ]
19
+ @dialogs.add BotPlatform::Dialogs::WaterfallDialog.new("profile", steps)
20
+ @dialogs.add BotPlatform::Dialogs::Prompts::TextPrompt.new("name")
21
+ @dialogs.add BotPlatform::Dialogs::Prompts::NumberPrompt.new("age")
22
+ @dialogs.add BotPlatform::Dialogs::Prompts::ConfirmPrompt.new("confirm")
23
+
24
+ @conversation_state = BotPlatform::State::ConversationState.new storage
25
+ end
26
+
27
+ def on_turn(ctx)
28
+ if ctx.activity.type == BotPlatform::Activity::TYPES[:message]
29
+ dialog_ctx = @dialogs.create_dialog_context(ctx)
30
+
31
+ # run continue is there're some existed dialogs
32
+ results = dialog_ctx.continue_dialog
33
+
34
+ # there's no existed dialog
35
+ if results.status == :empty
36
+ dialog_ctx.start_dialog "profile", nil
37
+ elsif results.status == :complete
38
+ user_profile = @user_state.get_property(:user_profile)
39
+ end
40
+
41
+ # save user_profile and dialog_state
42
+ @user_state.save_changes(ctx, false)
43
+ @conversation_state.save_changes(ctx, false)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,50 @@
1
+ module Waterfall
2
+ module Steps
3
+ def request_name_step(step_ctx)
4
+ return step_ctx.prompt(
5
+ "name",
6
+ BotPlatform::Dialogs::Prompts::PromptOptions.new(
7
+ prompt:BotPlatform::MessageFactory.Text("Input your name please.")
8
+ )
9
+ )
10
+ end
11
+
12
+ def confirm_asking_age_step(step_ctx, user_profile)
13
+ profile = user_profile
14
+ profile[:name] = step_ctx.result
15
+ return step_ctx.prompt(
16
+ "confirm",
17
+ BotPlatform::Dialogs::Prompts::PromptOptions.new(
18
+ prompt:BotPlatform::MessageFactory.Text("May I ask your age?")
19
+ )
20
+ )
21
+ end
22
+
23
+ def request_age_step(step_ctx)
24
+ if step_ctx.result
25
+ step_ctx.prompt("age", BotPlatform::Dialogs::Prompts::PromptOptions.new(prompt:BotPlatform::MessageFactory.Text("Input your age please")))
26
+ else
27
+ step_ctx.next(-1)
28
+ end
29
+ end
30
+
31
+ def confirm_register_step(step_ctx, profile)
32
+ age = step_ctx.result.to_i
33
+
34
+ profile[:age] = '(unknown)'
35
+ profile[:age] = age if age != -1
36
+
37
+ prompt = "Register user profile as below. Is it okay?\n Name:#{profile[:name]}\n Age: #{profile[:age]}"
38
+ step_ctx.prompt("confirm", BotPlatform::Dialogs::Prompts::PromptOptions.new(prompt:BotPlatform::MessageFactory.Text(prompt)))
39
+ end
40
+
41
+ def summary_step(step_ctx)
42
+ if step_ctx.result
43
+ step_ctx.turn_context.send_message "Profile saved."
44
+ else
45
+ step_ctx.turn_context.send_message "Profile registration has been canceled."
46
+ end
47
+ step_ctx.stop_dialog
48
+ end
49
+ end
50
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bot_platform
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ningfeng Yang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-05 00:00:00.000000000 Z
11
+ date: 2021-09-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: One bot, multiple channels supported
14
14
  email:
@@ -41,6 +41,7 @@ files:
41
41
  - bot_platform.gemspec
42
42
  - docs/channels.md
43
43
  - exe/welcome
44
+ - images/bot-platform.png
44
45
  - lib/bot_platform.rb
45
46
  - lib/bot_platform/activity.rb
46
47
  - lib/bot_platform/adapter.rb
@@ -65,13 +66,19 @@ files:
65
66
  - lib/bot_platform/dialogs/dialog.rb
66
67
  - lib/bot_platform/dialogs/dialog_context.rb
67
68
  - lib/bot_platform/dialogs/dialog_instance.rb
69
+ - lib/bot_platform/dialogs/dialog_reason.rb
68
70
  - lib/bot_platform/dialogs/dialog_result.rb
69
71
  - lib/bot_platform/dialogs/dialog_set.rb
70
72
  - lib/bot_platform/dialogs/dialog_state.rb
73
+ - lib/bot_platform/dialogs/prompts/confirm_prompt.rb
74
+ - lib/bot_platform/dialogs/prompts/number_prompt.rb
71
75
  - lib/bot_platform/dialogs/prompts/prompt.rb
72
76
  - lib/bot_platform/dialogs/prompts/prompt_options.rb
73
77
  - lib/bot_platform/dialogs/prompts/prompt_recognizer_result.rb
74
78
  - lib/bot_platform/dialogs/prompts/text_prompt.rb
79
+ - lib/bot_platform/dialogs/waterfall_dialog.rb
80
+ - lib/bot_platform/dialogs/waterfall_step.rb
81
+ - lib/bot_platform/dialogs/waterfall_step_context.rb
75
82
  - lib/bot_platform/message_factory.rb
76
83
  - lib/bot_platform/state/bot_state.rb
77
84
  - lib/bot_platform/state/conversation_state.rb
@@ -83,6 +90,8 @@ files:
83
90
  - lib/bot_platform/turn_context.rb
84
91
  - lib/bot_platform/version.rb
85
92
  - samples/dialogs/dialog_simple.rb
93
+ - samples/dialogs/waterfall_dialogs.rb
94
+ - samples/dialogs/waterfall_steps.rb
86
95
  - samples/echo.rb
87
96
  homepage: https://github.com/lifevar/bot-platform
88
97
  licenses: