boty 0.0.7 → 0.0.9

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: ec2bf939ca3aff3761d4019b065287e836d6859c
4
- data.tar.gz: acd79aba96e84b017fff702f11fb9f20a6cd9d97
3
+ metadata.gz: b15b8096419aa755624c59ba1c22e35d7c62a6e3
4
+ data.tar.gz: 52b507f57d34b6ed50d838c8cd96ed117e39fc98
5
5
  SHA512:
6
- metadata.gz: 9c5edc1117584ea21477c080b246f89ee8653b118daf83469f78215c9961f12442bc680733f0ec51b2a01a2c02c411b58cf139d4607f8fbee9270817a1a09443
7
- data.tar.gz: 41ddccf73cc09e48e89854c21941640e38498ef8ce6e7e69e3fbfac77b05ceb3f8f35b086c524820add7ecc7273f4c6b1841ad00042721213b66cd1a6ad1abcf
6
+ metadata.gz: 3d933754cd44b578e03335dd53977748662d2cb893c0ab28e44ec51bd39335116947b79777dca9583deeef63ce8e43bc654170b434ab4f9ac225650464a2bc14
7
+ data.tar.gz: 961c2bf18e65662c8eb0a3c5cdc02ed3882c52b3b6326f3acc9d31845e0c0ce0e53b5f8823a27955308b7e2fc022cb5367a889b116594f64ea8b3d48d62a7a52
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- boty (0.0.7)
4
+ boty (0.0.9)
5
5
  eventmachine
6
6
  faye-websocket
7
7
  thor
data/README.md CHANGED
@@ -131,9 +131,56 @@ Turn on this resource. And done, your bot is up and running!
131
131
 
132
132
  For now, check the `script/ping.rb` and follow it's leads.
133
133
 
134
+ ### Describing script usage
135
+
136
+ A bot list all the commands and message handlers that it knows in the moment. If
137
+ you want to give a nice description and/or a usage tip on command you can use
138
+ the `desc` method.
139
+
140
+ Given that your bot has the following script:
141
+
142
+ ```ruby
143
+ desc "pug me", "Send some nice pug in the channel."
144
+ respond(/pug me/i) do
145
+ # ...
146
+ end
147
+ ```
148
+
149
+ The follow text will be part of the response for a `@bot: knows` command:
150
+
151
+ pug me: Send some nice pug in the channel.
152
+
153
+ You can use just the description if you want. In this case the `regex` itself
154
+ will be used as the command name.
155
+
156
+ ```ruby
157
+ desc "Send some nice pug in the channel."
158
+ respond(/pug me/i) do
159
+ # ...
160
+ end
161
+ ```
162
+
163
+ valeriano 2:25PM
164
+ @bot: knows
165
+
166
+ bot 2:25PM
167
+ knows: List all the commands known by this bot.
168
+ /pug me/i: Send some nice pug in the channel.
169
+
170
+ We strongly recommend that you describe all of your scripts. But if you don't,
171
+ the bot will be capable of tell you what `regexes` are binded to it:
172
+
173
+ valeriano 2:47PM
174
+ @jabberu: knows
175
+
176
+ jabberu 2:47PM
177
+ knows: List all the commands known by this bot.
178
+ /pug me/i
179
+ /jabberu, are you there\?/i
180
+
134
181
  ### Testing your own scripts
135
182
 
136
- **todo: document**`
183
+ **todo: document**
137
184
 
138
185
  For now, check the `spec/script/ping_spec.rb` and follow it's leads.
139
186
 
data/bin/bot CHANGED
@@ -3,7 +3,8 @@ require "./lib/boty"
3
3
 
4
4
  session = Boty::Session.new
5
5
  session.start do |bot|
6
- bot.message(/are you there\?/i) do |message|
6
+ bot.desc "Responds when someone asks for the #{bot.name} presence."
7
+ bot.message(/#{bot.name}, are you there\?/i) do |message|
7
8
  next if message.from? self
8
9
  say "Ohay <@#{message.user}>! I'm here, that's for sure."
9
10
  end
@@ -0,0 +1,35 @@
1
+ module Boty
2
+ class Action
3
+ attr_reader :regex, :desc, :action
4
+
5
+ class Description
6
+ attr_reader :command, :description
7
+ attr_writer :regex
8
+
9
+ def initialize(command, description: nil, regex: nil)
10
+ if description.nil?
11
+ @description = command
12
+ else
13
+ @command, @description = command, description
14
+ end
15
+
16
+ @regex = regex
17
+ end
18
+
19
+ def command
20
+ return @command if @command
21
+
22
+ match = /\?(i?)-(mx|mix):(.*)\)/.match @regex.to_s
23
+ "/#{match[3]}/#{match[1]}"
24
+ end
25
+ end
26
+
27
+ def initialize(regex, desc, &action)
28
+ desc = Hash(desc)
29
+ description = Description.new(desc[:command],
30
+ description: desc[:description],
31
+ regex: regex)
32
+ @regex, @desc, @action = regex, description, action
33
+ end
34
+ end
35
+ end
data/lib/boty/bot.rb CHANGED
@@ -7,6 +7,7 @@ module Boty
7
7
  @raw_info, @id, @name = bot_info, bot_info["id"], bot_info["name"]
8
8
  @events = {}
9
9
  load_default_scripts
10
+ on :message, &method(:message_handler)
10
11
  end
11
12
 
12
13
  def event(data)
@@ -23,23 +24,13 @@ module Boty
23
24
  end
24
25
 
25
26
  def message(regex, &block)
26
- on :message do |data|
27
- yield_message_if_matches(data, block) do
28
- regex.match data["text"]
29
- end
30
- end
27
+ @handlers ||= []
28
+ @handlers << create_action(regex, &block)
31
29
  end
32
30
 
33
31
  def respond(regex, &block)
34
- on :message do |data|
35
- # ignores if the mentions was sent by the bot itself, avoid infinite
36
- # loops.
37
- next if message_from_bot_itself? data
38
- logger.debug { "message wasn't from bot itself, so continuing..." }
39
- yield_message_if_matches(data, block) do
40
- has_mention?(data) && regex.match(data["text"])
41
- end
42
- end
32
+ @commands ||= []
33
+ @commands << create_action(regex, &block)
43
34
  end
44
35
 
45
36
  def say(message, api_parameters = {})
@@ -49,16 +40,27 @@ module Boty
49
40
  logger.debug { "post response: #{post_response}" }
50
41
  end
51
42
 
43
+ def desc(command, description = nil)
44
+ @current_desc = { command: command, description: description }
45
+ end
46
+
47
+ def know_how
48
+ descriptions = (Array(@commands) + Array(@handlers)).compact.map(&:desc)
49
+ descriptions.inject({}) { |hsh, desc|
50
+ hsh.merge!(desc.command => desc.description)
51
+ }
52
+ end
53
+
52
54
  private
53
55
 
54
- def load_default_scripts
55
- # TODO: guarantee that we not load the same file twice
56
- Dir["script/**/*.rb"].each do |file|
57
- instance_eval File.read(file), file, 1
58
- end
56
+ def scripts_to_load
59
57
  default_scripts_path = File.expand_path("../../../script", __FILE__)
60
- # also loads the default scripts:
61
- Dir["#{default_scripts_path}/**/*.rb"].each do |file|
58
+ paths = Dir["script/**/*.rb"] + Dir["#{default_scripts_path}/**/*.rb"]
59
+ paths.map { |file| File.expand_path file }.uniq
60
+ end
61
+
62
+ def load_default_scripts
63
+ scripts_to_load.each do |file|
62
64
  instance_eval File.read(file), file, 1
63
65
  end
64
66
  end
@@ -73,22 +75,34 @@ module Boty
73
75
  type
74
76
  end
75
77
 
76
- def has_mention?(data)
77
- /<@#{name}>|<@#{id}>/ =~ data["text"]
78
+ def create_action(regex, &block)
79
+ Boty::Action.new(regex, @current_desc, &block).tap {
80
+ @current_desc = nil
81
+ }
78
82
  end
79
83
 
80
84
  def message_from_bot_itself?(data)
81
- data["user"] == self.id
85
+ data["user"] == self.id || data["user"] == self.name
86
+ end
87
+
88
+ def has_valid_mention?(data)
89
+ return false if message_from_bot_itself? data
90
+ !!(/(<@#{id}|#{name}>)/ =~ data["text"])
91
+ end
92
+
93
+ def execute_command(command, message)
94
+ @_message = message
95
+ instance_exec @_message, &command.action
96
+ @_message = nil
82
97
  end
83
98
 
84
- def yield_message_if_matches(data, message_block)
85
- match = yield
86
- if match
87
- # Store the current message in the bot context so it can be used to
88
- # infer channel to respond, and so on.
89
- @_message = Message.new data, match: match
90
- instance_exec @_message, &message_block
91
- @_message = nil
99
+ def message_handler(data)
100
+ actions = has_valid_mention?(data) ? @commands : @handlers
101
+
102
+ Array(actions).each do |command|
103
+ next unless match = command.regex.match(data["text"])
104
+ #command.execute(self, match) #=> or something like that...
105
+ execute_command command, Message.new(data, match: match)
92
106
  end
93
107
  end
94
108
  end
data/lib/boty/session.rb CHANGED
@@ -13,7 +13,11 @@ module Boty
13
13
 
14
14
  stablish_connection do |ws|
15
15
  ws.on :message do |event|
16
- on_message event, bot
16
+ begin
17
+ on_message event, bot
18
+ rescue StandardError => e
19
+ logger.error "Message #{event} could not be processed. #{e.message}"
20
+ end
17
21
  end
18
22
  end
19
23
  end
data/lib/boty/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Boty
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.9"
3
3
  end
data/lib/boty.rb CHANGED
@@ -34,4 +34,5 @@ require "boty/version"
34
34
  require "boty/slack"
35
35
  require "boty/session"
36
36
  require "boty/message"
37
+ require "boty/action"
37
38
  require "boty/bot"
data/script/knows.rb ADDED
@@ -0,0 +1,10 @@
1
+ desc "knows", "list all the commands known by this bot."
2
+ respond(/knows/i) do
3
+ message = know_how.inject("") { |_message, command|
4
+
5
+ _message << command.first
6
+ _message << ": #{command.last}" if command.last
7
+ _message << "\n"
8
+ }
9
+ say message
10
+ end
data/script/pug.rb CHANGED
@@ -1,8 +1,10 @@
1
+ desc "Send some nice pug in the channel."
1
2
  respond(/pug me/i) do
2
3
  response = JSON.parse Net::HTTP.get(URI "http://pugme.herokuapp.com/random")
3
4
  say "<#{response["pug"]}>"
4
5
  end
5
6
 
7
+ desc "pug bomb X", "Send X pugs in the channel."
6
8
  respond(/pug bomb( (\d+))?/i) do |message|
7
9
  count = message.match[2] || 5
8
10
  response = JSON.parse Net::HTTP.get(URI "http://pugme.herokuapp.com/bomb?count=#{count}")
@@ -3,6 +3,7 @@ require "./<%= bot_name %>"
3
3
 
4
4
  session = Boty::Session.new
5
5
  session.start do |bot|
6
+ desc "Responds when the bot name (<%= bot_name %>) is mentioned in a message."
6
7
  bot.message(/<%= bot_name %>/i) do |message|
7
8
  next if message.from? self
8
9
  say "Ohay <@#{message.user}>! I'm here, that's for sure."
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: boty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ricardo Valeriano
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-11-21 00:00:00.000000000 Z
11
+ date: 2015-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: eventmachine
@@ -174,6 +174,7 @@ files:
174
174
  - boty.gemspec
175
175
  - exe/boty
176
176
  - lib/boty.rb
177
+ - lib/boty/action.rb
177
178
  - lib/boty/bot.rb
178
179
  - lib/boty/cli.rb
179
180
  - lib/boty/dsl.rb
@@ -187,6 +188,7 @@ files:
187
188
  - lib/boty/version.rb
188
189
  - lib/tasks/.keep
189
190
  - log/.keep
191
+ - script/knows.rb
190
192
  - script/pug.rb
191
193
  - template/project/%bot_name%.rb
192
194
  - template/project/.env.local.tt