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