robut 0.2.0
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.
- data/.gitignore +6 -0
- data/Gemfile +17 -0
- data/README.rdoc +124 -0
- data/Rakefile +27 -0
- data/bin/robut +9 -0
- data/examples/Chatfile +22 -0
- data/lib/robut.rb +5 -0
- data/lib/robut/connection.rb +167 -0
- data/lib/robut/plugin.rb +16 -0
- data/lib/robut/plugin/base.rb +70 -0
- data/lib/robut/plugin/calc.rb +20 -0
- data/lib/robut/plugin/echo.rb +14 -0
- data/lib/robut/plugin/later.rb +73 -0
- data/lib/robut/plugin/lunch.rb +57 -0
- data/lib/robut/plugin/meme.rb +30 -0
- data/lib/robut/plugin/ping.rb +11 -0
- data/lib/robut/plugin/rdio.rb +70 -0
- data/lib/robut/plugin/rdio/public/css/rdio.css +141 -0
- data/lib/robut/plugin/rdio/public/css/style.css +79 -0
- data/lib/robut/plugin/rdio/public/css/style_after.css +42 -0
- data/lib/robut/plugin/rdio/public/images/background.png +0 -0
- data/lib/robut/plugin/rdio/public/images/no-album.png +0 -0
- data/lib/robut/plugin/rdio/public/index.html +42 -0
- data/lib/robut/plugin/rdio/public/js/libs/dd_belatedpng.js +13 -0
- data/lib/robut/plugin/rdio/public/js/libs/jquery-1.5.1.min.js +16 -0
- data/lib/robut/plugin/rdio/public/js/libs/modernizr-1.7.min.js +2 -0
- data/lib/robut/plugin/rdio/public/js/rdio.js +129 -0
- data/lib/robut/plugin/rdio/public/js/script.js +3 -0
- data/lib/robut/plugin/rdio/server.rb +34 -0
- data/lib/robut/plugin/say.rb +20 -0
- data/lib/robut/plugin/sayings.rb +31 -0
- data/lib/robut/plugin/twss.rb +13 -0
- data/lib/robut/storage.rb +3 -0
- data/lib/robut/storage/base.rb +21 -0
- data/lib/robut/storage/hash_store.rb +26 -0
- data/lib/robut/storage/yaml_store.rb +51 -0
- data/lib/robut/version.rb +4 -0
- data/robut.gemspec +23 -0
- data/test/mocks/connection_mock.rb +26 -0
- data/test/simplecov_helper.rb +2 -0
- data/test/test_helper.rb +7 -0
- data/test/unit/connection_test.rb +123 -0
- data/test/unit/plugin/base_test.rb +16 -0
- data/test/unit/plugin/echo_test.rb +26 -0
- data/test/unit/plugin/later_test.rb +39 -0
- data/test/unit/plugin/lunch_test.rb +35 -0
- data/test/unit/plugin/ping_test.rb +21 -0
- data/test/unit/plugin/say_test.rb +28 -0
- data/test/unit/storage/hash_store_test.rb +15 -0
- data/test/unit/storage/yaml_store_test.rb +42 -0
- data/test/unit/storage/yaml_test.yml +1 -0
- metadata +135 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in robut.gemspec
|
4
|
+
gemspec
|
5
|
+
gem 'rake'
|
6
|
+
|
7
|
+
group :test do
|
8
|
+
gem 'simplecov'
|
9
|
+
end
|
10
|
+
|
11
|
+
group :plugin do
|
12
|
+
gem 'calc'
|
13
|
+
gem 'twss'
|
14
|
+
gem 'rdio'
|
15
|
+
gem 'sinatra'
|
16
|
+
gem 'meme_generator'
|
17
|
+
end
|
data/README.rdoc
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
= Robut
|
2
|
+
|
3
|
+
The friendly plugin-enabled HipChat bot.
|
4
|
+
|
5
|
+
== Installation and usage
|
6
|
+
|
7
|
+
Robut can be installed by running <tt>gem install robut</tt>. This
|
8
|
+
installs the +robut+ binary. When run, +robut+ reads a Chatfile,
|
9
|
+
connects to the specified HipChat server and chatroom, and feeds every
|
10
|
+
line said in the chatroom through the plugins configured by the
|
11
|
+
Chatfile.
|
12
|
+
|
13
|
+
Once robut is running, the plugins listen to what's being said in the
|
14
|
+
chatroom. Most plugins listen for @replies to robut:
|
15
|
+
|
16
|
+
@robut lunch? # => "Banh Mi!"
|
17
|
+
@robut calc 1 + 1 # => 2
|
18
|
+
|
19
|
+
Others listen to everything, and don't require an @reply.
|
20
|
+
|
21
|
+
Some of the included plugins require extra gems to be installed:
|
22
|
+
|
23
|
+
[Robut::Plugin::TWSS] requires the <tt>twss</tt> gem
|
24
|
+
[Robut::Plugin::Meme] requires the <tt>meme_generator</tt> gem
|
25
|
+
[Robut::Plugin::Calc] requires the <tt>calc</tt> gem
|
26
|
+
[Robut::Plugin::Rdio] requires the <tt>rdio</tt> and <tt>sinatra</tt> gems
|
27
|
+
|
28
|
+
== The Chatfile
|
29
|
+
|
30
|
+
When the +robut+ command runs, it looks for and evals ruby code in a
|
31
|
+
file called +Chatfile+ in the current directory. You can override the
|
32
|
+
configuration file by passing +robut+ a path to a Chatfile as the
|
33
|
+
first parameter:
|
34
|
+
|
35
|
+
robut /path/to/Chatfile
|
36
|
+
|
37
|
+
The Chatfile is just ruby code. A simple example can be found here: Chatfile[https://github.com/justinweiss/robut/blob/master/examples/Chatfile]
|
38
|
+
|
39
|
+
=== Adding and configuring plugins
|
40
|
+
|
41
|
+
Plugins are ruby classes, so enabling a plugin just requires requiring
|
42
|
+
the plugin file, optionally configuring the plugin class, and adding
|
43
|
+
the class to the global plugin list:
|
44
|
+
|
45
|
+
require 'robut/plugin/lunch'
|
46
|
+
Robut::Plugin::Lunch.places = ["Banh Mi", "Mad Oven", "Mod Pizza", "Taphouse"]
|
47
|
+
Robut::Plugin.plugins << Robut::Plugin::Lunch
|
48
|
+
|
49
|
+
Each plugin can be configured differently, or not at all. It's best to
|
50
|
+
look at the docs for the plugins you want to use to figure out what
|
51
|
+
kind of configuration they support.
|
52
|
+
|
53
|
+
Some plugins might require storage (like the `lunch` plugin). You can
|
54
|
+
configure the type of storage you want to use based on the need for
|
55
|
+
persistence. The default is the HashStore which is in-memory only. Below
|
56
|
+
is an example of using the YamlStore.
|
57
|
+
|
58
|
+
Robut::Connection.configure do |config|
|
59
|
+
# ...
|
60
|
+
Robut::Storage::YamlStore.file = "~/.robut_store"
|
61
|
+
config.store = Robut::Storage::YamlStore
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
=== Configuring the HipChat connection
|
66
|
+
|
67
|
+
The Chatfile also configures the HipChat connection. This is done in a
|
68
|
+
Robut::Connection.configure block:
|
69
|
+
|
70
|
+
# Configure the robut jabber connection and you're good to go!
|
71
|
+
Robut::Connection.configure do |config|
|
72
|
+
config.jid = '...@chat.hipchat.com/bot'
|
73
|
+
config.password = 'password'
|
74
|
+
config.nick = 'My Nick'
|
75
|
+
config.room = '...@conf.hipchat.com'
|
76
|
+
|
77
|
+
# Example of the YamlStore which uses a yaml file for persistence
|
78
|
+
Robut::Storage::YamlStore.file = "~/.robut_store"
|
79
|
+
config.store = Robut::Storage::YamlStore
|
80
|
+
|
81
|
+
# Add a logger if you want to debug the connection
|
82
|
+
# config.logger = Logger.new(STDOUT)
|
83
|
+
end
|
84
|
+
|
85
|
+
This block usually goes at the end of the Chatfile.
|
86
|
+
|
87
|
+
== Built-in plugins
|
88
|
+
|
89
|
+
Robut includes a few plugins that we've found useful:
|
90
|
+
|
91
|
+
[Robut::Plugin::Calc] a simple calculator. <br /> <br /> Example: <tt>@robut calc 1 + 1 # => 2</tt>
|
92
|
+
[Robut::Plugin::Lunch] a random decider for lunch locations. <br /> <br /> Example: <tt>@robut lunch? # => "Banh Mi!"</tt>
|
93
|
+
[Robut::Plugin::Meme] an interface to memegenerator.net. <br /> <br /> Example: <tt>@robut meme Y_U_NO FIX THE BUILD?</tt>
|
94
|
+
[Robut::Plugin::Sayings] a simple regex listener and responder. <br /> <br /> Example: <tt>You're the worst robot ever, @robut. # => I know. </tt>
|
95
|
+
[Robut::Plugin::TWSS] an interface to the TWSS gem. Listens to anything said in the chat room and responds "That's what she said!" where appropriate. <br /> <br /> Example: <tt>well hurry up, you're not going fast enough # => "That's what she said!" </tt>
|
96
|
+
[Robut::Plugin::Echo] echo back whatever it gets. <br /> <br /> Example: <tt>@robut echo hello word</tt>
|
97
|
+
[Robut::Plugin::Say] invokes the "say" command (text-to-speech). <br /> <br /> Example: <tt>@robut say this rocks</tt>
|
98
|
+
[Robut::Plugin::Ping] responds with "pong". <br /> <br /> Example: <tt>@robut ping</tt>
|
99
|
+
[Robut::Plugin::Later] performs the given command after waiting an arbitrary amount of time. <br /> <br /> Example: <tt>@robut in 5 minutes echo @justin wake up!</tt>
|
100
|
+
[Robut::Plugin::Rdio] uses the Rdio[http://www.rdio.com] API and a simple web server to queue and play songs on Rdio. <br /> <br /> Example: <tt>@robut play ok computer</tt>
|
101
|
+
|
102
|
+
== Writing custom plugins
|
103
|
+
|
104
|
+
You can supply your own plugins to Robut. To create a plugin, subclass
|
105
|
+
Robut::Plugin::Base and implement the <tt>handle(time, sender_nick,
|
106
|
+
message)</tt> to perform any plugin-specific logic.
|
107
|
+
|
108
|
+
Robut::Plugin::Base provides a few helper methods that are documented
|
109
|
+
in its class definition.
|
110
|
+
|
111
|
+
== Contributing
|
112
|
+
|
113
|
+
Once you've made your great commits:
|
114
|
+
|
115
|
+
1. Fork robut
|
116
|
+
2. Create a topic branch - git checkout -b my_branch
|
117
|
+
3. Push to your branch - git push origin my_branch
|
118
|
+
4. Send me a pull request
|
119
|
+
5. That's it!
|
120
|
+
|
121
|
+
== Todo
|
122
|
+
|
123
|
+
* Support connections to multiple rooms
|
124
|
+
* More plugins!
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
require 'bundler'
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
task :default => :test
|
7
|
+
task :build => :test
|
8
|
+
|
9
|
+
Rake::TestTask.new do |t|
|
10
|
+
t.libs << "test"
|
11
|
+
t.test_files = FileList['test/**/*_test.rb']
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
Rake::TestTask.new(:coverage) do |t|
|
16
|
+
t.libs << "test"
|
17
|
+
t.ruby_opts = ["-rsimplecov_helper"]
|
18
|
+
t.test_files = FileList['test/**/*_test.rb']
|
19
|
+
t.verbose = true
|
20
|
+
end
|
21
|
+
|
22
|
+
Rake::RDocTask.new do |rd|
|
23
|
+
rd.main = "README.rdoc"
|
24
|
+
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
25
|
+
rd.rdoc_dir = 'doc'
|
26
|
+
end
|
27
|
+
|
data/bin/robut
ADDED
data/examples/Chatfile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Require your plugins here
|
2
|
+
require 'robut/plugin/twss'
|
3
|
+
require 'robut/storage/yaml_store'
|
4
|
+
|
5
|
+
# Add the plugin classes to the Robut plugin list.
|
6
|
+
# Plugins are handled in the order that they appear in this array.
|
7
|
+
Robut::Plugin.plugins << Robut::Plugin::TWSS
|
8
|
+
|
9
|
+
# Configure the robut jabber connection and you're good to go!
|
10
|
+
Robut::Connection.configure do |config|
|
11
|
+
config.jid = '...@chat.hipchat.com/bot'
|
12
|
+
config.password = 'password'
|
13
|
+
config.nick = 'My Nick'
|
14
|
+
config.room = '...@conf.hipchat.com'
|
15
|
+
|
16
|
+
# Some plugins require storage
|
17
|
+
Robut::Storage::YamlStore.file = ".robut"
|
18
|
+
config.store = Robut::Storage::YamlStore
|
19
|
+
|
20
|
+
# Add a logger if you want to debug the connection
|
21
|
+
# config.logger = Logger.new(STDOUT)
|
22
|
+
end
|
data/lib/robut.rb
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'xmpp4r'
|
2
|
+
require 'xmpp4r/muc/helper/simplemucclient'
|
3
|
+
require 'xmpp4r/roster/helper/roster'
|
4
|
+
require 'ostruct'
|
5
|
+
|
6
|
+
# Handles opening a connection to the HipChat server, and feeds all
|
7
|
+
# messages through our Robut::Plugin list.
|
8
|
+
class Robut::Connection
|
9
|
+
|
10
|
+
# The configuration used by the Robut connection.
|
11
|
+
#
|
12
|
+
# Parameters:
|
13
|
+
#
|
14
|
+
# [+jid+, +password+, +nick+] The HipChat credentials given on
|
15
|
+
# https://www.hipchat.com/account/xmpp
|
16
|
+
#
|
17
|
+
# [+room+] The chat room to join, in the format <tt>jabber_name</tt>@<tt>conference_server</tt>
|
18
|
+
#
|
19
|
+
# [+logger+] a logger instance to use for debug output.
|
20
|
+
attr_accessor :config
|
21
|
+
|
22
|
+
# The Jabber::Client that's connected to the HipChat server.
|
23
|
+
attr_accessor :client
|
24
|
+
|
25
|
+
# The MUC that wraps the Jabber Chat protocol.
|
26
|
+
attr_accessor :muc
|
27
|
+
|
28
|
+
# The storage instance that's available to plugins
|
29
|
+
attr_accessor :store
|
30
|
+
|
31
|
+
# The roster of currently available people
|
32
|
+
attr_accessor :roster
|
33
|
+
|
34
|
+
class << self
|
35
|
+
# Class-level config. This is set by the +configure+ class method,
|
36
|
+
# and is used if no configuration is passed to the +initialize+
|
37
|
+
# method.
|
38
|
+
attr_accessor :config
|
39
|
+
end
|
40
|
+
|
41
|
+
# Configures the connection at the class level. When the +robut+ bin
|
42
|
+
# file is loaded, it evals the file referenced by the first
|
43
|
+
# command-line parameter. This file can configure the connection
|
44
|
+
# instance later created by +robut+ by setting parameters in the
|
45
|
+
# Robut::Connection.configure block.
|
46
|
+
def self.configure
|
47
|
+
self.config = OpenStruct.new
|
48
|
+
yield config
|
49
|
+
end
|
50
|
+
|
51
|
+
# Sets the instance config to +config+, converting it into an
|
52
|
+
# OpenStruct if necessary.
|
53
|
+
def config=(config)
|
54
|
+
@config = config.kind_of?(Hash) ? OpenStruct.new(config) : config
|
55
|
+
end
|
56
|
+
|
57
|
+
# Initializes the connection. If no +config+ is passed, it defaults
|
58
|
+
# to the class_level +config+ instance variable.
|
59
|
+
def initialize(_config = nil)
|
60
|
+
self.config = _config || self.class.config
|
61
|
+
|
62
|
+
self.client = Jabber::Client.new(self.config.jid)
|
63
|
+
self.muc = Jabber::MUC::SimpleMUCClient.new(client)
|
64
|
+
self.store = self.config.store || Robut::Storage::HashStore # default to in-memory store only
|
65
|
+
|
66
|
+
if self.config.logger
|
67
|
+
Jabber.logger = self.config.logger
|
68
|
+
Jabber.debug = true
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Send +message+ to the room we're currently connected to, or
|
73
|
+
# directly to the person referenced by +to+. +to+ can be either a
|
74
|
+
# jid or the string name of the person.
|
75
|
+
def reply(message, to = nil)
|
76
|
+
if to
|
77
|
+
unless to.kind_of?(Jabber::JID)
|
78
|
+
to = find_jid_by_name(to)
|
79
|
+
end
|
80
|
+
|
81
|
+
msg = Jabber::Message.new(to || muc.room, message)
|
82
|
+
msg.type = :chat
|
83
|
+
client.send(msg)
|
84
|
+
else
|
85
|
+
muc.send(Jabber::Message.new(muc.room, message))
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Sends the chat message +message+ through +plugins+.
|
90
|
+
def handle_message(plugins, time, nick, message)
|
91
|
+
plugins.each do |plugin|
|
92
|
+
begin
|
93
|
+
rsp = plugin.handle(time, nick, message)
|
94
|
+
break if rsp == true
|
95
|
+
rescue => e
|
96
|
+
reply("I just pooped myself trying to run #{plugin.class.name}. AWK-WAAAARD!")
|
97
|
+
if config.logger
|
98
|
+
config.logger.error e
|
99
|
+
config.logger.error e.backtrace.join("\n")
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Connects to the specified room with the given credentials, and
|
106
|
+
# enters an infinite loop. Any messages sent to the room will pass
|
107
|
+
# through all the included plugins.
|
108
|
+
def connect
|
109
|
+
client.connect
|
110
|
+
client.auth(config.password)
|
111
|
+
client.send(Jabber::Presence.new.set_type(:available))
|
112
|
+
|
113
|
+
self.roster = Jabber::Roster::Helper.new(client)
|
114
|
+
roster.wait_for_roster
|
115
|
+
|
116
|
+
# Add the callback from messages that occur inside the room
|
117
|
+
muc.on_message do |time, nick, message|
|
118
|
+
plugins = Robut::Plugin.plugins.map { |p| p.new(self, nil) }
|
119
|
+
handle_message(plugins, time, nick, message)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Add the callback from direct messages. Turns out the
|
123
|
+
# on_private_message callback doesn't do what it sounds like, so I
|
124
|
+
# have to go a little deeper into xmpp4r to get this working.
|
125
|
+
client.add_message_callback(200, self) { |message|
|
126
|
+
if !muc.from_room?(message.from) && message.type == :chat && message.body
|
127
|
+
time = Time.now # TODO: get real timestamp? Doesn't seem like
|
128
|
+
# jabber gives it to us
|
129
|
+
sender_jid = message.from
|
130
|
+
plugins = Robut::Plugin.plugins.map { |p| p.new(self, sender_jid) }
|
131
|
+
handle_message(plugins, time, self.roster[sender_jid].iname, message.body)
|
132
|
+
true
|
133
|
+
else
|
134
|
+
false
|
135
|
+
end
|
136
|
+
}
|
137
|
+
|
138
|
+
muc.join(config.room + '/' + config.nick)
|
139
|
+
|
140
|
+
trap_signals
|
141
|
+
loop { sleep 1 }
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
|
146
|
+
# Since we're entering an infinite loop, we have to trap TERM and
|
147
|
+
# INT. If something like the Rdio plugin has started a server that
|
148
|
+
# has already trapped those signals, we want to run those signal
|
149
|
+
# handlers first.
|
150
|
+
def trap_signals
|
151
|
+
old_signal_callbacks = {}
|
152
|
+
signal_callback = Proc.new do |signal|
|
153
|
+
old_signal_callbacks[signal].call if old_signal_callbacks[signal]
|
154
|
+
exit
|
155
|
+
end
|
156
|
+
|
157
|
+
[:INT, :TERM].each do |sig|
|
158
|
+
old_signal_callbacks[sig] = trap(sig) { signal_callback.call(sig) }
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# Find a jid in the roster with the given name, case-insensitively
|
163
|
+
def find_jid_by_name(name)
|
164
|
+
name = name.downcase
|
165
|
+
roster.items.detect {|jid, item| item.iname.downcase == name}.first
|
166
|
+
end
|
167
|
+
end
|
data/lib/robut/plugin.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Robut plugins implement a simple interface to listen for messages
|
2
|
+
# and optionally respond to them. All plugins inherit from
|
3
|
+
# Robut::Plugin::Base.
|
4
|
+
module Robut::Plugin
|
5
|
+
autoload :Base, 'robut/plugin/base'
|
6
|
+
|
7
|
+
class << self
|
8
|
+
# A list of all available plugin classes. When you require a new
|
9
|
+
# plugin class, you should add it to this list if you want it to
|
10
|
+
# respond to messages.
|
11
|
+
attr_accessor :plugins
|
12
|
+
end
|
13
|
+
|
14
|
+
self.plugins = []
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# All Robut plugins inherit from this base class. Plugins should
|
2
|
+
# implement the +handle+ method to implement their functionality.
|
3
|
+
class Robut::Plugin::Base
|
4
|
+
|
5
|
+
# A reference to the connection attached to this instance of the
|
6
|
+
# plugin. This is mostly used to communicate back to the server.
|
7
|
+
attr_accessor :connection
|
8
|
+
|
9
|
+
# If we are handling a private message, holds a reference to the
|
10
|
+
# sender of the message. +nil+ if the message was sent to the entire
|
11
|
+
# room.
|
12
|
+
attr_accessor :private_sender
|
13
|
+
|
14
|
+
# Creates a new instance of this plugin that references the
|
15
|
+
# specified connection.
|
16
|
+
def initialize(connection, private_sender = nil)
|
17
|
+
self.connection = connection
|
18
|
+
self.private_sender = private_sender
|
19
|
+
end
|
20
|
+
|
21
|
+
# Send +message+ back to the HipChat server. If +to+ == +:room+,
|
22
|
+
# replies to the room. If +to+ == nil, responds in the manner the
|
23
|
+
# original message was sent. Otherwise, PMs the message to +to+.
|
24
|
+
def reply(message, to = nil)
|
25
|
+
if to == :room
|
26
|
+
connection.reply(message, nil)
|
27
|
+
else
|
28
|
+
connection.reply(message, to || private_sender)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# An ordered list of all words in the message with any reference to
|
33
|
+
# the bot's nick stripped out. If +command+ is passed in, it is also
|
34
|
+
# stripped out. This is useful to separate the 'parameters' from the
|
35
|
+
# 'commands' in a message.
|
36
|
+
def words(message, command = nil)
|
37
|
+
reply = at_nick
|
38
|
+
command = command.downcase if command
|
39
|
+
message.split.reject {|word| word.downcase == reply || word.downcase == command }
|
40
|
+
end
|
41
|
+
|
42
|
+
# The bot's nickname, for @-replies.
|
43
|
+
def nick
|
44
|
+
connection.config.nick.split.first
|
45
|
+
end
|
46
|
+
|
47
|
+
# #nick with the @-symbol prepended
|
48
|
+
def at_nick
|
49
|
+
"@#{nick.downcase}"
|
50
|
+
end
|
51
|
+
|
52
|
+
# Was +message+ sent to Robut as an @reply?
|
53
|
+
def sent_to_me?(message)
|
54
|
+
message =~ /(^|\s)@#{nick}(\s|$)/i
|
55
|
+
end
|
56
|
+
|
57
|
+
# Do whatever you need to do to handle this message.
|
58
|
+
# If you want to stop the plugin execution chain, return +true+ from this
|
59
|
+
# method. Plugins are handled in the order that they appear in
|
60
|
+
# Robut::Plugin.plugins
|
61
|
+
def handle(time, sender_nick, message)
|
62
|
+
raise NotImplementedError, "Implement me in #{self.class.name}!"
|
63
|
+
end
|
64
|
+
|
65
|
+
# Accessor for the store instance
|
66
|
+
def store
|
67
|
+
connection.store
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|