bot_platform 0.1.0 → 0.2.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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.idea/.gitignore +8 -0
  3. data/.idea/bot_platform.iml +317 -0
  4. data/.idea/misc.xml +4 -0
  5. data/.idea/modules.xml +8 -0
  6. data/.idea/vcs.xml +6 -0
  7. data/.ruby-version +1 -0
  8. data/Gemfile.lock +1 -1
  9. data/LICENSE +21 -0
  10. data/README.md +19 -9
  11. data/bin/cli +34 -0
  12. data/docs/channels.md +7 -0
  13. data/lib/bot_platform/activity.rb +32 -0
  14. data/lib/bot_platform/adapter.rb +87 -0
  15. data/lib/bot_platform/asserts.rb +69 -0
  16. data/lib/bot_platform/boot.rb +12 -0
  17. data/lib/bot_platform/channels/base.rb +26 -0
  18. data/lib/bot_platform/channels/chatwork.rb +1 -0
  19. data/lib/bot_platform/channels/console.rb +60 -0
  20. data/lib/bot_platform/channels/facebook.rb +1 -0
  21. data/lib/bot_platform/channels/line.rb +1 -0
  22. data/lib/bot_platform/channels/lineworks.rb +102 -0
  23. data/lib/bot_platform/channels/skype.rb +1 -0
  24. data/lib/bot_platform/channels/skype_for_business.rb +1 -0
  25. data/lib/bot_platform/channels/slack.rb +15 -0
  26. data/lib/bot_platform/channels/teams.rb +15 -0
  27. data/lib/bot_platform/channels/web.rb +15 -0
  28. data/lib/bot_platform/channels/wechat.rb +1 -0
  29. data/lib/bot_platform/channels.rb +9 -0
  30. data/lib/bot_platform/cli.rb +97 -0
  31. data/lib/bot_platform/conversation_state.rb +32 -0
  32. data/lib/bot_platform/dialogs/dialog.rb +48 -0
  33. data/lib/bot_platform/dialogs/dialog_context.rb +104 -0
  34. data/lib/bot_platform/dialogs/dialog_instance.rb +15 -0
  35. data/lib/bot_platform/dialogs/dialog_result.rb +22 -0
  36. data/lib/bot_platform/dialogs/dialog_set.rb +38 -0
  37. data/lib/bot_platform/dialogs/dialog_state.rb +11 -0
  38. data/lib/bot_platform/dialogs/prompts/prompt.rb +84 -0
  39. data/lib/bot_platform/dialogs/prompts/prompt_options.rb +12 -0
  40. data/lib/bot_platform/dialogs/prompts/prompt_recognizer_result.rb +16 -0
  41. data/lib/bot_platform/dialogs/prompts/text_prompt.rb +36 -0
  42. data/lib/bot_platform/dialogs.rb +17 -0
  43. data/lib/bot_platform/message_factory.rb +9 -0
  44. data/lib/bot_platform/state/bot_state.rb +21 -0
  45. data/lib/bot_platform/state/conversation_state.rb +17 -0
  46. data/lib/bot_platform/state/user_state.rb +1 -0
  47. data/lib/bot_platform/storage/memory_storage.rb +51 -0
  48. data/lib/bot_platform/storage/mysql_storage.rb +1 -0
  49. data/lib/bot_platform/storage/redis_storage.rb +1 -0
  50. data/lib/bot_platform/storage/storageable.rb +33 -0
  51. data/lib/bot_platform/turn_context.rb +105 -0
  52. data/lib/bot_platform/version.rb +1 -1
  53. data/lib/bot_platform.rb +11 -0
  54. data/samples/dialogs/dialog_simple.rb +29 -0
  55. data/samples/echo.rb +5 -0
  56. metadata +52 -2
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BotPlatform
4
+ module Dialogs
5
+ module Prompts
6
+ class PromptOptions
7
+ attr_accessor :prompt, :retry_prompt, :choices, :validations
8
+
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BotPlatform
4
+ module Dialogs
5
+ module Prompts
6
+ class PromptRecognizerResult
7
+ attr_accessor :succeeded, :value
8
+
9
+ def initialize
10
+ @succeeded = false
11
+ @value = nil
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BotPlatform
4
+ module Dialogs
5
+ module Prompts
6
+ class TextPrompt < Prompt
7
+ def on_prompt(ctx, state, options, is_retry)
8
+ assert_turn_context_is_valid ctx
9
+ #assert_dialog_instance_state_is_valid state
10
+ assert_prompt_options_is_valid options
11
+
12
+ if is_retry && !options.retry_prompt.nil?
13
+ ctx.send_activity options.retry_prompt
14
+ else
15
+ ctx.send_activity options.prompt
16
+ end
17
+ end
18
+
19
+ def on_recognize(ctx, state, options)
20
+ assert_turn_context_is_valid ctx
21
+
22
+ result = PromptRecognizerResult.new
23
+ if ctx.activity.type == BotPlatform::Activity::TYPES[:message]
24
+ message = ctx.activity.text
25
+ unless message.nil? || message.empty?
26
+ result.succeeded = true
27
+ result.value = message
28
+ end
29
+ end
30
+
31
+ return result
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'dialogs/dialog'
2
+ require_relative 'dialogs/dialog_context'
3
+ require_relative 'dialogs/dialog_instance'
4
+ require_relative 'dialogs/dialog_result'
5
+ require_relative 'dialogs/dialog_set'
6
+ require_relative 'dialogs/dialog_state'
7
+
8
+ require_relative 'dialogs/prompts/prompt'
9
+ require_relative 'dialogs/prompts/prompt_options'
10
+ require_relative 'dialogs/prompts/text_prompt'
11
+ require_relative 'dialogs/prompts/prompt_recognizer_result'
12
+
13
+ module BotPlatform
14
+ module Dialogs
15
+
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BotPlatform
4
+ class MessageFactory
5
+ def self.Text(text)
6
+ return Activity.new Activity::TYPES[:message], {text: text}
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BotPlatform
4
+ module State
5
+ class BotState
6
+ include BotPlatform::Asserts
7
+
8
+ attr_accessor :storage, :service_key
9
+ def initialize(storage, service_key)
10
+ @storage = storage
11
+ @service_key = service_key
12
+ end
13
+
14
+ def save_changes(turn_context, force=false)
15
+ assert_turn_context_is_valid turn_context
16
+
17
+ #TODO:
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BotPlatform
4
+ module State
5
+ class ConversationState < BotState
6
+ def initialize(storage)
7
+ super(storage, "conversation_state")
8
+ end
9
+
10
+ def get_storage_key(turn_context)
11
+ channel_id = turn_context.activity.channel_id
12
+ conversation_id = turn_context.conversation.id
13
+ "#{channel_id}/conversations/#{conversation_id}"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1 @@
1
+ # frozen_string_literal: true
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'singleton'
4
+
5
+ module BotPlatform
6
+ module Storage
7
+ class MemoryStorage
8
+ include Singleton
9
+ include Storageable
10
+
11
+ attr_accessor :data, :locker
12
+
13
+ def initialize
14
+ @locker = Mutex::new
15
+ @data = {}
16
+ end
17
+
18
+ def read(keys)
19
+ new_hash = {}
20
+ @locker.synchronize do
21
+ keys.each do |key|
22
+ if @data.key?(key)
23
+ k = key.to_sym
24
+ new_hash[k] = @data[k]
25
+ end
26
+ end
27
+ end
28
+ return new_hash
29
+ end
30
+
31
+ def write(changes)
32
+ @locker.synchronize do
33
+ changes.each do |change|
34
+ @data[change.key.to_sym] = change.value
35
+ end
36
+ end
37
+ end
38
+
39
+ def getState(context)
40
+ user_id = context.from[:user_id]
41
+ room_id = context.from[:room_id] || ""
42
+ # FIXME: room_id appear and disappear
43
+ #key = "#{user_id}@#{room_id}"
44
+ key = "#{user_id}".intern
45
+ @data[key] = ConversationState.new(key) if @data[key].nil?
46
+ return @data[key]
47
+ end
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1 @@
1
+ # frozen_string_literal: true
@@ -0,0 +1 @@
1
+ # frozen_string_literal: true
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BotPlatform
4
+ module Storage
5
+ module Storageable
6
+ attr_accessor :data, :_user_state, :coversation_state, :dialog_state
7
+
8
+ def set(key, value, exipred=false)
9
+ end
10
+
11
+ def get(key)
12
+ end
13
+
14
+ def del(key)
15
+ end
16
+
17
+ def read(keys)
18
+ end
19
+
20
+ def write(changes)
21
+ end
22
+
23
+ def user_state
24
+ get(:_user_state)
25
+ end
26
+
27
+ def user_state=(state)
28
+ set(:_user_state, state)
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BotPlatform
4
+ class TurnContext
5
+ include Asserts
6
+
7
+ attr_reader :adpter, #元のアダプター情報
8
+ :activity, # ユーザーからの要求(incoming)
9
+ :channel_id,
10
+ :from
11
+
12
+ attr_accessor :state, #コンテキストに登録されたサービスを保持
13
+ :responded, # 応答済フラグ
14
+ :locale,
15
+ :buffered_reply_activities,
16
+ :turn_state, # コンテキストに登録されたサービスを保持
17
+ :_on_send_activities,
18
+ :_on_update_activities,
19
+ :_on_delete_activities
20
+
21
+ def initialize(adapter, activity)
22
+ @adapter = adapter
23
+ @activity = activity # incoming activity
24
+ @from = activity.from
25
+ @channel_id = activity.channel_id
26
+ @responded = false
27
+ @locale = "ja"
28
+ @_on_send_activities = []
29
+ @_on_update_activities = []
30
+ @_on_delete_activities = []
31
+
32
+ end
33
+
34
+ def add_on_send_activities(activity_handler)
35
+ @_on_send_activities << activity_handler
36
+ self
37
+ end
38
+
39
+ def add_on_update_activities(activity_handler)
40
+ @_on_update_activities << activity_handler
41
+ self
42
+ end
43
+
44
+ def add_on_delete_activits(activity_handler)
45
+ @_on_delete_activities << activity_handler
46
+ self
47
+ end
48
+
49
+ def self.dup_context(context, activity)
50
+ ctx = TurnContext.new context.adapter, activity
51
+ ctx.state = context.state
52
+ ctx.responded = context.responded
53
+ if context.is_a?(TurnContext)
54
+ ctx.buffered_reply_activities = context.buffered_reply_activities
55
+ # keep private middleware pipeline hooks.
56
+ ctx._on_send_activities = context._on_send_activities
57
+ ctx._on_update_activity = context._on_update_activity
58
+ ctx._on_delete_activity = context._on_delete_activity
59
+ end
60
+ return ctx
61
+ end
62
+
63
+ def send_message(text)
64
+ activity_to_send = Activity.new(Activity::TYPES[:message], {text: text})
65
+ send_activity(activity_to_send)
66
+ end
67
+
68
+ def send_confirm(text,prefix="")
69
+ activity_to_send = Activity.new(Activity::TYPES[:confirm], {text: text, prefix: prefix})
70
+ send_activity(activity_to_send)
71
+ end
72
+
73
+ def send_options(caption, prefix, options)
74
+ activity_to_send = Activity.new(Activity::TYPES[:options], {text: caption, options: options, prefix: prefix})
75
+ send_activity(activity_to_send)
76
+ end
77
+
78
+ def send_image(preview_url, resource_url)
79
+ activity_to_send = Activity.new(Activity::TYPES[:image], {resource_url: resource_url, preview_url: preview_url})
80
+ send_activity(activity_to_send)
81
+ end
82
+
83
+ def send_content(content)
84
+ activity_to_send = Activity.new(Activity::TYPES[:carousel], {
85
+ content: content, to: @activity.from
86
+ })
87
+ send_activity(activity_to_send)
88
+ end
89
+
90
+ def send_activity(activity)
91
+ activity.to = @activity.from
92
+ send_activities([activity])
93
+ end
94
+
95
+ # Sends a set of activities to the sender of the incoming activity.
96
+ def send_activities(activities)
97
+ assert_activity_is_not_null activities
98
+ assert_activity_is_not_null activities[0]
99
+
100
+ @adapter.send_activities(self, activities)
101
+ end
102
+
103
+
104
+ end
105
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BotPlatform
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/bot_platform.rb CHANGED
@@ -1,6 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "bot_platform/version"
4
+ require_relative "bot_platform/activity"
5
+ require_relative "bot_platform/adapter"
6
+ require_relative "bot_platform/asserts"
7
+ require_relative "bot_platform/message_factory"
8
+ require_relative "bot_platform/turn_context"
9
+ require_relative "bot_platform/channels"
10
+ require_relative "bot_platform/dialogs"
11
+ require_relative "bot_platform/storage/storageable"
12
+ require_relative "bot_platform/storage/memory_storage"
13
+ require_relative "bot_platform/state/bot_state"
14
+ require_relative "bot_platform/state/conversation_state"
4
15
 
5
16
  module BotPlatform
6
17
  class Error < StandardError; end
@@ -0,0 +1,29 @@
1
+ class DialogSimple
2
+ attr_accessor :dialogs
3
+
4
+ def initialize
5
+ @dialogs = BotPlatform::Dialogs::DialogSet.new
6
+ @dialogs.add(BotPlatform::Dialogs::Prompts::TextPrompt.new("name"))
7
+
8
+ storage = BotPlatform::Storage::MemoryStorage.instance
9
+ @conversation_state = BotPlatform::State::ConversationState.new storage
10
+ end
11
+
12
+ def on_turn(ctx)
13
+ dialog_ctx = @dialogs.create_dialog_context(ctx)
14
+ results = dialog_ctx.continue_dialog
15
+ options = BotPlatform::Dialogs::Prompts::PromptOptions.new
16
+ options.prompt = BotPlatform::MessageFactory.Text("Input your name please:")
17
+ if results.status == :empty
18
+ dialog_ctx.prompt(
19
+ "name",
20
+ options
21
+ )
22
+ elsif results.status == :complete
23
+ unless results.result.nil?
24
+ ctx.send_activity BotPlatform::MessageFactory.Text("Hello! #{results.result}!")
25
+ end
26
+ end
27
+ @conversation_state.save_changes(ctx, false)
28
+ end
29
+ end
data/samples/echo.rb ADDED
@@ -0,0 +1,5 @@
1
+ class Echo
2
+ def on_turn(ctx)
3
+ ctx.send_message "You said: #{ctx.activity.text}"
4
+ end
5
+ 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.1.0
4
+ version: 0.2.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-04 00:00:00.000000000 Z
11
+ date: 2021-09-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: simply write bot codes
14
14
  email:
@@ -20,20 +20,70 @@ extra_rdoc_files: []
20
20
  files:
21
21
  - ".circleci/config.yml"
22
22
  - ".gitignore"
23
+ - ".idea/.gitignore"
24
+ - ".idea/bot_platform.iml"
25
+ - ".idea/misc.xml"
26
+ - ".idea/modules.xml"
27
+ - ".idea/vcs.xml"
23
28
  - ".rspec"
24
29
  - ".rubocop.yml"
30
+ - ".ruby-version"
25
31
  - CHANGELOG.md
26
32
  - CODE_OF_CONDUCT.md
27
33
  - Gemfile
28
34
  - Gemfile.lock
35
+ - LICENSE
29
36
  - README.md
30
37
  - Rakefile
38
+ - bin/cli
31
39
  - bin/console
32
40
  - bin/setup
33
41
  - bot_platform.gemspec
42
+ - docs/channels.md
34
43
  - exe/welcome
35
44
  - lib/bot_platform.rb
45
+ - lib/bot_platform/activity.rb
46
+ - lib/bot_platform/adapter.rb
47
+ - lib/bot_platform/asserts.rb
48
+ - lib/bot_platform/boot.rb
49
+ - lib/bot_platform/channels.rb
50
+ - lib/bot_platform/channels/base.rb
51
+ - lib/bot_platform/channels/chatwork.rb
52
+ - lib/bot_platform/channels/console.rb
53
+ - lib/bot_platform/channels/facebook.rb
54
+ - lib/bot_platform/channels/line.rb
55
+ - lib/bot_platform/channels/lineworks.rb
56
+ - lib/bot_platform/channels/skype.rb
57
+ - lib/bot_platform/channels/skype_for_business.rb
58
+ - lib/bot_platform/channels/slack.rb
59
+ - lib/bot_platform/channels/teams.rb
60
+ - lib/bot_platform/channels/web.rb
61
+ - lib/bot_platform/channels/wechat.rb
62
+ - lib/bot_platform/cli.rb
63
+ - lib/bot_platform/conversation_state.rb
64
+ - lib/bot_platform/dialogs.rb
65
+ - lib/bot_platform/dialogs/dialog.rb
66
+ - lib/bot_platform/dialogs/dialog_context.rb
67
+ - lib/bot_platform/dialogs/dialog_instance.rb
68
+ - lib/bot_platform/dialogs/dialog_result.rb
69
+ - lib/bot_platform/dialogs/dialog_set.rb
70
+ - lib/bot_platform/dialogs/dialog_state.rb
71
+ - lib/bot_platform/dialogs/prompts/prompt.rb
72
+ - lib/bot_platform/dialogs/prompts/prompt_options.rb
73
+ - lib/bot_platform/dialogs/prompts/prompt_recognizer_result.rb
74
+ - lib/bot_platform/dialogs/prompts/text_prompt.rb
75
+ - lib/bot_platform/message_factory.rb
76
+ - lib/bot_platform/state/bot_state.rb
77
+ - lib/bot_platform/state/conversation_state.rb
78
+ - lib/bot_platform/state/user_state.rb
79
+ - lib/bot_platform/storage/memory_storage.rb
80
+ - lib/bot_platform/storage/mysql_storage.rb
81
+ - lib/bot_platform/storage/redis_storage.rb
82
+ - lib/bot_platform/storage/storageable.rb
83
+ - lib/bot_platform/turn_context.rb
36
84
  - lib/bot_platform/version.rb
85
+ - samples/dialogs/dialog_simple.rb
86
+ - samples/echo.rb
37
87
  homepage: https://github.com/lifevar/bot-platform
38
88
  licenses: []
39
89
  metadata: