socrates 0.1.3 → 0.1.4
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/README.md +17 -4
- data/exe/socrates +69 -2
- data/lib/socrates/adapters/slack_adapter.rb +8 -8
- data/lib/socrates/bots/cli_bot.rb +1 -1
- data/lib/socrates/bots/slack_bot.rb +1 -1
- data/lib/socrates/core/dispatcher.rb +1 -1
- data/lib/socrates/sample_states.rb +1 -1
- data/lib/socrates/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c607c420626916f58b95937ab1494db96777de17
|
4
|
+
data.tar.gz: 7a981c8a829195f334488f2bc061d69d925ae9ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27eda804b512cbedcbdc32e90c3375128cc2fa01e6e1721e9ef57043d18fe2aa2fd510a7d5bf966d912c63074d0db6c91d3a5d2264e9746f79d6c5c0a74b9b83
|
7
|
+
data.tar.gz: ef78d69889110102795189a999d75d8d6dca08c61d8b08bec245c8c1867ba516b1c9e0079aef75936575d905e5be5c4d806f9fe9baf4693f4e65f7bfd79d6e5b
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Socrates
|
2
2
|
|
3
|
-
Socrates is a micro-framework for building conversational interfaces. It provides straight-forward state management, a clear pattern for modeling the states and conversational flow (transitions), and some helpers.
|
3
|
+
Socrates is a micro-framework for building stateful conversational interfaces. It provides straight-forward state management, a clear pattern for modeling the states and conversational flow (transitions), and some helpers.
|
4
4
|
|
5
5
|
It's designed for building conversational Slack bots, but is designed in such a way that other adapters could be written. It ships with a Console adapter for testing locally in the terminal as well as a Memory adapter for use in automated tests.
|
6
6
|
|
@@ -19,7 +19,7 @@ class GetStarted
|
|
19
19
|
include Socrates::Core::State
|
20
20
|
|
21
21
|
def listen(message)
|
22
|
-
case message.
|
22
|
+
case message.downcase
|
23
23
|
when "help"
|
24
24
|
transition_to :help
|
25
25
|
when "age"
|
@@ -113,7 +113,7 @@ class CalculateAge
|
|
113
113
|
end
|
114
114
|
|
115
115
|
def calculate_age
|
116
|
-
((Date.today.to_time - birth_date.to_time) /
|
116
|
+
((Date.today.to_time - birth_date.to_time) / 1.year).floor
|
117
117
|
end
|
118
118
|
end
|
119
119
|
```
|
@@ -136,7 +136,20 @@ Or install it yourself as:
|
|
136
136
|
|
137
137
|
## Usage
|
138
138
|
|
139
|
-
|
139
|
+
Socrates is intended to be used programmatically from your application.
|
140
|
+
|
141
|
+
However, it's easy to see a sample conversation run in either the console or on Slack.
|
142
|
+
|
143
|
+
To see socrates in action in the console:
|
144
|
+
|
145
|
+
$ socrates run
|
146
|
+
|
147
|
+
And on Slack:
|
148
|
+
|
149
|
+
$ SLACK_API_TOKEN=<your token> socrates -a slack run
|
150
|
+
|
151
|
+
Use `-s redis` to store state in Redis instead of memory. The key difference is that state will survive exiting and
|
152
|
+
restarting the bot. Use the `-d` flag for debugging log information.
|
140
153
|
|
141
154
|
## Core Concepts
|
142
155
|
|
data/exe/socrates
CHANGED
@@ -4,9 +4,76 @@ File.expand_path("../../lib", __FILE__).tap do |lib|
|
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
5
|
end
|
6
6
|
|
7
|
+
require "optparse"
|
8
|
+
|
7
9
|
require "socrates"
|
8
10
|
require "socrates/sample_states"
|
9
11
|
|
10
|
-
|
12
|
+
options = {
|
13
|
+
adapter: "console",
|
14
|
+
storage: "memory",
|
15
|
+
debug: false
|
16
|
+
}
|
17
|
+
|
18
|
+
option_parser = OptionParser.new do |parser|
|
19
|
+
parser.banner = "Usage: socrates [options] run"
|
20
|
+
|
21
|
+
parser.on("-h", "--help", "Show this help message") do
|
22
|
+
puts parser
|
23
|
+
exit
|
24
|
+
end
|
25
|
+
parser.on("-a", "--adapter ADAPTER", "Use the specified Adapter: console (default) or slack") do |value|
|
26
|
+
options[:adapter] = value.downcase
|
27
|
+
end
|
28
|
+
parser.on("-s", "--storage STORAGE", "Use the specified Storage: memory (default) or redis") do |value|
|
29
|
+
options[:storage] = value.downcase
|
30
|
+
end
|
31
|
+
parser.on("-d", "--debug", "Print detailed logging") do
|
32
|
+
options[:debug] = true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
option_parser.parse!
|
36
|
+
|
37
|
+
def run_command(options)
|
38
|
+
storage =
|
39
|
+
case options[:storage]
|
40
|
+
when "redis"
|
41
|
+
Socrates::Storage::RedisStorage.new(url: ENV.fetch("REDIS_URL", "redis://localhost"))
|
42
|
+
else
|
43
|
+
Socrates::Storage::MemoryStorage.new
|
44
|
+
end
|
45
|
+
|
46
|
+
Socrates.configure do |config|
|
47
|
+
config.storage = storage
|
48
|
+
|
49
|
+
if options[:debug]
|
50
|
+
config.logger = Socrates::Logger.default
|
51
|
+
config.logger.level = Logger::DEBUG
|
52
|
+
end
|
53
|
+
end
|
11
54
|
|
12
|
-
|
55
|
+
case (adapter = options[:adapter])
|
56
|
+
when "console"
|
57
|
+
Socrates::Bots::CLIBot.new(state_factory: Socrates::SampleStates::StateFactory.new).start
|
58
|
+
when "slack"
|
59
|
+
Socrates::Bots::SlackBot.new(state_factory: Socrates::SampleStates::StateFactory.new).start
|
60
|
+
else
|
61
|
+
puts "Unknown adapter '#{adapter}'"
|
62
|
+
exit 1
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
command = ARGV.shift
|
67
|
+
|
68
|
+
if command.nil?
|
69
|
+
puts option_parser.help
|
70
|
+
exit 1
|
71
|
+
end
|
72
|
+
|
73
|
+
case command.downcase
|
74
|
+
when "run"
|
75
|
+
run_command(options)
|
76
|
+
else
|
77
|
+
puts "Unknown command '#{command}'"
|
78
|
+
exit 1
|
79
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Socrates
|
2
2
|
module Adapters
|
3
3
|
class SlackAdapter
|
4
|
-
def initialize(
|
5
|
-
@
|
4
|
+
def initialize(real_time_client)
|
5
|
+
@real_time_client = real_time_client
|
6
6
|
end
|
7
7
|
|
8
8
|
def client_id_from_context(context)
|
@@ -10,7 +10,7 @@ module Socrates
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def send_message(message, context:)
|
13
|
-
@
|
13
|
+
@real_time_client.message(text: message, channel: context.channel)
|
14
14
|
end
|
15
15
|
|
16
16
|
def send_direct_message(message, user, *)
|
@@ -18,28 +18,28 @@ module Socrates
|
|
18
18
|
|
19
19
|
im_channel = lookup_im_channel(user)
|
20
20
|
|
21
|
-
@
|
21
|
+
@real_time_client.message(text: message, channel: im_channel)
|
22
22
|
end
|
23
23
|
|
24
24
|
def users_list
|
25
|
-
client = @
|
25
|
+
client = @real_time_client.web_client
|
26
26
|
client.users_list
|
27
27
|
end
|
28
28
|
|
29
29
|
def lookup_email(context:)
|
30
|
-
client = @
|
30
|
+
client = @real_time_client.web_client
|
31
31
|
client.users_info(user: context.user)
|
32
32
|
end
|
33
33
|
|
34
34
|
private
|
35
35
|
|
36
36
|
def lookup_im_channel(user)
|
37
|
-
im = @
|
37
|
+
im = @real_time_client.ims.values.find { |i| i.user == user }
|
38
38
|
|
39
39
|
return im if im.present?
|
40
40
|
|
41
41
|
# Start a new conversation with this user.
|
42
|
-
response = @
|
42
|
+
response = @real_time_client.web_client.im_open(user: user.id)
|
43
43
|
response.channel.id
|
44
44
|
end
|
45
45
|
end
|
@@ -24,7 +24,7 @@ module Socrates
|
|
24
24
|
# When first connecting, Slack may resend the last message. Ignore it...
|
25
25
|
next if data.reply_to.present?
|
26
26
|
|
27
|
-
@dispatcher.dispatch(
|
27
|
+
@dispatcher.dispatch(data.text, context: data)
|
28
28
|
end
|
29
29
|
|
30
30
|
@slack_client.start!
|
data/lib/socrates/version.rb
CHANGED
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.4
|
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-04-
|
11
|
+
date: 2017-04-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|