chatterbot 2.0.2 → 2.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.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +19 -0
- data/Gemfile +9 -17
- data/README.markdown +10 -23
- data/Rakefile +2 -18
- data/chatterbot.gemspec +17 -12
- data/docs/Gemfile +3 -0
- data/docs/README.md +3 -0
- data/docs/_config.yml +37 -0
- data/docs/_includes/footer.html +3 -0
- data/docs/_includes/header.html +4 -0
- data/docs/_includes/navigation.html +23 -0
- data/docs/_layouts/default.html +98 -0
- data/docs/_layouts/page.html +11 -0
- data/docs/_posts/.gitkeep +0 -0
- data/docs/_site/Gemfile +3 -0
- data/docs/_site/advanced.html +465 -0
- data/docs/_site/configuration.html +436 -0
- data/docs/_site/contributing.html +414 -0
- data/docs/_site/css/main.css +58 -0
- data/docs/_site/css/syntax.css +61 -0
- data/docs/_site/deploying.html +451 -0
- data/docs/_site/examples.html +559 -0
- data/docs/_site/features.html +496 -0
- data/docs/_site/images/01-create-application.png +0 -0
- data/docs/_site/images/02-application-permissions.png +0 -0
- data/docs/_site/images/03-mobile-number.png +0 -0
- data/docs/_site/images/04-access-token.png +0 -0
- data/docs/_site/index.html +461 -0
- data/docs/_site/javascripts/main.js +1 -0
- data/docs/_site/other-tools.html +419 -0
- data/docs/_site/params.json +1 -0
- data/docs/_site/rdoc.html +409 -0
- data/docs/_site/setup.html +491 -0
- data/docs/_site/stylesheets/pygment_trac.css +68 -0
- data/docs/_site/stylesheets/stylesheet.css +247 -0
- data/docs/_site/tut.html +402 -0
- data/docs/_site/twitter-docs.html +409 -0
- data/docs/_site/walkthrough.html +447 -0
- data/docs/advanced.md +62 -0
- data/docs/basics.md +12 -0
- data/docs/bin/jekyll-page +109 -0
- data/docs/configuration.md +32 -0
- data/docs/contributing.md +14 -0
- data/docs/css/main.css +58 -0
- data/docs/css/syntax.css +61 -0
- data/docs/deploying.md +47 -0
- data/docs/examples.md +120 -0
- data/docs/features.md +88 -0
- data/docs/images/01-create-application.png +0 -0
- data/docs/images/02-application-permissions.png +0 -0
- data/docs/images/03-mobile-number.png +0 -0
- data/docs/images/04-access-token.png +0 -0
- data/docs/index.md +69 -0
- data/docs/javascripts/main.js +1 -0
- data/docs/other-tools.md +17 -0
- data/docs/params.json +1 -0
- data/docs/rdoc.md +6 -0
- data/docs/setup.md +84 -0
- data/docs/stylesheets/pygment_trac.css +68 -0
- data/docs/stylesheets/stylesheet.css +247 -0
- data/docs/tips.md +22 -0
- data/docs/tut.md +6 -0
- data/docs/twitter-docs.md +6 -0
- data/docs/walkthrough.md +46 -0
- data/lib/chatterbot.rb +0 -1
- data/lib/chatterbot/bot.rb +7 -67
- data/lib/chatterbot/client.rb +2 -9
- data/lib/chatterbot/config.rb +1 -2
- data/lib/chatterbot/dsl.rb +20 -47
- data/lib/chatterbot/home_timeline.rb +1 -1
- data/lib/chatterbot/search.rb +26 -3
- data/lib/chatterbot/skeleton.rb +0 -2
- data/lib/chatterbot/tweet.rb +13 -3
- data/lib/chatterbot/ui.rb +0 -1
- data/lib/chatterbot/version.rb +1 -1
- data/spec/bot_spec.rb +1 -76
- data/spec/client_spec.rb +0 -3
- data/spec/config_manager_spec.rb +6 -5
- data/spec/config_spec.rb +4 -1
- data/spec/dsl_spec.rb +10 -35
- data/spec/fixtures/update_with_media.png +0 -0
- data/spec/search_spec.rb +40 -1
- data/spec/spec_helper.rb +1 -4
- data/spec/tweet_spec.rb +74 -34
- data/templates/skeleton.txt +0 -47
- metadata +81 -135
- data/.document +0 -5
- data/.travis.yml +0 -11
- data/examples/streaming_bot.rb +0 -48
- data/examples/tweet_logger.rb +0 -68
- data/lib/chatterbot/streaming.rb +0 -62
- data/spec/streaming_spec.rb +0 -172
data/docs/tips.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "Tips and Tricks"
|
4
|
+
category: doc
|
5
|
+
published: false
|
6
|
+
---
|
7
|
+
|
8
|
+
setting profile data
|
9
|
+
|
10
|
+
resetting since_id/since_id_reply
|
11
|
+
|
12
|
+
deleting tweets
|
13
|
+
|
14
|
+
making sure a user is following your bot
|
15
|
+
|
16
|
+
posting images
|
17
|
+
|
18
|
+
running multiple searches
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
|
data/docs/tut.md
ADDED
data/docs/walkthrough.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "Walkthrough"
|
4
|
+
category: tut
|
5
|
+
---
|
6
|
+
|
7
|
+
Make a Twitter account
|
8
|
+
----------------------
|
9
|
+
|
10
|
+
First thing you'll need to do is create an account for your bot on
|
11
|
+
Twitter. That's the easy part.
|
12
|
+
|
13
|
+
Run the generator
|
14
|
+
-----------------
|
15
|
+
|
16
|
+
Chatterbot comes with a script named `chatterbot-register` which will
|
17
|
+
handle two tasks -- it will authorize your bot with Twitter and it
|
18
|
+
will generate a skeleton script, which you use to implement your
|
19
|
+
actual bot.
|
20
|
+
|
21
|
+
When you run `chatterbot-register` it will walk you through the
|
22
|
+
authorization process. If you prefer, you can do this manually. If
|
23
|
+
you'd like to learn more about it, you can read the
|
24
|
+
[Authorizing your Bot](setup.html) section.
|
25
|
+
|
26
|
+
Write your bot
|
27
|
+
--------------
|
28
|
+
|
29
|
+
Chatterbot is written in ruby, but it accepts some very simple
|
30
|
+
scripting commands which can handle almost everything you might need
|
31
|
+
to do on Twitter. You can get some ideas of things you can do on the
|
32
|
+
[Examples](examples.html) page.
|
33
|
+
|
34
|
+
require 'chatterbot/dsl'
|
35
|
+
search("'surely you must be joking'") do |tweet|
|
36
|
+
reply "@#{tweet_user(tweet)} I am serious, and don't call me Shirley!", tweet
|
37
|
+
end
|
38
|
+
|
39
|
+
Or, you can create a bot object yourself, extend it if needed, and use it like so:
|
40
|
+
|
41
|
+
bot = Chatterbot::Bot.new
|
42
|
+
bot.search("'surely you must be joking'") do |tweet|
|
43
|
+
bot.reply "@#{tweet_user(tweet)} I am serious, and don't call me Shirley!", tweet
|
44
|
+
end
|
45
|
+
|
46
|
+
That's it!
|
data/lib/chatterbot.rb
CHANGED
data/lib/chatterbot/bot.rb
CHANGED
@@ -5,7 +5,6 @@ module Chatterbot
|
|
5
5
|
# primary Bot object, includes all the other modules
|
6
6
|
class Bot
|
7
7
|
include Utils
|
8
|
-
include Streaming
|
9
8
|
include Blocklist
|
10
9
|
include Safelist
|
11
10
|
include Config
|
@@ -26,9 +25,6 @@ module Chatterbot
|
|
26
25
|
# handlers that can use the REST API
|
27
26
|
HANDLER_CALLS = [:direct_messages, :home_timeline, :replies, :search]
|
28
27
|
|
29
|
-
# handlers that require the Streaming API
|
30
|
-
STREAMING_ONLY_HANDLERS = [:favorited, :followed, :deleted]
|
31
|
-
|
32
28
|
#
|
33
29
|
# Create a new bot. No options for now.
|
34
30
|
def initialize(params={})
|
@@ -46,7 +42,7 @@ module Chatterbot
|
|
46
42
|
|
47
43
|
at_exit do
|
48
44
|
if !@handlers.empty? && @run_count <= 0 && skip_run? != true
|
49
|
-
|
45
|
+
run!
|
50
46
|
end
|
51
47
|
|
52
48
|
raise $! if $!
|
@@ -54,58 +50,10 @@ module Chatterbot
|
|
54
50
|
@handlers = {}
|
55
51
|
end
|
56
52
|
|
57
|
-
|
58
|
-
|
59
|
-
#
|
60
|
-
def run_or_stream
|
61
|
-
@run_count += 1
|
62
|
-
if streaming?
|
63
|
-
stream!
|
64
|
-
else
|
65
|
-
run!
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
#
|
70
|
-
# run the bot with the Streaming API
|
71
|
-
#
|
72
|
-
def stream!
|
73
|
-
before_run
|
74
|
-
|
75
|
-
#
|
76
|
-
# figure out how we want to call streaming client
|
77
|
-
#
|
78
|
-
if @handlers[:search]
|
79
|
-
method = :filter
|
80
|
-
args = streamify_search_options(@handlers[:search].opts)
|
81
|
-
else
|
82
|
-
method = :user
|
83
|
-
args = {
|
84
|
-
stall_warnings: "true"
|
85
|
-
}
|
86
|
-
end
|
87
|
-
|
88
|
-
|
89
|
-
streaming_client.send(method, args) do |object|
|
90
|
-
handle_streaming_object(object)
|
91
|
-
end
|
92
|
-
after_run
|
53
|
+
def screen_name
|
54
|
+
@screen_name ||= client.settings.screen_name
|
93
55
|
end
|
94
56
|
|
95
|
-
#
|
96
|
-
# the REST API and Streaming API have a slightly different format.
|
97
|
-
# tweak our search handler to switch from REST to Streaming
|
98
|
-
#
|
99
|
-
def streamify_search_options(opts)
|
100
|
-
if opts.is_a?(String)
|
101
|
-
{ track: opts }
|
102
|
-
elsif opts.is_a?(Array)
|
103
|
-
{ track: opts.join(", ") }
|
104
|
-
else
|
105
|
-
opts
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
57
|
#
|
110
58
|
# run the bot with the REST API
|
111
59
|
#
|
@@ -114,7 +62,6 @@ module Chatterbot
|
|
114
62
|
|
115
63
|
HANDLER_CALLS.each { |c|
|
116
64
|
if (h = @handlers[c])
|
117
|
-
puts "calling #{c} #{h.opts.inspect}"
|
118
65
|
send(c, *(h.opts)) do |obj|
|
119
66
|
h.call(obj)
|
120
67
|
end
|
@@ -134,24 +81,17 @@ module Chatterbot
|
|
134
81
|
end
|
135
82
|
|
136
83
|
def call_api_immediately?
|
137
|
-
|
84
|
+
true
|
138
85
|
end
|
139
86
|
|
140
87
|
def register_handler(method, opts = nil, &block)
|
141
88
|
# @todo raise error if method already defined
|
142
89
|
@handlers[method] = Handler.new(opts, &block)
|
143
90
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
elsif call_api_immediately?
|
148
|
-
@run_count += 1
|
149
|
-
h = @handlers[method]
|
150
|
-
self.send(method, *(h.opts)) do |obj|
|
151
|
-
h.call(obj)
|
152
|
-
end
|
91
|
+
h = @handlers[method]
|
92
|
+
self.send(method, *(h.opts)) do |obj|
|
93
|
+
h.call(obj)
|
153
94
|
end
|
154
|
-
|
155
95
|
end
|
156
96
|
end
|
157
97
|
end
|
data/lib/chatterbot/client.rb
CHANGED
@@ -6,7 +6,7 @@ module Chatterbot
|
|
6
6
|
# routines for connecting to Twitter and validating the bot
|
7
7
|
#
|
8
8
|
module Client
|
9
|
-
attr_accessor :screen_name, :client
|
9
|
+
attr_accessor :screen_name, :client
|
10
10
|
|
11
11
|
#
|
12
12
|
# the main interface to the Twitter API
|
@@ -14,14 +14,7 @@ module Chatterbot
|
|
14
14
|
def client
|
15
15
|
@client ||= Twitter::REST::Client.new(client_params)
|
16
16
|
end
|
17
|
-
|
18
|
-
#
|
19
|
-
# interace to the Streaming API
|
20
|
-
#
|
21
|
-
def streaming_client
|
22
|
-
@streaming_client ||= Twitter::Streaming::Client.new(client_params)
|
23
|
-
end
|
24
|
-
|
17
|
+
|
25
18
|
#
|
26
19
|
# return the currently authenticated User
|
27
20
|
#
|
data/lib/chatterbot/config.rb
CHANGED
@@ -55,7 +55,6 @@ module Chatterbot
|
|
55
55
|
|
56
56
|
attr_boolean :debug_mode, false
|
57
57
|
attr_boolean :verbose, false
|
58
|
-
attr_boolean :streaming, false
|
59
58
|
attr_boolean :skip_run, false
|
60
59
|
attr_boolean :only_interact_with_followers, false
|
61
60
|
|
@@ -212,7 +211,7 @@ module Chatterbot
|
|
212
211
|
:consumer_key => ENV["chatterbot_consumer_key"],
|
213
212
|
:consumer_secret => ENV["chatterbot_consumer_secret"],
|
214
213
|
:access_token => ENV["chatterbot_access_token"],
|
215
|
-
:access_token_secret => ENV["chatterbot_access_secret"]
|
214
|
+
:access_token_secret => ENV["chatterbot_access_secret"] || ENV["chatterbot_access_token_secret"]
|
216
215
|
}.delete_if { |k, v| v.nil? }.merge(slurp_file(config_file) || {})
|
217
216
|
end
|
218
217
|
|
data/lib/chatterbot/dsl.rb
CHANGED
@@ -14,6 +14,10 @@ module Chatterbot
|
|
14
14
|
#
|
15
15
|
# search twitter for the specified terms, then pass any matches to
|
16
16
|
# the block.
|
17
|
+
# NOTE: by default, search terms are wrapped in quotes so the
|
18
|
+
# Twitter API will return tweets that include your exact query.
|
19
|
+
# You can disable this by passing exact:false as an option
|
20
|
+
#
|
17
21
|
# @param args [Hash] options. these will be passed directly to
|
18
22
|
# Twitter via the twitter gem. You can see the possible arguments
|
19
23
|
# at http://www.rubydoc.info/gems/twitter/Twitter/REST/Search#search-instance_method
|
@@ -66,55 +70,17 @@ module Chatterbot
|
|
66
70
|
bot.register_handler(:direct_messages, block)
|
67
71
|
end
|
68
72
|
|
69
|
-
|
70
|
-
#
|
71
|
-
# handle notifications of bot tweets favorited by other users.
|
72
|
-
# Using this block will require usage of the Streaming API.
|
73
|
-
#
|
74
|
-
# @example
|
75
|
-
# favorited do |tweet|
|
76
|
-
# puts tweet.text # this is the actual tweeted text
|
77
|
-
# reply "@#{user.screen_name} thanks for the fave!", tweet
|
78
|
-
# end
|
79
|
-
def favorited(&block)
|
80
|
-
bot.register_handler(:favorited, block)
|
81
|
-
end
|
82
|
-
|
83
|
-
#
|
84
|
-
# handle notifications that the bot has a new follower.
|
85
|
-
# Using this block will require usage of the Streaming API.
|
86
|
-
#
|
87
|
-
# @example
|
88
|
-
# followed do |user|
|
89
|
-
# follow user
|
90
|
-
# end
|
91
|
-
def followed(&block)
|
92
|
-
bot.register_handler(:followed, block)
|
93
|
-
end
|
94
|
-
|
95
|
-
#
|
96
|
-
# handle notifications of tweets on the bot's timeline that were deleted.
|
97
|
-
# Using this block will require usage of the Streaming API.
|
98
|
-
def deleted(&block)
|
99
|
-
bot.register_handler(:deleted, block)
|
100
|
-
end
|
101
|
-
|
102
|
-
|
103
|
-
#
|
104
|
-
# enable or disable usage of the Streaming API
|
105
|
-
#
|
106
|
-
def use_streaming(s=nil)
|
107
|
-
s = true if s.nil?
|
108
|
-
bot.streaming = s
|
109
|
-
end
|
110
|
-
|
111
|
-
|
112
73
|
#
|
113
74
|
# send a tweet
|
114
75
|
#
|
115
76
|
# @param [String] txt the text you want to tweet
|
116
|
-
# @param [Hash] params
|
117
|
-
#
|
77
|
+
# @param [Hash] params options for the tweet. You can get an idea
|
78
|
+
# of possible values you can send here from the underlying Twitter
|
79
|
+
# gem docs: http://rdoc.info/gems/twitter/Twitter/API#update-instance_method
|
80
|
+
# @option params [String,File] :media Optional file object to send
|
81
|
+
# with the tweet. Must be an image or video that will be accepted by
|
82
|
+
# Twitter. You can pass a File object, or the path to a file
|
83
|
+
# @see http://rdoc.info/gems/twitter/Twitter/API#update-instance_method
|
118
84
|
# @param [Tweet] original if this is a reply, the original tweet. this will
|
119
85
|
# be used for variable substitution, and for logging
|
120
86
|
def tweet(txt, params = {}, original = nil)
|
@@ -141,8 +107,15 @@ module Chatterbot
|
|
141
107
|
#
|
142
108
|
# @param [String] txt the text you want to tweet
|
143
109
|
# @param [Tweet] source the original tweet you are replying to
|
144
|
-
|
145
|
-
|
110
|
+
# @param [Hash] params options for the tweet. You can get an idea
|
111
|
+
# of possible values you can send here from the underlying Twitter
|
112
|
+
# gem docs: http://rdoc.info/gems/twitter/Twitter/API#update-instance_method
|
113
|
+
# @option params [String,File] :media Optional file object to send with the
|
114
|
+
# tweet. Must be an image or video that will be accepted by
|
115
|
+
# Twitter. You can pass a File object, or the path to a file
|
116
|
+
# @see http://rdoc.info/gems/twitter/Twitter/API#update-instance_method
|
117
|
+
def reply(txt, source, params={})
|
118
|
+
bot.reply(txt, source, params)
|
146
119
|
end
|
147
120
|
|
148
121
|
#
|
@@ -7,7 +7,7 @@ module Chatterbot
|
|
7
7
|
# handle the bots timeline
|
8
8
|
def home_timeline(*args, &block)
|
9
9
|
return unless require_login
|
10
|
-
debug "check for home_timeline tweets since #{
|
10
|
+
debug "check for home_timeline tweets since #{since_id_home_timeline}"
|
11
11
|
|
12
12
|
opts = {
|
13
13
|
:since_id => since_id_home_timeline,
|
data/lib/chatterbot/search.rb
CHANGED
@@ -24,25 +24,47 @@ module Chatterbot
|
|
24
24
|
@skip_retweets = false
|
25
25
|
end
|
26
26
|
|
27
|
-
|
27
|
+
|
28
28
|
#
|
29
29
|
# check if this is a retweet that we want to skip
|
30
30
|
#
|
31
31
|
def skippable_retweet?(t)
|
32
32
|
@skip_retweets && t.retweeted_status?
|
33
33
|
end
|
34
|
+
|
35
|
+
def wrap_search_query(q)
|
36
|
+
if q =~ / /
|
37
|
+
['"', q.gsub(/^"/, '').gsub(/"$/, ''), '"'].join("")
|
38
|
+
else
|
39
|
+
q
|
40
|
+
end
|
41
|
+
end
|
34
42
|
|
35
43
|
# internal search code
|
36
44
|
def search(queries, opts = {}, &block)
|
37
45
|
debug "check for tweets since #{since_id}"
|
38
46
|
|
39
47
|
max_tweets = opts.delete(:limit) || MAX_SEARCH_TWEETS
|
48
|
+
exact_match = if opts.key?(:exact)
|
49
|
+
opts.delete(:exact)
|
50
|
+
else
|
51
|
+
true
|
52
|
+
end
|
53
|
+
|
40
54
|
|
41
55
|
if queries.is_a?(String)
|
42
|
-
queries = [
|
56
|
+
queries = [
|
57
|
+
queries
|
58
|
+
]
|
43
59
|
end
|
44
60
|
|
45
|
-
query = queries.
|
61
|
+
query = queries.map { |q|
|
62
|
+
if exact_match == true
|
63
|
+
q = wrap_search_query(q)
|
64
|
+
end
|
65
|
+
|
66
|
+
q
|
67
|
+
}.join(" OR ")
|
46
68
|
|
47
69
|
#
|
48
70
|
# search twitter
|
@@ -50,6 +72,7 @@ module Chatterbot
|
|
50
72
|
|
51
73
|
debug "search: #{query} #{default_opts.merge(opts)}"
|
52
74
|
@current_tweet = nil
|
75
|
+
|
53
76
|
client.search( query, default_opts.merge(opts) ).take(max_tweets).each { |s|
|
54
77
|
update_since_id(s)
|
55
78
|
debug s.text
|
data/lib/chatterbot/skeleton.rb
CHANGED
data/lib/chatterbot/tweet.rb
CHANGED
@@ -13,7 +13,16 @@ module Chatterbot
|
|
13
13
|
debug "I'm in debug mode, otherwise I would tweet: #{txt}"
|
14
14
|
else
|
15
15
|
debug txt
|
16
|
-
|
16
|
+
if params.has_key?(:media)
|
17
|
+
file = params.delete(:media)
|
18
|
+
if ! file.is_a?(File)
|
19
|
+
file = File.new(file)
|
20
|
+
end
|
21
|
+
|
22
|
+
client.update_with_media txt, file, params
|
23
|
+
else
|
24
|
+
client.update txt, params
|
25
|
+
end
|
17
26
|
end
|
18
27
|
rescue Twitter::Error::Forbidden => e
|
19
28
|
#:nocov:
|
@@ -24,9 +33,10 @@ module Chatterbot
|
|
24
33
|
|
25
34
|
|
26
35
|
# reply to a tweet
|
27
|
-
def reply(txt, source)
|
36
|
+
def reply(txt, source, params = {})
|
28
37
|
debug txt
|
29
|
-
|
38
|
+
params = {:in_reply_to_status_id => source.id}.merge(params)
|
39
|
+
tweet txt, params, source
|
30
40
|
end
|
31
41
|
end
|
32
42
|
end
|