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.
Files changed (93) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +19 -0
  3. data/Gemfile +9 -17
  4. data/README.markdown +10 -23
  5. data/Rakefile +2 -18
  6. data/chatterbot.gemspec +17 -12
  7. data/docs/Gemfile +3 -0
  8. data/docs/README.md +3 -0
  9. data/docs/_config.yml +37 -0
  10. data/docs/_includes/footer.html +3 -0
  11. data/docs/_includes/header.html +4 -0
  12. data/docs/_includes/navigation.html +23 -0
  13. data/docs/_layouts/default.html +98 -0
  14. data/docs/_layouts/page.html +11 -0
  15. data/docs/_posts/.gitkeep +0 -0
  16. data/docs/_site/Gemfile +3 -0
  17. data/docs/_site/advanced.html +465 -0
  18. data/docs/_site/configuration.html +436 -0
  19. data/docs/_site/contributing.html +414 -0
  20. data/docs/_site/css/main.css +58 -0
  21. data/docs/_site/css/syntax.css +61 -0
  22. data/docs/_site/deploying.html +451 -0
  23. data/docs/_site/examples.html +559 -0
  24. data/docs/_site/features.html +496 -0
  25. data/docs/_site/images/01-create-application.png +0 -0
  26. data/docs/_site/images/02-application-permissions.png +0 -0
  27. data/docs/_site/images/03-mobile-number.png +0 -0
  28. data/docs/_site/images/04-access-token.png +0 -0
  29. data/docs/_site/index.html +461 -0
  30. data/docs/_site/javascripts/main.js +1 -0
  31. data/docs/_site/other-tools.html +419 -0
  32. data/docs/_site/params.json +1 -0
  33. data/docs/_site/rdoc.html +409 -0
  34. data/docs/_site/setup.html +491 -0
  35. data/docs/_site/stylesheets/pygment_trac.css +68 -0
  36. data/docs/_site/stylesheets/stylesheet.css +247 -0
  37. data/docs/_site/tut.html +402 -0
  38. data/docs/_site/twitter-docs.html +409 -0
  39. data/docs/_site/walkthrough.html +447 -0
  40. data/docs/advanced.md +62 -0
  41. data/docs/basics.md +12 -0
  42. data/docs/bin/jekyll-page +109 -0
  43. data/docs/configuration.md +32 -0
  44. data/docs/contributing.md +14 -0
  45. data/docs/css/main.css +58 -0
  46. data/docs/css/syntax.css +61 -0
  47. data/docs/deploying.md +47 -0
  48. data/docs/examples.md +120 -0
  49. data/docs/features.md +88 -0
  50. data/docs/images/01-create-application.png +0 -0
  51. data/docs/images/02-application-permissions.png +0 -0
  52. data/docs/images/03-mobile-number.png +0 -0
  53. data/docs/images/04-access-token.png +0 -0
  54. data/docs/index.md +69 -0
  55. data/docs/javascripts/main.js +1 -0
  56. data/docs/other-tools.md +17 -0
  57. data/docs/params.json +1 -0
  58. data/docs/rdoc.md +6 -0
  59. data/docs/setup.md +84 -0
  60. data/docs/stylesheets/pygment_trac.css +68 -0
  61. data/docs/stylesheets/stylesheet.css +247 -0
  62. data/docs/tips.md +22 -0
  63. data/docs/tut.md +6 -0
  64. data/docs/twitter-docs.md +6 -0
  65. data/docs/walkthrough.md +46 -0
  66. data/lib/chatterbot.rb +0 -1
  67. data/lib/chatterbot/bot.rb +7 -67
  68. data/lib/chatterbot/client.rb +2 -9
  69. data/lib/chatterbot/config.rb +1 -2
  70. data/lib/chatterbot/dsl.rb +20 -47
  71. data/lib/chatterbot/home_timeline.rb +1 -1
  72. data/lib/chatterbot/search.rb +26 -3
  73. data/lib/chatterbot/skeleton.rb +0 -2
  74. data/lib/chatterbot/tweet.rb +13 -3
  75. data/lib/chatterbot/ui.rb +0 -1
  76. data/lib/chatterbot/version.rb +1 -1
  77. data/spec/bot_spec.rb +1 -76
  78. data/spec/client_spec.rb +0 -3
  79. data/spec/config_manager_spec.rb +6 -5
  80. data/spec/config_spec.rb +4 -1
  81. data/spec/dsl_spec.rb +10 -35
  82. data/spec/fixtures/update_with_media.png +0 -0
  83. data/spec/search_spec.rb +40 -1
  84. data/spec/spec_helper.rb +1 -4
  85. data/spec/tweet_spec.rb +74 -34
  86. data/templates/skeleton.txt +0 -47
  87. metadata +81 -135
  88. data/.document +0 -5
  89. data/.travis.yml +0 -11
  90. data/examples/streaming_bot.rb +0 -48
  91. data/examples/tweet_logger.rb +0 -68
  92. data/lib/chatterbot/streaming.rb +0 -62
  93. 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
@@ -0,0 +1,6 @@
1
+ ---
2
+ layout: default
3
+ title: "Setup"
4
+ ---
5
+
6
+ setting up your bot!
@@ -0,0 +1,6 @@
1
+ ---
2
+ layout: page
3
+ title: "Twitter API docs"
4
+ category: links
5
+ link: https://dev.twitter.com/rest/public
6
+ ---
@@ -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
@@ -45,7 +45,6 @@ module Chatterbot
45
45
  require "chatterbot/followers"
46
46
  require "chatterbot/helpers"
47
47
  require "chatterbot/utils"
48
- require "chatterbot/streaming"
49
48
 
50
49
  require "chatterbot/bot"
51
50
  end
@@ -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
- run_or_stream
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
- # determine the right API to use and run the bot
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
- !streaming?
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
- if STREAMING_ONLY_HANDLERS.include?(method)
145
- puts "Forcing usage of Streaming API to support #{method} calls"
146
- self.streaming = true
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
@@ -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, :streaming_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
  #
@@ -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
 
@@ -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 opts for the tweet
117
- # @see http://rdoc.info/gems/twitter/Twitter/API#update-instance_method
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
- def reply(txt, source)
145
- bot.reply(txt, source)
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 #{since_id}"
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,
@@ -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 = [queries]
56
+ queries = [
57
+ queries
58
+ ]
43
59
  end
44
60
 
45
- query = queries.join(" OR ")
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
@@ -18,8 +18,6 @@ module Chatterbot
18
18
  :timestamp => Time.now
19
19
  })
20
20
 
21
- puts opts.inspect
22
-
23
21
  src % opts
24
22
  end
25
23
  end
@@ -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
- client.update txt, params
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
- tweet txt, {:in_reply_to_status_id => source.id}, source
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