chatterbot 2.0.3 → 2.0.4

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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -5
  3. data/Gemfile +9 -17
  4. data/Rakefile +2 -18
  5. data/chatterbot.gemspec +10 -11
  6. data/docs/Gemfile +3 -0
  7. data/docs/README.md +3 -0
  8. data/docs/_config.yml +37 -0
  9. data/docs/_includes/footer.html +3 -0
  10. data/docs/_includes/header.html +4 -0
  11. data/docs/_includes/navigation.html +23 -0
  12. data/docs/_layouts/default.html +98 -0
  13. data/docs/_layouts/page.html +11 -0
  14. data/docs/_posts/.gitkeep +0 -0
  15. data/docs/_site/Gemfile +3 -0
  16. data/docs/_site/advanced.html +476 -0
  17. data/docs/_site/configuration.html +456 -0
  18. data/docs/_site/contributing.html +433 -0
  19. data/docs/_site/css/main.css +58 -0
  20. data/docs/_site/css/syntax.css +61 -0
  21. data/docs/_site/deploying.html +468 -0
  22. data/docs/_site/examples.html +574 -0
  23. data/docs/_site/features.html +497 -0
  24. data/docs/_site/images/01-create-application.png +0 -0
  25. data/docs/_site/images/02-application-permissions.png +0 -0
  26. data/docs/_site/images/03-mobile-number.png +0 -0
  27. data/docs/_site/images/04-access-token.png +0 -0
  28. data/docs/_site/index.html +482 -0
  29. data/docs/_site/javascripts/main.js +1 -0
  30. data/docs/_site/other-tools.html +438 -0
  31. data/docs/_site/params.json +1 -0
  32. data/docs/_site/rdoc.html +428 -0
  33. data/docs/_site/setup.html +500 -0
  34. data/docs/_site/streaming.html +506 -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 +422 -0
  38. data/docs/_site/twitter-docs.html +428 -0
  39. data/docs/_site/walkthrough.html +463 -0
  40. data/docs/advanced.md +67 -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 +53 -0
  48. data/docs/examples.md +168 -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 +70 -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/streaming.md +98 -0
  61. data/docs/stylesheets/pygment_trac.css +68 -0
  62. data/docs/stylesheets/stylesheet.css +247 -0
  63. data/docs/tips.md +22 -0
  64. data/docs/tut.md +6 -0
  65. data/docs/twitter-docs.md +6 -0
  66. data/docs/walkthrough.md +46 -0
  67. data/examples/streaming_bot.rb +11 -10
  68. data/ext/mkrf_conf.rb +28 -0
  69. data/lib/chatterbot/bot.rb +5 -1
  70. data/lib/chatterbot/config.rb +1 -1
  71. data/lib/chatterbot/home_timeline.rb +1 -1
  72. data/lib/chatterbot/streaming.rb +11 -1
  73. data/lib/chatterbot/version.rb +1 -1
  74. data/spec/spec_helper.rb +1 -4
  75. metadata +71 -122
  76. data/examples/tweet_logger.rb +0 -68
@@ -0,0 +1,67 @@
1
+ ---
2
+ layout: page
3
+ title: "Advanced Features"
4
+ category: doc
5
+ ---
6
+
7
+ Direct Client Access
8
+ --------------------
9
+
10
+ If you want to do something not provided directly by Chatterbot, you
11
+ have access to an instance of Twitter::Client provided by the
12
+ **client** method. In theory, you can do something like this in your
13
+ bot to unfollow users who DM you:
14
+
15
+ client.direct_messages_received(:since_id => since_id).each do |m|
16
+ client.unfollow(m.user.name)
17
+ end
18
+
19
+ Storing Config in the Database
20
+ ------------------------------
21
+ Sometimes it is preferable to store the authorization credentials for
22
+ your bot in a database.
23
+
24
+ Chatterbot can manage configurations that are stored in the database,
25
+ but to do this you will need to specify how to connect to the
26
+ database. You can do this by specifying the connection string
27
+ either in one of the global config files by setting
28
+
29
+ ```
30
+ :db_uri:mysql://username:password@host/database
31
+ ```
32
+
33
+ Or you can specify the connection on the command-line by using the
34
+ --db="db_uri" configuration option. Any calls to the database are
35
+ handled by the Sequel gem, and MySQL and Sqlite should work. The DB
36
+ URI should be in the form of
37
+
38
+ mysql://username:password@host/database
39
+
40
+ see http://sequel.rubyforge.org/rdoc/files/doc/opening_databases_rdoc.html
41
+ for details.
42
+
43
+
44
+ Logging Tweets to the Database
45
+ ------------------------------
46
+
47
+ Chatterbot can log tweet activity to a database if desired. This can
48
+ be handy for archival purposes, or for tracking what's going on with
49
+ your bot.
50
+
51
+ If you've configured your bot for database access, you can store a
52
+ tweet to the database by calling the `log` method like this:
53
+
54
+ ```
55
+ search "chatterbot" do |tweet|
56
+ log tweet
57
+ end
58
+ ```
59
+
60
+ See `Chatterbot::Logging` for details on this.
61
+
62
+
63
+ Streaming
64
+ ---------
65
+
66
+ Chatterbot has basic support for Twitter's Streaming API. You can read
67
+ more about it [here](streaming.html)
@@ -0,0 +1,12 @@
1
+ ---
2
+ layout: page
3
+ title: "Basics"
4
+ category: tut
5
+ published: false
6
+ ---
7
+
8
+ A bit about concepts, what you might do, ethics, etc.
9
+
10
+
11
+ basic features
12
+
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'date'
4
+ require 'optparse'
5
+
6
+ options = {
7
+ # Expects to be in the bin/ sub-directory by default
8
+ :path => File.dirname(File.dirname(__FILE__))
9
+ }
10
+
11
+ parser = OptionParser.new do |opt|
12
+ opt.banner = 'usage: jekyll-page TITLE CATEGORY [FILENAME] [OPTIONS]'
13
+ opt.separator ''
14
+ opt.separator 'Options'
15
+ opt.on('-e', '--edit', 'Edit the page') do |edit|
16
+ options[:edit] = true
17
+ end
18
+ opt.on('-l', '--link', 'Relink pages') do |link|
19
+ options[:link] = true
20
+ end
21
+ opt.on('-p PATH', '--path PATH', String, 'Path to project root') do |path|
22
+ options[:path] = path
23
+ end
24
+ opt.separator ''
25
+ end
26
+
27
+ parser.parse!
28
+
29
+ title = ARGV[0]
30
+ category = ARGV[1]
31
+ filename = ARGV[2]
32
+
33
+ # Resolve any relative links
34
+ BASE_DIR = File.expand_path(options[:path])
35
+ POSTS_DIR = "#{BASE_DIR}/_posts"
36
+ PAGES_DIR = "#{BASE_DIR}/_pages"
37
+
38
+ # Ensure the _posts directory exists (we are in the correct directory)
39
+ if not Dir.exists?(POSTS_DIR)
40
+ puts "#{POSTS_DIR} directory does not exists"
41
+ exit
42
+ end
43
+
44
+ # Create _pages directory if it doesn't exist
45
+ if not Dir.exists?(PAGES_DIR)
46
+ Dir.mkdir(PAGES_DIR)
47
+ end
48
+
49
+ if options[:link]
50
+ Dir.foreach(POSTS_DIR) do |name|
51
+ next if name[0] == '.'
52
+ nodate = name[/\d{4}-\d{2}-\d{2}-(?<rest>.*)/, 'rest']
53
+ if File.symlink?("#{PAGES_DIR}/#{nodate}")
54
+ File.delete("#{PAGES_DIR}/#{nodate}")
55
+ end
56
+ abspath = File.absolute_path("#{POSTS_DIR}/#{name}")
57
+ File.symlink(abspath, "#{PAGES_DIR}/#{nodate}")
58
+ end
59
+ end
60
+
61
+ if not title or not category
62
+ # This flag can be used by itself, exit silently if no arguments
63
+ # are defined
64
+ if not options[:link]
65
+ puts parser
66
+ end
67
+ exit
68
+ end
69
+
70
+ if not filename
71
+ filename = title.downcase.gsub(/[^a-z0-9\s]/, '').gsub(/\s+/, '-')
72
+ end
73
+
74
+ today=Date.today().strftime('%F')
75
+ now=DateTime.now().strftime('%F %T')
76
+
77
+ filepath = "#{POSTS_DIR}/#{today}-#{filename}.md"
78
+ symlink = "#{PAGES_DIR}/#{filename}.md"
79
+
80
+ if File.exists?(filepath)
81
+ puts "File #{filepath} already exists"
82
+ exit
83
+ end
84
+
85
+ content = <<END
86
+ ---
87
+ layout: page
88
+ title: \"#{title}\"
89
+ category: #{category}
90
+ date: #{now}
91
+ ---
92
+
93
+
94
+ END
95
+
96
+ File.open(filepath, 'w') do |file|
97
+ file.puts content
98
+ end
99
+
100
+ File.symlink(File.absolute_path(filepath), symlink)
101
+
102
+ if options[:edit]
103
+ if not ENV['EDITOR']
104
+ puts 'No $EDITOR variable set'
105
+ exit
106
+ end
107
+ puts ENV['EDITOR']
108
+ exec("#{ENV['EDITOR']} #{filename}")
109
+ end
@@ -0,0 +1,32 @@
1
+ ---
2
+ layout: page
3
+ title: "Configuration"
4
+ category: doc
5
+ ---
6
+
7
+ You will need to store some information for your bot. This includes
8
+ the OAuth credentials, timestamps, etc. Chatterbot offers a whole
9
+ bunch of different methods of storing the config for your bot:
10
+
11
+ 1. Your credentials can be stored as variables in the script itself.
12
+ If you generate a bot via `chatterbot-register`, the file will have
13
+ these variables specified. However, if your bot source code is
14
+ going to be public, you should NOT do this. Anyone who has your
15
+ credentials can do nasty things with your Twitter account. Also, if
16
+ your bot is using replies or searches, chatterbot will need to
17
+ track some state information, and that data will be written to a
18
+ YAML file.
19
+ 2. In a YAML file with the same name as the bot, so if you have
20
+ botname.rb or a Botname class, store your config in botname.yaml.
21
+ `chatterbot-register` will also create this file. If you are using
22
+ git or another source code control system, you should **NOT** store
23
+ this file! It will be updated every time your bots run.
24
+ 3. In a global config file at `/etc/chatterbot.yml` -- values stored here
25
+ will apply to any bots you run.
26
+ 4. In another global config file specified in the environment variable
27
+ `'chatterbot_config'`.
28
+ 5. In a `global.yml` file in the same directory as your bot. This
29
+ gives you the ability to have a global configuration file, but keep
30
+ it with your bots if desired.
31
+ 6. In a database. You can read more about this on the [Advanced
32
+ Features](advanced.html) page
@@ -0,0 +1,14 @@
1
+ ---
2
+ layout: page
3
+ title: "Contributing"
4
+ category: dev
5
+ ---
6
+
7
+ Bug fixes, features, etc are eagerly welcomed. Since this code is
8
+ being used to run current Twitter bots, any changes need to maintain
9
+ compatibility. If there are bugs or things you would like to improve,
10
+ fork the project and hack away. I'll pull anything back that makes
11
+ sense if requested.
12
+
13
+
14
+
@@ -0,0 +1,58 @@
1
+ body {
2
+ font-weight: 400;
3
+ text-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);
4
+ }
5
+
6
+ pre, code {
7
+ border: none;
8
+ border-radius: 0;
9
+ background-color: #f9f9f9;
10
+ font-size: 0.85em;
11
+ }
12
+
13
+ pre {
14
+ font-size: 1em;
15
+ }
16
+
17
+ code {
18
+ color: inherit;
19
+ }
20
+
21
+ #header {
22
+ border-bottom: 1px solid #eee;
23
+ margin-bottom: 20px;
24
+ }
25
+
26
+ #header a:hover {
27
+ text-decoration: none;
28
+ }
29
+
30
+ #footer {
31
+ margin: 20px 0;
32
+ font-size: 0.85em;
33
+ color: #999;
34
+ text-align: center;
35
+ }
36
+
37
+ #content > .page-header:first-child {
38
+ margin-top: 0;
39
+ }
40
+
41
+ #content > .page-header:first-child h2 {
42
+ margin-top: 0;
43
+ }
44
+
45
+
46
+ #navigation {
47
+ font-size: 0.9em;
48
+ }
49
+
50
+ #navigation li a {
51
+ padding-left: 10px;
52
+ padding-right: 10px;
53
+ }
54
+
55
+ #navigation .nav-header {
56
+ padding-left: 0;
57
+ padding-right: 0;
58
+ }
@@ -0,0 +1,61 @@
1
+ .highlight .hll { background-color: #ffffcc }
2
+ .highlight { background: #ffffff; }
3
+ .highlight .c { color: #888888 } /* Comment */
4
+ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
5
+ .highlight .k { color: #008800; font-weight: bold } /* Keyword */
6
+ .highlight .cm { color: #888888 } /* Comment.Multiline */
7
+ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
8
+ .highlight .c1 { color: #888888 } /* Comment.Single */
9
+ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
10
+ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
11
+ .highlight .ge { font-style: italic } /* Generic.Emph */
12
+ .highlight .gr { color: #aa0000 } /* Generic.Error */
13
+ .highlight .gh { color: #333333 } /* Generic.Heading */
14
+ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
15
+ .highlight .go { color: #888888 } /* Generic.Output */
16
+ .highlight .gp { color: #555555 } /* Generic.Prompt */
17
+ .highlight .gs { font-weight: bold } /* Generic.Strong */
18
+ .highlight .gu { color: #666666 } /* Generic.Subheading */
19
+ .highlight .gt { color: #aa0000 } /* Generic.Traceback */
20
+ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
21
+ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
22
+ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
23
+ .highlight .kp { color: #008800 } /* Keyword.Pseudo */
24
+ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
25
+ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
26
+ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
27
+ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
28
+ .highlight .na { color: #336699 } /* Name.Attribute */
29
+ .highlight .nb { color: #003388 } /* Name.Builtin */
30
+ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
31
+ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
32
+ .highlight .nd { color: #555555 } /* Name.Decorator */
33
+ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
34
+ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
35
+ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */
36
+ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
37
+ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */
38
+ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
39
+ .highlight .nv { color: #336699 } /* Name.Variable */
40
+ .highlight .ow { color: #008800 } /* Operator.Word */
41
+ .highlight .w { color: #bbbbbb } /* Text.Whitespace */
42
+ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
43
+ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
44
+ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
45
+ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
46
+ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
47
+ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
48
+ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
49
+ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
50
+ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
51
+ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
52
+ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
53
+ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
54
+ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
55
+ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
56
+ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
57
+ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
58
+ .highlight .vc { color: #336699 } /* Name.Variable.Class */
59
+ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */
60
+ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */
61
+ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
@@ -0,0 +1,53 @@
1
+ ---
2
+ layout: page
3
+ title: "Running your Bot"
4
+ category: doc
5
+ ---
6
+
7
+ There's a couple ways of running your bot:
8
+
9
+ Manually
10
+ --------
11
+
12
+ Run it on the command-line whenever you like. Whee!
13
+
14
+
15
+ Cron
16
+ ----
17
+ Run it via cron. Here's an example of running a bot every two minutes
18
+
19
+ */2 * * * * . ~/.bash_profile; cd /path/to/bot/; ./bot.rb
20
+
21
+ Looping
22
+ -------
23
+ Run it as a background process. Just put the guts of your bot in a loop like this:
24
+
25
+ ```rb
26
+ loop do
27
+ search "twitter" do |tweet|
28
+ # here you could do something with a tweet
29
+ # if you want to retweet
30
+ retweet(tweet[:id])
31
+ end
32
+
33
+ replies do |tweet|
34
+ # do stuff
35
+ end
36
+
37
+ # explicitly update our config
38
+ update_config
39
+
40
+ sleep 60
41
+ end
42
+ ```
43
+
44
+ **NOTE:** You need to call `update_config` to update the last tweet your script
45
+ has processed -- if you don't have this call, you will get duplicate
46
+ tweets.
47
+
48
+ Streaming
49
+ ---------
50
+
51
+ Chatterbot has rough support for the Streaming API. If your bot can
52
+ use it, it's a great option, because you get your data immediately.
53
+ You can read more about setting up a bot to use [streaming](streaming.html).
@@ -0,0 +1,168 @@
1
+ ---
2
+ layout: page
3
+ title: "Examples"
4
+ category: tut
5
+ ---
6
+
7
+ Here's a couple examples of working bots.
8
+
9
+ @echoes_bot
10
+ -----------
11
+
12
+ This is a working bot. It responds to any mentions with the incoming
13
+ text:
14
+
15
+ <blockquote class="twitter-tweet" lang="en"><p><a href="https://twitter.com/muffinista">@muffinista</a> hello there!</p>&mdash; Echo Echo (@echoes_bot) <a href="https://twitter.com/echoes_bot/status/515166110950256640">September 25, 2014</a></blockquote>
16
+ <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
17
+
18
+ Here's the code. This is right out of the git repo for chatterbot:
19
+
20
+ ```
21
+ ## This is a very simple working example of a bot you can build with
22
+ ## chatterbot. It looks for mentions of '@echoes_bot' (the twitter
23
+ ## handle the bot uses), and sends replies with the name switched to
24
+ ## the handle of the sending user
25
+
26
+ #
27
+ # require the dsl lib to include all the methods you see below.
28
+ #
29
+ require 'rubygems'
30
+ require 'chatterbot/dsl'
31
+
32
+ puts "Loading echoes_bot.rb"
33
+
34
+ ##
35
+ ## If I wanted to exclude some terms from triggering this bot, I would list them here.
36
+ ## For now, we'll block URLs to keep this from being a source of spam
37
+ ##
38
+ exclude "http://"
39
+
40
+ blacklist "mean_user, private_user"
41
+
42
+ puts "checking for replies to me"
43
+ replies do |tweet|
44
+ # replace the incoming username with #USER#, which will be replaced
45
+ # with the handle of the user who tweeted us by the
46
+ # replace_variables helper
47
+ src = tweet.text.gsub(/@echoes_bot/, "#USER#")
48
+
49
+ # send it back!
50
+ reply src, tweet
51
+ end
52
+ ```
53
+
54
+
55
+ @SpaceJamCheck
56
+ --------------
57
+
58
+ This is another working bot. It checks the website for the movie Space
59
+ Jam to see if it is still online (it does this by using the spacejam
60
+ gem), and tweets the results of that check.
61
+
62
+
63
+ ```
64
+ #!/usr/bin/env ruby
65
+
66
+ require 'rubygems'
67
+ require 'bundler/setup'
68
+
69
+ require 'chatterbot/dsl'
70
+ require 'spacejam'
71
+
72
+ #
73
+ # this is the script for the twitter bot SpaceJamCheck
74
+ # generated on 2013-11-04 16:24:46 -0500
75
+ #
76
+
77
+ consumer_key 'key'
78
+ consumer_secret 'secret'
79
+
80
+ secret 'secret'
81
+ token 'token'
82
+
83
+
84
+ check_url = "http://www2.warnerbros.com/spacejam/movie/jam.htm"
85
+ check_string = "<title>Space Jam</title>"
86
+
87
+ uptime_messages = [
88
+ "Hooray! Space Jam is still online!",
89
+ "It's #{Time.now.year} and the Space Jam website is still online",
90
+ "In case you were worried, Space Jam is still online",
91
+ "Looks like the Space Jam website is still there",
92
+ "Yes",
93
+ "Yep",
94
+ "Still Kickin",
95
+ "The Space Jam website is still online",
96
+ "Still Online"
97
+ ]
98
+
99
+ downtime_messages = [
100
+ "Hmm, looks like Space Jam isn't online. Hopefully it's a fluke ;("
101
+ ]
102
+
103
+
104
+ x = Spacejam::HTTPCheck.new(url:check_url, body:check_string)
105
+
106
+ # pick a random tweet according to the website status
107
+ result = if x.online?
108
+ uptime_messages
109
+ else
110
+ downtime_messages
111
+ end.sample
112
+
113
+ # add a timestamp. this helps to prevent duplicate tweet issues
114
+ result << " (#{Time.now.utc})"
115
+
116
+ # tweet it out!
117
+ tweet result
118
+ ```
119
+
120
+
121
+ Streaming Bot
122
+ --------------
123
+
124
+
125
+ ```
126
+ #!/usr/bin/env ruby
127
+
128
+ ## This is a very simple working example of a bot using the streaming
129
+ ## API. It's basically a copy of echoes_bot.rb, just using streaming.
130
+
131
+ #
132
+ # require the dsl lib to include all the methods you see below.
133
+ #
134
+ require 'rubygems'
135
+ require 'chatterbot/dsl'
136
+
137
+ consumer_secret 'foo'
138
+ secret 'bar'
139
+ token 'biz'
140
+ consumer_key 'bam'
141
+
142
+
143
+ puts "Loading echoes_bot.rb using the streaming API"
144
+
145
+ exclude "http://", "https://"
146
+
147
+ blacklist "mean_user, private_user"
148
+
149
+ streaming do
150
+ favorited do |user, tweet|
151
+ reply "@#{user.screen_name} thanks for the fave!", tweet
152
+ end
153
+
154
+ followed do |user|
155
+ tweet "@#{user.screen_name} just followed me!"
156
+ follow user
157
+ end
158
+
159
+ replies do |tweet|
160
+ favorite tweet
161
+
162
+ puts "It's a tweet!"
163
+ src = tweet.text.gsub(/@echoes_bot/, "#USER#")
164
+ reply src, tweet
165
+ end
166
+ end
167
+
168
+ ```