chatterbot 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +52 -0
- data/Gemfile +25 -0
- data/LICENSE.txt +17 -0
- data/README.rdoc +184 -0
- data/Rakefile +26 -0
- data/bin/chatterbot-blacklist +63 -0
- data/chatterbot.gemspec +53 -0
- data/examples/class_bot.rb +9 -0
- data/examples/config.yml.example +6 -0
- data/examples/dsl_test.rb +9 -0
- data/examples/echoes_bot.rb +27 -0
- data/lib/chatterbot.rb +50 -0
- data/lib/chatterbot/blacklist.rb +69 -0
- data/lib/chatterbot/bot.rb +29 -0
- data/lib/chatterbot/client.rb +123 -0
- data/lib/chatterbot/config.rb +259 -0
- data/lib/chatterbot/db.rb +70 -0
- data/lib/chatterbot/dsl.rb +100 -0
- data/lib/chatterbot/helpers.rb +29 -0
- data/lib/chatterbot/logging.rb +48 -0
- data/lib/chatterbot/reply.rb +28 -0
- data/lib/chatterbot/search.rb +35 -0
- data/lib/chatterbot/tweet.rb +25 -0
- data/lib/chatterbot/version.rb +3 -0
- data/spec/blacklist_spec.rb +115 -0
- data/spec/bot_spec.rb +5 -0
- data/spec/client_spec.rb +60 -0
- data/spec/config_spec.rb +204 -0
- data/spec/db_spec.rb +33 -0
- data/spec/dsl_spec.rb +73 -0
- data/spec/helpers_spec.rb +40 -0
- data/spec/logging_spec.rb +65 -0
- data/spec/reply_spec.rb +54 -0
- data/spec/search_spec.rb +72 -0
- data/spec/spec_helper.rb +52 -0
- data/spec/tweet_spec.rb +76 -0
- data/specs.watchr +60 -0
- metadata +162 -0
data/.document
ADDED
data/.gitignore
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
Gemfile.lock
|
2
|
+
|
3
|
+
# rcov generated
|
4
|
+
coverage
|
5
|
+
|
6
|
+
# rdoc generated
|
7
|
+
rdoc
|
8
|
+
|
9
|
+
# yard generated
|
10
|
+
doc
|
11
|
+
.yardoc
|
12
|
+
|
13
|
+
# bundler
|
14
|
+
.bundle
|
15
|
+
|
16
|
+
# jeweler generated
|
17
|
+
pkg
|
18
|
+
|
19
|
+
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
20
|
+
#
|
21
|
+
# * Create a file at ~/.gitignore
|
22
|
+
# * Include files you want ignored
|
23
|
+
# * Run: git config --global core.excludesfile ~/.gitignore
|
24
|
+
#
|
25
|
+
# After doing this, these files will be ignored in all your git projects,
|
26
|
+
# saving you from having to 'pollute' every project you touch with them
|
27
|
+
#
|
28
|
+
# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
|
29
|
+
#
|
30
|
+
# For MacOS:
|
31
|
+
#
|
32
|
+
#.DS_Store
|
33
|
+
|
34
|
+
# For TextMate
|
35
|
+
#*.tmproj
|
36
|
+
#tmtags
|
37
|
+
|
38
|
+
# For emacs:
|
39
|
+
#*~
|
40
|
+
#\#*
|
41
|
+
#.\#*
|
42
|
+
|
43
|
+
# For vim:
|
44
|
+
#*.swp
|
45
|
+
|
46
|
+
# For redcar:
|
47
|
+
#.redcar
|
48
|
+
|
49
|
+
# For rubinius:
|
50
|
+
#*.rbc
|
51
|
+
|
52
|
+
examples/*.yml
|
data/Gemfile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
source :rubygems
|
2
|
+
gemspec
|
3
|
+
|
4
|
+
#gem "twitter_oauth"
|
5
|
+
#gem "sequel"
|
6
|
+
|
7
|
+
# Add dependencies to develop your gem here.
|
8
|
+
# Include everything needed to run rake, tests, features, etc.
|
9
|
+
group :development do
|
10
|
+
gem "shoulda", ">= 0"
|
11
|
+
gem "rspec"
|
12
|
+
|
13
|
+
gem "bundler", "~> 1.0.0"
|
14
|
+
gem "rcov"
|
15
|
+
gem "watchr"
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# couple extra gems for testing db connectivity
|
20
|
+
#
|
21
|
+
group :test do
|
22
|
+
gem "sequel"
|
23
|
+
gem "mysql"
|
24
|
+
gem "sqlite3"
|
25
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
DO WHAT THE FUCK YOU WANT TO -- BUT DON'T BE AN ASSHOLE PUBLIC LICENSE
|
2
|
+
|
3
|
+
Version 1, May 2011
|
4
|
+
|
5
|
+
Copyright (C) 2011 Colin Mitchell <colin@muffinlabs.com>
|
6
|
+
Derived from WTFPL, Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
7
|
+
|
8
|
+
Everyone is permitted to copy and distribute verbatim or modified
|
9
|
+
copies of this license document, and changing it is allowed as long
|
10
|
+
as the name is changed.
|
11
|
+
|
12
|
+
DO WHAT THE FUCK YOU WANT TO -- BUT DON'T BE AN ASSHOLE PUBLIC LICENSE
|
13
|
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
14
|
+
|
15
|
+
0. You just DO WHAT THE FUCK YOU WANT TO.
|
16
|
+
1. Don't be an asshole. Really.
|
17
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
= Chatterbot
|
2
|
+
|
3
|
+
Chatterbot is a Ruby library for making bots on Twitter. It is basic
|
4
|
+
enough that you can put it into use quickly, but can be used to make
|
5
|
+
pretty involved bots. It handles searches, replies and tweets, and has
|
6
|
+
a simple blacklist system to help keep you from spamming people who
|
7
|
+
don't want to hear from your bot.
|
8
|
+
|
9
|
+
== A quick list of features:
|
10
|
+
|
11
|
+
* Works via Twitter's OAuth system.
|
12
|
+
* Handles search queries and replies to your bot
|
13
|
+
* Use a simple DSL, or extend a Bot class if you need it
|
14
|
+
* Simple blacklistling system to limit your annoyance of users
|
15
|
+
* Optionally log tweets to the database for metrics and tracking purposes
|
16
|
+
|
17
|
+
== Using Chatterbot
|
18
|
+
|
19
|
+
=== Make a Twitter account
|
20
|
+
|
21
|
+
First thing you'll need to do is create an account for your bot on
|
22
|
+
Twitter. That's the easy part.
|
23
|
+
|
24
|
+
=== Write your bot
|
25
|
+
|
26
|
+
Chatterbot has a very simple DSL inspired by Sinatra and Twibot, an
|
27
|
+
earlier Twitter bot framework. Here's an example, based on @dr_rumack
|
28
|
+
on Twitter (http://twitter.com/#!/Dr_Rumack):
|
29
|
+
|
30
|
+
require 'chatterbot/dsl'
|
31
|
+
search("'surely you must be joking'") do |tweet|
|
32
|
+
reply "@#{tweet_user(tweet)} I am serious, and don't call me Shirley!", tweet
|
33
|
+
end
|
34
|
+
|
35
|
+
Or, you can create a bot object yourself, extend it if needed, and use
|
36
|
+
it like so:
|
37
|
+
|
38
|
+
bot = Chatterbot::Bot.new
|
39
|
+
bot.search("'surely you must be joking'") do |tweet|
|
40
|
+
bot.reply "@#{tweet_user(tweet)} I am serious, and don't call me Shirley!", tweet
|
41
|
+
end
|
42
|
+
|
43
|
+
That's it!
|
44
|
+
|
45
|
+
=== Authorize your bot
|
46
|
+
|
47
|
+
If you only want to use Chatterbot to search for tweets, it will work
|
48
|
+
out of the box without any authorization. However, if you want to
|
49
|
+
reply to tweets, or check for replies to your bot, you will have to
|
50
|
+
jump through a few authorization hoops with Twitter. The very
|
51
|
+
first time you want to setup a bot, you will need to register an
|
52
|
+
application with Twitter. Twitter requires all API communication to be via an
|
53
|
+
app which is registered on Twitter. I would set one up and make it
|
54
|
+
part of Chatterbot, but unfortunately Twitter doesn't allow developers
|
55
|
+
to publicly post the OAuth consumer key/secret that you would need to
|
56
|
+
use. If you're planning to run more than one bot, you only need to do
|
57
|
+
this step once -- you can use the same app setup for other bots too.
|
58
|
+
|
59
|
+
Chatterbot will walk you through what is needed to get this setup. If
|
60
|
+
you run your bot without having an app setup, it will prompt you with
|
61
|
+
the instructions. Here's the instructions if you want to do it yourself:
|
62
|
+
|
63
|
+
1. Setup your own app on Twitter at this URL https://twitter.com/apps/new
|
64
|
+
2. Choose 'Client' as the app type
|
65
|
+
3. Choose 'Read & Write' access unless you don't need to send tweets.
|
66
|
+
4. Take the consumer key/consumer secret values, and either run your
|
67
|
+
bot, and enter them in when prompted, or store them in a config
|
68
|
+
file for your bot. (See below for details on this). It should look
|
69
|
+
like this:
|
70
|
+
|
71
|
+
---
|
72
|
+
:consumer_secret: CONSUMER SECRET GOES HERE
|
73
|
+
:consumer_key: CONSUMER KEY GOES HERE
|
74
|
+
|
75
|
+
Chatterbot will point you at the URL in Step #1, then ask for the
|
76
|
+
same values as in Step #4.
|
77
|
+
|
78
|
+
Once this is done, you will need to setup authorization for the actual
|
79
|
+
bot with Twitter. At the first run, you'll get a message asking you to go
|
80
|
+
to a Twitter URL, where you can authorize the bot to post messages for
|
81
|
+
your account or not. If you accept, you'll get a PIN number back.
|
82
|
+
You need to copy this and paste it back into the prompt for the
|
83
|
+
bot. Hit return, and you should be all set.
|
84
|
+
|
85
|
+
This is obviously a bunch of effort, but once you're done, you're
|
86
|
+
ready to go!
|
87
|
+
|
88
|
+
=== Configuration
|
89
|
+
|
90
|
+
Chatterbot offers a couple different methods of storing the config for
|
91
|
+
your bot:
|
92
|
+
|
93
|
+
1. In a YAML file with the same name as the bot, so if you have
|
94
|
+
botname.rb or a Botname class, store your config in botname.yaml
|
95
|
+
2. In a global config file at <tt>/etc/chatterbot.yml</tt> -- values stored here
|
96
|
+
will apply to any bots you run.
|
97
|
+
3. In another global config file specified in the environment variable
|
98
|
+
<tt>'chatterbot_config'</tt>.
|
99
|
+
4. In a <tt>global.yml</tt> file in the same directory as your bot. This
|
100
|
+
gives you the ability to have a global configuration file, but keep
|
101
|
+
it with your bots if desired.
|
102
|
+
5. In a database. You can store your configuration in a DB, and then
|
103
|
+
specify the connection string either in one of the global config
|
104
|
+
files, or on the command-line by using the <tt>--db="db_uri"</tt>
|
105
|
+
configuration option. Any calls to the database are handled by the
|
106
|
+
Sequel gem, and MySQL and Sqlite should work. The DB URI should
|
107
|
+
be in the form of <tt>mysql://username:password@host/database</tt> -- see
|
108
|
+
http://sequel.rubyforge.org/rdoc/files/doc/opening_databases_rdoc.html
|
109
|
+
for details.
|
110
|
+
|
111
|
+
=== Running Your Bot
|
112
|
+
|
113
|
+
There's a couple ways of running your bot:
|
114
|
+
|
115
|
+
Run it on the command-line whenever you like. Whee!
|
116
|
+
|
117
|
+
Run it via cron. Here's an example of running a bot every two minutes
|
118
|
+
|
119
|
+
*/2 * * * * . ~/.bash_profile; cd /path/to/bot/; ./bot.rb
|
120
|
+
|
121
|
+
Run it as a background process. Just put the guts of your bot in a loop like this:
|
122
|
+
loop do
|
123
|
+
replies do |tweet|
|
124
|
+
# do stuff
|
125
|
+
end
|
126
|
+
|
127
|
+
sleep 60
|
128
|
+
end
|
129
|
+
|
130
|
+
=== Database logging
|
131
|
+
|
132
|
+
Chatterbot can log tweet activity to the database if desired. This
|
133
|
+
can be handy for tracking what's going on with your bot. See
|
134
|
+
<tt>Chatterbot::Logging</tt> for details on this.
|
135
|
+
|
136
|
+
|
137
|
+
=== Blacklists
|
138
|
+
|
139
|
+
Not everyone wants to hear from your bot. To keep annoyances to a
|
140
|
+
minimum, Chatterbot has a global blacklist option, as well as
|
141
|
+
bot-specific blacklists if desired. The global blacklist is stored in
|
142
|
+
the database, and you can add entries to it by using the
|
143
|
+
<tt>chatterbot-blacklist</tt> script included with the gem.
|
144
|
+
|
145
|
+
You can also specify users to skip as part of the DSL:
|
146
|
+
|
147
|
+
require 'chatterbot'
|
148
|
+
blacklist "mean_user, private_user"
|
149
|
+
|
150
|
+
There's also an 'exclude' method which can be used to add
|
151
|
+
words/phrases you might want to ignore -- for example, if you wanted
|
152
|
+
to ignore tweets with links, you could do something like this:
|
153
|
+
|
154
|
+
exclude "http://"
|
155
|
+
|
156
|
+
== TODO
|
157
|
+
|
158
|
+
* A skeleton bot generator
|
159
|
+
* web-based frontend for tracking bot activity
|
160
|
+
* opt-out system that adds people to blacklist if they reply to a bot
|
161
|
+
in the right way
|
162
|
+
|
163
|
+
== Contributing to Chatterbot
|
164
|
+
|
165
|
+
Since this code is based off of actual Twitter bots, it's mostly
|
166
|
+
working the way I want it to, and I might prefer to keep it that way.
|
167
|
+
But please, if there are bugs or things you would like to improve,
|
168
|
+
fork the project and hack away. I'll pull anything back that makes
|
169
|
+
sense if requested.
|
170
|
+
|
171
|
+
|
172
|
+
== Copyright/License
|
173
|
+
|
174
|
+
Copyright (c) 2011 Colin Mitchell. Chatterbot is distributed under a
|
175
|
+
modified WTFPL licence -- it's the 'Do what the fuck you want to --
|
176
|
+
but don't be an asshole' public license. Please see LICENSE.txt for
|
177
|
+
further details. Basically, do whatever you want with this code, but
|
178
|
+
don't be an asshole about it. If you spam users inappropriately,
|
179
|
+
expect your karma to suffer.
|
180
|
+
|
181
|
+
|
182
|
+
http://muffinlabs.com
|
183
|
+
|
184
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require "chatterbot/version"
|
5
|
+
|
6
|
+
require 'rspec/core'
|
7
|
+
require 'rspec/core/rake_task'
|
8
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
9
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
10
|
+
end
|
11
|
+
|
12
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
13
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
14
|
+
spec.rcov_opts = %w{--exclude .bundler,.rvm}
|
15
|
+
spec.rcov = true
|
16
|
+
end
|
17
|
+
|
18
|
+
task :default => :spec
|
19
|
+
|
20
|
+
require 'rdoc/task'
|
21
|
+
Rake::RDocTask.new do |rdoc|
|
22
|
+
rdoc.main = "README.rdoc"
|
23
|
+
rdoc.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
24
|
+
rdoc.rdoc_dir = 'rdoc'
|
25
|
+
rdoc.title = "'chatterbot #{Chatterbot::VERSION}'"
|
26
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
3
|
+
|
4
|
+
require 'chatterbot'
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
include Chatterbot::Helpers
|
8
|
+
include Chatterbot::Blacklist
|
9
|
+
include Chatterbot::Config
|
10
|
+
include Chatterbot::DB
|
11
|
+
include Chatterbot::Logging
|
12
|
+
|
13
|
+
@display_blacklist = false
|
14
|
+
|
15
|
+
#
|
16
|
+
# pull in any arguments and set them as env variables
|
17
|
+
#
|
18
|
+
opts = OptionParser.new
|
19
|
+
opts.banner = "Usage: #{File.basename($0)} [options]"
|
20
|
+
|
21
|
+
opts.separator ""
|
22
|
+
opts.separator "Specific options:"
|
23
|
+
|
24
|
+
opts.on('-d', '--db [ARG]', "Specify a DB connection URI") { |d| ENV["chatterbot_db"] = d }
|
25
|
+
opts.on('-c', '--config [ARG]', "Specify a config file to use") { |c| ENV["chatterbot_config"] = c }
|
26
|
+
opts.on('-p', '--print', "Print out the current blacklist") { @display_blacklist = true }
|
27
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
28
|
+
puts opts
|
29
|
+
exit
|
30
|
+
end
|
31
|
+
|
32
|
+
extra = opts.parse!(ARGV)
|
33
|
+
|
34
|
+
if ! has_db?
|
35
|
+
puts "You need to specify a db connection!"
|
36
|
+
exit
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
if @display_blacklist
|
41
|
+
db[:blacklist].each do |u|
|
42
|
+
puts u.inspect
|
43
|
+
end
|
44
|
+
|
45
|
+
elsif extra.empty?
|
46
|
+
#
|
47
|
+
# iterate through STDIN and add anything to the blacklist. nothing too shiny here.
|
48
|
+
#
|
49
|
+
$stdin.each_line do |l|
|
50
|
+
add_to_blacklist(l.chomp)
|
51
|
+
end
|
52
|
+
else
|
53
|
+
#
|
54
|
+
# add any users specified on the command-line
|
55
|
+
#
|
56
|
+
extra.each do |l|
|
57
|
+
add_to_blacklist(l.chomp)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
|
data/chatterbot.gemspec
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "chatterbot/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = %q{chatterbot}
|
7
|
+
s.version = Chatterbot::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Colin Mitchell"]
|
10
|
+
s.email = %q{colin@muffinlabs.com}
|
11
|
+
s.homepage = %q{http://github.com/muffinista/chatterbot}
|
12
|
+
s.summary = %q{A framework for writing Twitter bots}
|
13
|
+
s.description = %q{A framework for writing bots that run on Twitter. Comes with a simple DSL for easy coding.}
|
14
|
+
|
15
|
+
s.rubyforge_project = "chatterbot"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
s.licenses = ["WTFDBAL"]
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
s.specification_version = 3
|
25
|
+
|
26
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
27
|
+
s.add_runtime_dependency(%q<twitter_oauth>, [">= 0"])
|
28
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
29
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
30
|
+
s.add_development_dependency(%q<rdoc>, [">= 0"])
|
31
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
32
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
33
|
+
s.add_development_dependency(%q<watchr>, [">= 0"])
|
34
|
+
else
|
35
|
+
s.add_dependency(%q<twitter_oauth>, [">= 0"])
|
36
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
37
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
38
|
+
s.add_dependency(%q<rdoc>, [">= 0"])
|
39
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
40
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
41
|
+
s.add_dependency(%q<watchr>, [">= 0"])
|
42
|
+
end
|
43
|
+
else
|
44
|
+
s.add_dependency(%q<twitter_oauth>, [">= 0"])
|
45
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
46
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
47
|
+
s.add_dependency(%q<rdoc>, [">= 0"])
|
48
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
49
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
50
|
+
s.add_dependency(%q<watchr>, [">= 0"])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|