socrates 0.1.16 → 0.1.17

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f8a04c124dd3cd0a515b6f101904fd6484138f29
4
- data.tar.gz: 58980557833fa80594c337a98208d06645a696a2
3
+ metadata.gz: 73a8be96fc0b04e14a3137c1ad12ab9a7bcecd88
4
+ data.tar.gz: 1b55c1e1a2422ce84e3a60d2317b44876862cfbb
5
5
  SHA512:
6
- metadata.gz: b271fadac73d6cd4f5f41d5971ef266d86e3a2302b25860c043aa0287a09cdc5d426949c21a5de12a7aeb54652aec88b38a2bd98283fc5ff75563e805e9bb527
7
- data.tar.gz: 389636e1706c447bc54da299a3409d2990c73085463b56db0154b7967f97079eedcce40570fd8c6ef0f7908283d51e6c75ca5ceb20131f79845ade905ab5ddb2
6
+ metadata.gz: f4049f03b482773651d22cc6fa3dfb29d055fc1762d35a99b4fb7592fd8c1567240e6d552cb11712988df4e6173d73004ddee39b47470cfad32dd33a88c5f99c
7
+ data.tar.gz: 1dcaca7bed84ac8fb3219959ecf7fbec8fe5d52c66749842012d7252d64074a521fff2f9a972fcab92cf99e009a3e022f3f7d43bac5ef2c40effde5c6bb51923
data/exe/socrates CHANGED
@@ -34,7 +34,7 @@ option_parser = OptionParser.new do |parser|
34
34
  end
35
35
  option_parser.parse!
36
36
 
37
- def run_command(options)
37
+ def run_command(options) # rubocop:disable Metrics/MethodLength
38
38
  storage =
39
39
  case options[:storage]
40
40
  when "redis"
@@ -54,9 +54,15 @@ def run_command(options)
54
54
 
55
55
  case (adapter = options[:adapter])
56
56
  when "console"
57
- Socrates::Bots::CLI.new(state_factory: Socrates::SampleStates::StateFactory.new).start
57
+ adapter = Socrates::Adapters::Console.new
58
+ adapter.add_user(id: 1, name: "joe", first: "Joe", last: "Smith", email: "joe@example.com")
59
+ adapter.add_user(id: 2, name: "rachel", first: "Rachel", last: "Doe", email: "rachel@example.com")
60
+
61
+ Socrates::Bots::CLI.new(adapter: adapter, state_factory: Socrates::SampleStates::StateFactory.new).start
62
+
58
63
  when "slack"
59
64
  Socrates::Bots::Slack.new(state_factory: Socrates::SampleStates::StateFactory.new).start
65
+
60
66
  else
61
67
  puts "Unknown adapter '#{adapter}'"
62
68
  exit 1
@@ -0,0 +1,63 @@
1
+ require "socrates/adapters/stubs"
2
+
3
+ module Socrates
4
+ module Adapters
5
+ module Adapter
6
+ def client_id_from(_context: nil, _user: nil)
7
+ raise NotImplementedError
8
+ end
9
+
10
+ def channel_from(_context: nil, _user: nil)
11
+ raise NotImplementedError
12
+ end
13
+
14
+ def queue_message(session, message, send_now: false)
15
+ raise ArgumentError, "session is required" unless session.present?
16
+ raise ArgumentError, "session.channel is required" unless session.channel.present?
17
+
18
+ session.messages[session.channel] << message
19
+ flush_session(session, channel: session.channel) if send_now
20
+ end
21
+
22
+ def queue_direct_message(session, message, recipient)
23
+ raise ArgumentError, "recipient is required" unless recipient.present?
24
+ raise ArgumentError, "recipient.if is required" unless recipient.id.present?
25
+
26
+ dm_channel = channel_from(user: recipient)
27
+
28
+ session.messages[dm_channel] << message
29
+ end
30
+
31
+ def flush_session(session, channel: nil)
32
+ session.messages.select { |c, _| channel.nil? || channel == c }.each do |c, messages|
33
+ send_message(c, messages.join("\n\n"))
34
+ messages.clear
35
+ end
36
+ end
37
+
38
+ def send_message(_channel, _message)
39
+ raise NotImplementedError
40
+ end
41
+
42
+ def user_from(_context:)
43
+ raise NotImplementedError
44
+ end
45
+
46
+ def users_list(*)
47
+ raise NotImplementedError
48
+ end
49
+
50
+ def lookup_user(_email:)
51
+ raise NotImplementedError
52
+ end
53
+
54
+ def lookup_email(*)
55
+ raise NotImplementedError
56
+ end
57
+
58
+ def users_channel(_user)
59
+ raise NotImplementedError
60
+ end
61
+ end
62
+ end
63
+ end
@@ -1,12 +1,13 @@
1
+ require "socrates/adapters/adapter"
1
2
  require "socrates/adapters/stubs"
2
3
 
3
4
  module Socrates
4
5
  module Adapters
5
6
  class Console
7
+ include Socrates::Adapters::Adapter
6
8
  include StubUserDirectory
7
9
 
8
10
  CLIENT_ID = "CONSOLE"
9
- CHANNEL = "C1"
10
11
 
11
12
  def initialize(name: "@socrates")
12
13
  super()
@@ -22,41 +23,22 @@ module Socrates
22
23
  def channel_from(context: nil, user: nil)
23
24
  raise ArgumentError, "Must provide one of :context or :user" if context.nil? && user.nil?
24
25
 
25
- CHANNEL
26
- end
27
-
28
- def send_message(session, message, send_now: false)
29
- raise ArgumentError, "Channel is required" unless session.channel.present?
30
-
31
- session.messages[session.channel] << message
32
- flush_session(session, channel: session.channel) if send_now
33
- end
34
-
35
- def send_direct_message(session, message, recipient)
36
- raise ArgumentError, "User is required" unless recipient.present?
37
-
38
- name =
39
- if recipient.respond_to?(:name)
40
- recipient.name
41
- elsif recipient.respond_to?(:id)
42
- recipient.id
43
- else
44
- recipient
45
- end
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
26
+ if context&.fetch(:channel).present?
27
+ context[:channel]
28
+ elsif user.present?
29
+ display_user(user)
30
+ else
31
+ "?"
54
32
  end
55
33
  end
56
34
 
57
35
  private
58
36
 
59
- def _send_message(channel, message) # TODO: Underscored name?
37
+ def display_user(user)
38
+ (user&.name || user&.id || user)&.upcase
39
+ end
40
+
41
+ def send_message(channel, message)
60
42
  puts "\n#{colorize(channel, "34;1")}: #{message}"
61
43
  end
62
44
 
@@ -1,8 +1,10 @@
1
+ require "socrates/adapters/adapter"
1
2
  require "socrates/adapters/stubs"
2
3
 
3
4
  module Socrates
4
5
  module Adapters
5
6
  class Memory
7
+ include Socrates::Adapters::Adapter
6
8
  include StubUserDirectory
7
9
 
8
10
  CLIENT_ID = "MEMORY"
@@ -28,28 +30,6 @@ module Socrates
28
30
  user.nil? ? CHANNEL : users_channel(user)
29
31
  end
30
32
 
31
- def send_message(session, message, send_now: false)
32
- raise ArgumentError, "Channel is required" unless session.channel.present?
33
-
34
- session.messages[session.channel] << message
35
- flush_session(session, channel: session.channel) if send_now
36
- end
37
-
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
45
-
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
51
- end
52
-
53
33
  #
54
34
  # Methods for fetching messages and dms in specs...
55
35
  #
@@ -72,7 +52,7 @@ module Socrates
72
52
 
73
53
  private
74
54
 
75
- def _send_message(channel, message) # TODO: Underscored name?
55
+ def send_message(channel, message)
76
56
  @history[channel] << message
77
57
  end
78
58
 
@@ -1,8 +1,11 @@
1
1
  require "active_support/core_ext/object"
2
+ require "socrates/adapters/adapter"
2
3
 
3
4
  module Socrates
4
5
  module Adapters
5
6
  class Slack
7
+ include Socrates::Adapters::Adapter
8
+
6
9
  def initialize(real_time_client)
7
10
  @real_time_client = real_time_client
8
11
  end
@@ -29,38 +32,6 @@ module Socrates
29
32
  raise ArgumentError, "Must provide one of context or user"
30
33
  end
31
34
 
32
- def user_from(context:)
33
- raise ArgumentError, "context cannot be nil" if context.nil?
34
- raise ArgumentError, "Expected context to respond to :user" unless context.respond_to?(:user)
35
-
36
- client = @real_time_client.web_client
37
- info = client.users_info(user: context.user)
38
- info.present? ? info.user : nil
39
- end
40
-
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
47
- end
48
-
49
- def send_direct_message(session, message, recipient)
50
- raise ArgumentError, "Expected recipient to respond to :id" unless recipient.respond_to?(:id)
51
-
52
- im_channel = lookup_im_channel(recipient)
53
-
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
62
- end
63
-
64
35
  def users_list(include_deleted: false, include_bots: false)
65
36
  client = @real_time_client.web_client
66
37
 
@@ -70,6 +41,15 @@ module Socrates
70
41
  end
71
42
  end
72
43
 
44
+ def user_from(context:)
45
+ raise ArgumentError, "context cannot be nil" if context.nil?
46
+ raise ArgumentError, "Expected context to respond to :user" unless context.respond_to?(:user)
47
+
48
+ client = @real_time_client.web_client
49
+ info = client.users_info(user: context.user)
50
+ info.present? ? info.user : nil
51
+ end
52
+
73
53
  # Note: this triggers a call to the Slack API which makes it ill-suited for use within a loop.
74
54
  def lookup_user(email:)
75
55
  users_list.members.find { |user| email == user.profile&.email }
@@ -85,7 +65,7 @@ module Socrates
85
65
 
86
66
  private
87
67
 
88
- def _send_message(channel, message) # TODO: Underscored name?
68
+ def send_message(channel, message)
89
69
  @real_time_client.message(text: message, channel: channel)
90
70
  end
91
71
 
@@ -10,8 +10,10 @@ module Socrates
10
10
  end
11
11
 
12
12
  def start
13
+ context = { channel: "CONSOLE" }
14
+
13
15
  while (input = gets.chomp)
14
- @dispatcher.dispatch(input)
16
+ @dispatcher.dispatch(input, context: context)
15
17
  end
16
18
  end
17
19
  end
@@ -46,7 +46,7 @@ module Socrates
46
46
  persist_state_data(session.client_id, state_data)
47
47
 
48
48
  # Send our initial message if one was passed to us.
49
- @adapter.send_direct_message(session, message, user) if message.present?
49
+ @adapter.queue_direct_message(session, message, user) if message.present?
50
50
 
51
51
  do_dispatch(session, nil)
52
52
  true
@@ -172,7 +172,7 @@ module Socrates
172
172
  @logger.warn "Error while processing action #{state.data.state_id}/#{state.data.state_action}: #{e.message}"
173
173
  @logger.warn e
174
174
 
175
- @adapter.send_message(session, @error_message, send_now: true)
175
+ @adapter.queue_message(session, @error_message, send_now: true)
176
176
 
177
177
  state.data.clear
178
178
  state.data.state_id = nil
@@ -48,14 +48,14 @@ module Socrates
48
48
  return if message.empty?
49
49
 
50
50
  @logger.info %Q(#{@session.channel} send: "#{format_for_logging(message)}")
51
- @adapter.send_message(@session, message, send_now: send_now)
51
+ @adapter.queue_message(@session, message, send_now: send_now)
52
52
  end
53
53
 
54
- def send_message(to:, message:)
54
+ def send_message(to:, message:) # TODO: direct_message? send_dm?
55
55
  displayable_to = to.respond_to?(:id) ? to.id : to
56
56
 
57
57
  @logger.info %Q(#{@session.channel} send direct to #{displayable_to}: "#{format_for_logging(message)}")
58
- @adapter.send_direct_message(@session, message, to)
58
+ @adapter.queue_direct_message(@session, message, to)
59
59
  end
60
60
 
61
61
  def transition_to(state_id, action: nil, data: {})
@@ -31,6 +31,8 @@ module Socrates
31
31
  transition_to :help
32
32
  when "age"
33
33
  transition_to :ask_for_name
34
+ when "dms"
35
+ transition_to :dms
34
36
  when "error"
35
37
  transition_to :raise_error
36
38
  else
@@ -47,6 +49,7 @@ module Socrates
47
49
  Thanks for asking! I can do these things for you...
48
50
 
49
51
  • `age` - Calculate your age from your birth date.
52
+ • `dms` - Sends a direct messages to two other users.
50
53
  • `error` - Start a short error path that raises an error.
51
54
  • `help` - Tell you what I can do for you.
52
55
 
@@ -167,6 +170,26 @@ module Socrates
167
170
  end
168
171
  end
169
172
 
173
+ class Dms
174
+ include Socrates::Core::State
175
+
176
+ def ask
177
+ respond message: "I will send whatever you type to two other users as direct messages."
178
+ end
179
+
180
+ def listen(message)
181
+ users = @adapter.users_list.members.sample(2)
182
+
183
+ users.each do |user|
184
+ send_message(to: user, message: "Message: #{message}")
185
+ end
186
+
187
+ respond message: "Direct messages sent!"
188
+
189
+ end_conversation
190
+ end
191
+ end
192
+
170
193
  class RaiseError
171
194
  include Socrates::Core::State
172
195
 
@@ -1,3 +1,3 @@
1
1
  module Socrates
2
- VERSION = "0.1.16"
2
+ VERSION = "0.1.17"
3
3
  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.16
4
+ version: 0.1.17
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-09-15 00:00:00.000000000 Z
11
+ date: 2017-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -170,6 +170,7 @@ files:
170
170
  - circle.yml
171
171
  - exe/socrates
172
172
  - lib/socrates.rb
173
+ - lib/socrates/adapters/adapter.rb
173
174
  - lib/socrates/adapters/console.rb
174
175
  - lib/socrates/adapters/memory.rb
175
176
  - lib/socrates/adapters/slack.rb