socrates 0.1.15 → 0.1.16
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 +4 -4
- data/.ruby-version +1 -1
- data/lib/socrates/adapters/console.rb +23 -11
- data/lib/socrates/adapters/memory.rb +20 -6
- data/lib/socrates/adapters/slack.rb +31 -18
- data/lib/socrates/core/dispatcher.rb +31 -21
- data/lib/socrates/core/session.rb +16 -0
- data/lib/socrates/core/state.rb +9 -9
- data/lib/socrates/core/state_data.rb +4 -0
- data/lib/socrates/sample_states.rb +2 -2
- data/lib/socrates/version.rb +1 -1
- data/socrates.gemspec +9 -11
- metadata +22 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8a04c124dd3cd0a515b6f101904fd6484138f29
|
4
|
+
data.tar.gz: 58980557833fa80594c337a98208d06645a696a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b271fadac73d6cd4f5f41d5971ef266d86e3a2302b25860c043aa0287a09cdc5d426949c21a5de12a7aeb54652aec88b38a2bd98283fc5ff75563e805e9bb527
|
7
|
+
data.tar.gz: 389636e1706c447bc54da299a3409d2990c73085463b56db0154b7967f97079eedcce40570fd8c6ef0f7908283d51e6c75ca5ceb20131f79845ade905ab5ddb2
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.4.
|
1
|
+
2.4.2
|
@@ -25,29 +25,41 @@ module Socrates
|
|
25
25
|
CHANNEL
|
26
26
|
end
|
27
27
|
|
28
|
-
def send_message(message,
|
29
|
-
raise ArgumentError, "Channel is required" unless channel.present?
|
28
|
+
def send_message(session, message, send_now: false)
|
29
|
+
raise ArgumentError, "Channel is required" unless session.channel.present?
|
30
30
|
|
31
|
-
|
31
|
+
session.messages[session.channel] << message
|
32
|
+
flush_session(session, channel: session.channel) if send_now
|
32
33
|
end
|
33
34
|
|
34
|
-
def send_direct_message(message,
|
35
|
-
raise ArgumentError, "User is required" unless
|
35
|
+
def send_direct_message(session, message, recipient)
|
36
|
+
raise ArgumentError, "User is required" unless recipient.present?
|
36
37
|
|
37
38
|
name =
|
38
|
-
if
|
39
|
-
|
40
|
-
elsif
|
41
|
-
|
39
|
+
if recipient.respond_to?(:name)
|
40
|
+
recipient.name
|
41
|
+
elsif recipient.respond_to?(:id)
|
42
|
+
recipient.id
|
42
43
|
else
|
43
|
-
|
44
|
+
recipient
|
44
45
|
end
|
45
46
|
|
46
|
-
|
47
|
+
session.messages[name] << message
|
48
|
+
end
|
49
|
+
|
50
|
+
def flush_session(session, channel: nil) # TODO: Dry this up? Session? Included module?
|
51
|
+
session.messages.select { |c, _| channel.nil? || channel == c }.each do |c, messages|
|
52
|
+
_send_message(c, messages.join("\n\n"))
|
53
|
+
messages.clear
|
54
|
+
end
|
47
55
|
end
|
48
56
|
|
49
57
|
private
|
50
58
|
|
59
|
+
def _send_message(channel, message) # TODO: Underscored name?
|
60
|
+
puts "\n#{colorize(channel, "34;1")}: #{message}"
|
61
|
+
end
|
62
|
+
|
51
63
|
def colorize(str, color_code)
|
52
64
|
"\e[#{color_code}m#{str}\e[0m"
|
53
65
|
end
|
@@ -28,16 +28,26 @@ module Socrates
|
|
28
28
|
user.nil? ? CHANNEL : users_channel(user)
|
29
29
|
end
|
30
30
|
|
31
|
-
def send_message(message,
|
32
|
-
raise ArgumentError, "Channel is required" unless channel.present?
|
31
|
+
def send_message(session, message, send_now: false)
|
32
|
+
raise ArgumentError, "Channel is required" unless session.channel.present?
|
33
33
|
|
34
|
-
|
34
|
+
session.messages[session.channel] << message
|
35
|
+
flush_session(session, channel: session.channel) if send_now
|
35
36
|
end
|
36
37
|
|
37
|
-
def send_direct_message(message,
|
38
|
-
raise ArgumentError, "
|
38
|
+
def send_direct_message(session, message, recipient)
|
39
|
+
raise ArgumentError, "Recipient is required" unless recipient.present?
|
40
|
+
|
41
|
+
im_channel = users_channel(recipient)
|
42
|
+
|
43
|
+
session.messages[im_channel] << message
|
44
|
+
end
|
39
45
|
|
40
|
-
|
46
|
+
def flush_session(session, channel: nil) # TODO: Dry this up? Session? Included module?
|
47
|
+
session.messages.select { |c, _| channel.nil? || channel == c }.each do |c, messages|
|
48
|
+
_send_message(c, messages.join("\n\n"))
|
49
|
+
messages.clear
|
50
|
+
end
|
41
51
|
end
|
42
52
|
|
43
53
|
#
|
@@ -62,6 +72,10 @@ module Socrates
|
|
62
72
|
|
63
73
|
private
|
64
74
|
|
75
|
+
def _send_message(channel, message) # TODO: Underscored name?
|
76
|
+
@history[channel] << message
|
77
|
+
end
|
78
|
+
|
65
79
|
def users_channel(user)
|
66
80
|
user.respond_to?(:id) ? user.id : user
|
67
81
|
end
|
@@ -9,47 +9,56 @@ module Socrates
|
|
9
9
|
|
10
10
|
def client_id_from(context: nil, user: nil)
|
11
11
|
unless context.nil?
|
12
|
-
raise ArgumentError, "Expected
|
12
|
+
raise ArgumentError, "Expected context to respond to :user" unless context.respond_to?(:user)
|
13
13
|
return context.user
|
14
14
|
end
|
15
15
|
unless user.nil?
|
16
|
-
raise ArgumentError, "Expected
|
16
|
+
raise ArgumentError, "Expected user to respond to :id" unless user.respond_to?(:id)
|
17
17
|
return user.id
|
18
18
|
end
|
19
|
-
raise ArgumentError, "Must provide one of
|
19
|
+
raise ArgumentError, "Must provide one of context or user"
|
20
20
|
end
|
21
21
|
|
22
22
|
def channel_from(context: nil, user: nil)
|
23
23
|
unless context.nil?
|
24
|
-
raise ArgumentError, "Expected
|
24
|
+
raise ArgumentError, "Expected context to respond to :channel" unless context.respond_to?(:channel)
|
25
25
|
return context.channel
|
26
26
|
end
|
27
|
-
unless user.nil?
|
28
|
-
|
29
|
-
|
30
|
-
end
|
31
|
-
raise ArgumentError, "Must provide one of :context or :user"
|
27
|
+
return lookup_im_channel(user) unless user.nil?
|
28
|
+
|
29
|
+
raise ArgumentError, "Must provide one of context or user"
|
32
30
|
end
|
33
31
|
|
34
32
|
def user_from(context:)
|
35
|
-
raise ArgumentError, "
|
36
|
-
raise ArgumentError, "Expected
|
33
|
+
raise ArgumentError, "context cannot be nil" if context.nil?
|
34
|
+
raise ArgumentError, "Expected context to respond to :user" unless context.respond_to?(:user)
|
37
35
|
|
38
36
|
client = @real_time_client.web_client
|
39
37
|
info = client.users_info(user: context.user)
|
40
38
|
info.present? ? info.user : nil
|
41
39
|
end
|
42
40
|
|
43
|
-
def send_message(message,
|
44
|
-
|
41
|
+
def send_message(session, message, send_now: false)
|
42
|
+
raise ArgumentError, "session is required" unless session.present?
|
43
|
+
raise ArgumentError, "session.channel is required" unless session.channel.present?
|
44
|
+
|
45
|
+
session.messages[session.channel] << message
|
46
|
+
flush_session(session, channel: session.channel) if send_now
|
45
47
|
end
|
46
48
|
|
47
|
-
def send_direct_message(message,
|
48
|
-
raise ArgumentError, "Expected
|
49
|
+
def send_direct_message(session, message, recipient)
|
50
|
+
raise ArgumentError, "Expected recipient to respond to :id" unless recipient.respond_to?(:id)
|
49
51
|
|
50
|
-
im_channel = lookup_im_channel(
|
52
|
+
im_channel = lookup_im_channel(recipient)
|
51
53
|
|
52
|
-
|
54
|
+
session.messages[im_channel] << message
|
55
|
+
end
|
56
|
+
|
57
|
+
def flush_session(session, channel: nil) # TODO: Dry this up? Session? Included module?
|
58
|
+
session.messages.select { |c, _| channel.nil? || channel == c }.each do |c, messages|
|
59
|
+
_send_message(c, messages.join("\n\n"))
|
60
|
+
messages.clear
|
61
|
+
end
|
53
62
|
end
|
54
63
|
|
55
64
|
def users_list(include_deleted: false, include_bots: false)
|
@@ -67,7 +76,7 @@ module Socrates
|
|
67
76
|
end
|
68
77
|
|
69
78
|
def lookup_email(context:)
|
70
|
-
raise ArgumentError, "Expected
|
79
|
+
raise ArgumentError, "Expected context to respond to :user" unless context.respond_to?(:user)
|
71
80
|
|
72
81
|
client = @real_time_client.web_client
|
73
82
|
info = client.users_info(user: context.user)
|
@@ -76,6 +85,10 @@ module Socrates
|
|
76
85
|
|
77
86
|
private
|
78
87
|
|
88
|
+
def _send_message(channel, message) # TODO: Underscored name?
|
89
|
+
@real_time_client.message(text: message, channel: channel)
|
90
|
+
end
|
91
|
+
|
79
92
|
def lookup_im_channel(user)
|
80
93
|
im = @real_time_client.ims.values.find { |i| i.user == user }
|
81
94
|
|
@@ -5,6 +5,7 @@ require "socrates/configuration"
|
|
5
5
|
require "socrates/logger"
|
6
6
|
require "socrates/string_helpers"
|
7
7
|
require "socrates/storage/memory"
|
8
|
+
require "socrates/core/session"
|
8
9
|
require "socrates/core/state"
|
9
10
|
require "socrates/core/state_data"
|
10
11
|
|
@@ -25,25 +26,30 @@ module Socrates
|
|
25
26
|
channel = @adapter.channel_from(context: context)
|
26
27
|
user = @adapter.user_from(context: context)
|
27
28
|
|
28
|
-
|
29
|
+
session = Session.new(client_id: client_id, channel: channel, user: user)
|
30
|
+
|
31
|
+
do_dispatch(session, message)
|
29
32
|
end
|
30
33
|
|
31
34
|
def start_conversation(user, state_id, message: nil)
|
32
35
|
client_id = @adapter.client_id_from(user: user)
|
33
36
|
channel = @adapter.channel_from(user: user)
|
34
37
|
|
38
|
+
session = Session.new(client_id: client_id, channel: channel, user: user)
|
39
|
+
|
35
40
|
# Now, we assume the user of this code does this check on their own...
|
36
41
|
# return false unless conversation_state(user).nil?
|
37
42
|
|
38
43
|
# Create state data to match the request.
|
39
44
|
state_data = Socrates::Core::StateData.new(state_id: state_id, state_action: :ask)
|
40
45
|
|
41
|
-
persist_state_data(client_id, state_data)
|
46
|
+
persist_state_data(session.client_id, state_data)
|
42
47
|
|
43
48
|
# Send our initial message if one was passed to us.
|
44
|
-
@adapter.send_direct_message(message, user) if message.present?
|
49
|
+
@adapter.send_direct_message(session, message, user) if message.present?
|
45
50
|
|
46
|
-
do_dispatch(
|
51
|
+
do_dispatch(session, nil)
|
52
|
+
true
|
47
53
|
end
|
48
54
|
|
49
55
|
def conversation_state(user)
|
@@ -55,7 +61,7 @@ module Socrates
|
|
55
61
|
snapshot = @storage.get(client_id)
|
56
62
|
state_data = StateData.deserialize(snapshot)
|
57
63
|
state_data = nil if state_data.expired? || state_data.finished?
|
58
|
-
rescue => e
|
64
|
+
rescue StandardError => e
|
59
65
|
@logger.warn "Error while fetching state_data for client id '#{client_id}'."
|
60
66
|
@logger.warn e
|
61
67
|
state_data = nil
|
@@ -68,28 +74,29 @@ module Socrates
|
|
68
74
|
|
69
75
|
DEFAULT_ERROR_MESSAGE = "Sorry, an error occurred. We'll have to start over..."
|
70
76
|
|
71
|
-
|
77
|
+
# rubocop:disable Metrics/AbcSize
|
78
|
+
def do_dispatch(session, message)
|
72
79
|
message = message&.strip
|
73
80
|
|
74
|
-
@logger.info %Q(#{client_id} recv: "#{message}")
|
81
|
+
@logger.info %Q(#{session.client_id} recv: "#{message}")
|
75
82
|
|
76
83
|
# In many cases, a two actions will run in this loop: :listen => :ask, but it's possible that a chain of 2 or
|
77
84
|
# more :ask actions could run, before stopping at a :listen (and waiting for the next input).
|
78
85
|
loop do
|
79
|
-
state_data = fetch_state_data(client_id)
|
80
|
-
state = instantiate_state(
|
86
|
+
state_data = fetch_state_data(session.client_id)
|
87
|
+
state = instantiate_state(session, state_data)
|
81
88
|
|
82
89
|
args = [state.data.state_action]
|
83
90
|
args << message if state.data.state_action == :listen
|
84
91
|
|
85
|
-
msg = "#{client_id} processing :#{state.data.state_id} / :#{args.first}"
|
92
|
+
msg = "#{session.client_id} processing :#{state.data.state_id} / :#{args.first}"
|
86
93
|
msg += %Q( / message: "#{args.second}") if args.count > 1
|
87
94
|
@logger.debug msg
|
88
95
|
|
89
96
|
begin
|
90
97
|
state.send(*args)
|
91
|
-
rescue => e
|
92
|
-
handle_action_error(e,
|
98
|
+
rescue StandardError => e
|
99
|
+
handle_action_error(e, session, state)
|
93
100
|
return
|
94
101
|
end
|
95
102
|
|
@@ -97,15 +104,17 @@ module Socrates
|
|
97
104
|
state.data.state_id = state.next_state_id
|
98
105
|
state.data.state_action = state.next_state_action
|
99
106
|
|
100
|
-
@logger.debug "#{client_id} transition to :#{state.data.state_id} / :#{state.data.state_action}"
|
107
|
+
@logger.debug "#{session.client_id} transition to :#{state.data.state_id} / :#{state.data.state_action}"
|
101
108
|
|
102
|
-
persist_state_data(client_id, state.data)
|
109
|
+
persist_state_data(session.client_id, state.data)
|
103
110
|
|
104
111
|
# Break from the loop if there's nothing left to do, i.e. no more state transitions.
|
105
112
|
break if done_transitioning?(state)
|
106
113
|
end
|
114
|
+
# rubocop:enable Metrics/AbcSize
|
107
115
|
|
108
|
-
|
116
|
+
# Flush the session, which contains any not-yet-send messages.
|
117
|
+
@adapter.flush_session(session)
|
109
118
|
end
|
110
119
|
|
111
120
|
# rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
@@ -114,7 +123,7 @@ module Socrates
|
|
114
123
|
begin
|
115
124
|
snapshot = @storage.get(client_id)
|
116
125
|
state_data = StateData.deserialize(snapshot)
|
117
|
-
rescue => e
|
126
|
+
rescue StandardError => e
|
118
127
|
@logger.warn "Error while fetching state_data for client id '#{client_id}', resetting state: #{e.message}"
|
119
128
|
@logger.warn e
|
120
129
|
end
|
@@ -147,8 +156,8 @@ module Socrates
|
|
147
156
|
@storage.put(client_id, state_data.serialize)
|
148
157
|
end
|
149
158
|
|
150
|
-
def instantiate_state(
|
151
|
-
@state_factory.build(state_data: state_data, adapter: @adapter,
|
159
|
+
def instantiate_state(session, state_data)
|
160
|
+
@state_factory.build(state_data: state_data, adapter: @adapter, session: session)
|
152
161
|
end
|
153
162
|
|
154
163
|
def done_transitioning?(state)
|
@@ -159,16 +168,17 @@ module Socrates
|
|
159
168
|
state.data.state_id.nil? || state.data.state_id == StateData::END_OF_CONVERSATION
|
160
169
|
end
|
161
170
|
|
162
|
-
def handle_action_error(e,
|
171
|
+
def handle_action_error(e, session, state)
|
163
172
|
@logger.warn "Error while processing action #{state.data.state_id}/#{state.data.state_action}: #{e.message}"
|
164
173
|
@logger.warn e
|
165
174
|
|
166
|
-
@adapter.send_message(@error_message,
|
175
|
+
@adapter.send_message(session, @error_message, send_now: true)
|
176
|
+
|
167
177
|
state.data.clear
|
168
178
|
state.data.state_id = nil
|
169
179
|
state.data.state_action = nil
|
170
180
|
|
171
|
-
persist_state_data(client_id, state.data)
|
181
|
+
persist_state_data(session.client_id, state.data)
|
172
182
|
end
|
173
183
|
end
|
174
184
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "socrates/configuration"
|
2
|
+
|
3
|
+
module Socrates
|
4
|
+
module Core
|
5
|
+
class Session
|
6
|
+
attr_accessor :client_id, :user, :channel, :messages
|
7
|
+
|
8
|
+
def initialize(client_id: nil, user: nil, channel: nil)
|
9
|
+
@client_id = client_id
|
10
|
+
@user = user
|
11
|
+
@channel = channel
|
12
|
+
@messages = Hash.new { |hash, key| hash[key] = [] }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/socrates/core/state.rb
CHANGED
@@ -9,13 +9,13 @@ require "socrates/core/state_data"
|
|
9
9
|
module Socrates
|
10
10
|
module Core
|
11
11
|
module State
|
12
|
-
attr_reader :data, :adapter, :
|
12
|
+
attr_reader :data, :adapter, :session, :user
|
13
13
|
|
14
|
-
def initialize(data: StateData.new, adapter:,
|
14
|
+
def initialize(data: StateData.new, adapter:, session:)
|
15
15
|
@data = data
|
16
16
|
@adapter = adapter
|
17
|
-
@
|
18
|
-
@user = user
|
17
|
+
@session = session
|
18
|
+
@user = session.user
|
19
19
|
@next_state_id = nil
|
20
20
|
@next_state_action = nil
|
21
21
|
@logger = Socrates.config.logger || Socrates::Logger.default
|
@@ -37,7 +37,7 @@ module Socrates
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
def respond(message: nil, template: nil)
|
40
|
+
def respond(message: nil, template: nil, send_now: false)
|
41
41
|
if template
|
42
42
|
# TODO: Partials?
|
43
43
|
filename = File.join(Socrates.config.view_path, template)
|
@@ -47,15 +47,15 @@ module Socrates
|
|
47
47
|
|
48
48
|
return if message.empty?
|
49
49
|
|
50
|
-
@logger.info %Q(#{@channel} send: "#{format_for_logging(message)}")
|
51
|
-
@adapter.send_message(message,
|
50
|
+
@logger.info %Q(#{@session.channel} send: "#{format_for_logging(message)}")
|
51
|
+
@adapter.send_message(@session, message, send_now: send_now)
|
52
52
|
end
|
53
53
|
|
54
54
|
def send_message(to:, message:)
|
55
55
|
displayable_to = to.respond_to?(:id) ? to.id : to
|
56
56
|
|
57
|
-
@logger.info %Q(#{@channel} send direct to #{displayable_to}: "#{format_for_logging(message)}")
|
58
|
-
@adapter.send_direct_message(message, to)
|
57
|
+
@logger.info %Q(#{@session.channel} send direct to #{displayable_to}: "#{format_for_logging(message)}")
|
58
|
+
@adapter.send_direct_message(@session, message, to)
|
59
59
|
end
|
60
60
|
|
61
61
|
def transition_to(state_id, action: nil, data: {})
|
@@ -14,11 +14,11 @@ module Socrates
|
|
14
14
|
:expired
|
15
15
|
end
|
16
16
|
|
17
|
-
def build(state_data:, adapter:,
|
17
|
+
def build(state_data:, adapter:, session:)
|
18
18
|
classname = StringHelpers.underscore_to_classname(state_data.state_id)
|
19
19
|
|
20
20
|
Object.const_get("Socrates::SampleStates::#{classname}")
|
21
|
-
.new(data: state_data, adapter: adapter,
|
21
|
+
.new(data: state_data, adapter: adapter, session: session)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
data/lib/socrates/version.rb
CHANGED
data/socrates.gemspec
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
1
|
lib = File.expand_path("../lib", __FILE__)
|
4
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
3
|
|
@@ -25,15 +23,15 @@ Gem::Specification.new do |spec|
|
|
25
23
|
|
26
24
|
spec.required_ruby_version = ">= 2.3.0"
|
27
25
|
|
28
|
-
spec.add_development_dependency "bundler", "~> 1.
|
29
|
-
spec.add_development_dependency "rake", "~>
|
30
|
-
spec.add_development_dependency "rspec", "~> 3.
|
31
|
-
spec.add_development_dependency "rubocop", "~> 0.
|
32
|
-
spec.add_development_dependency "timecop", "~> 0.
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.15"
|
27
|
+
spec.add_development_dependency "rake", "~> 12.1"
|
28
|
+
spec.add_development_dependency "rspec", "~> 3.6"
|
29
|
+
spec.add_development_dependency "rubocop", "~> 0.50.0"
|
30
|
+
spec.add_development_dependency "timecop", "~> 0.9.1"
|
33
31
|
|
34
|
-
spec.add_dependency "activesupport", ">= 5.
|
32
|
+
spec.add_dependency "activesupport", ">= 5.1.4"
|
35
33
|
spec.add_dependency "celluloid-io", ">= 0.17.3"
|
36
|
-
spec.add_dependency "hashie", ">= 3.5.
|
37
|
-
spec.add_dependency "redis", ">=
|
38
|
-
spec.add_dependency "slack-ruby-client", ">= 0.
|
34
|
+
spec.add_dependency "hashie", ">= 3.5.6"
|
35
|
+
spec.add_dependency "redis", ">= 4.0.0"
|
36
|
+
spec.add_dependency "slack-ruby-client", ">= 0.9.1"
|
39
37
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: socrates
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christian Nelson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,84 +16,84 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.15'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.15'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '12.1'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '12.1'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '3.
|
47
|
+
version: '3.6'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '3.
|
54
|
+
version: '3.6'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rubocop
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.
|
61
|
+
version: 0.50.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.
|
68
|
+
version: 0.50.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: timecop
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
75
|
+
version: 0.9.1
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.
|
82
|
+
version: 0.9.1
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: activesupport
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 5.
|
89
|
+
version: 5.1.4
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 5.
|
96
|
+
version: 5.1.4
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: celluloid-io
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,42 +114,42 @@ dependencies:
|
|
114
114
|
requirements:
|
115
115
|
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 3.5.
|
117
|
+
version: 3.5.6
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: 3.5.
|
124
|
+
version: 3.5.6
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: redis
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
129
|
- - ">="
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version:
|
131
|
+
version: 4.0.0
|
132
132
|
type: :runtime
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
138
|
+
version: 4.0.0
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: slack-ruby-client
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
143
|
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: 0.
|
145
|
+
version: 0.9.1
|
146
146
|
type: :runtime
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
150
|
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: 0.
|
152
|
+
version: 0.9.1
|
153
153
|
description:
|
154
154
|
email:
|
155
155
|
- christian@carbonfive.com
|
@@ -178,6 +178,7 @@ files:
|
|
178
178
|
- lib/socrates/bots/slack.rb
|
179
179
|
- lib/socrates/configuration.rb
|
180
180
|
- lib/socrates/core/dispatcher.rb
|
181
|
+
- lib/socrates/core/session.rb
|
181
182
|
- lib/socrates/core/state.rb
|
182
183
|
- lib/socrates/core/state_data.rb
|
183
184
|
- lib/socrates/logger.rb
|
@@ -208,7 +209,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
208
209
|
version: '0'
|
209
210
|
requirements: []
|
210
211
|
rubyforge_project:
|
211
|
-
rubygems_version: 2.6.
|
212
|
+
rubygems_version: 2.6.13
|
212
213
|
signing_key:
|
213
214
|
specification_version: 4
|
214
215
|
summary: A micro-framework for building stateful conversational bots.
|