socrates 0.1.15 → 0.1.16
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|