hashtag_retweet_bot 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,8 @@
1
+ bin/hashtag_retweet_bot
2
+ create_db_table.rb
3
+ feed.rb
4
+ hashtag_retweet_bot.gemspec
5
+ lib/bot.rb
6
+ Manifest
7
+ Rakefile
8
+ README.markdown
@@ -0,0 +1,77 @@
1
+ # Hashtag retweet bot
2
+
3
+ A bot that retweets all tweets tagged by a certain hashtag. Ideal for conferences, meetup groups, communities, etc.
4
+
5
+ As an example, let's say you want to retweet every tweet found with the hashtag #icecream every 5 minutes (300 seconds). This ruby gem will let you do it as easily as running:
6
+
7
+ hashtag_retweet_bot icecream 300
8
+
9
+ ## Installation
10
+
11
+ gem install hashtag_retweet_bot
12
+
13
+ Create the database:
14
+
15
+ mysqladmin create my_conference_db
16
+
17
+ Create a directory where you will run the bot from, and a config directory with 2 files in it: _database.yml_ for your database settings and either
18
+ * _oauth.yml_ to make the bot use OAuth (RECOMMENDED)
19
+ * _bot.yml_ for the login/password of the twitter account (DEPRECATED)
20
+
21
+ mkdir -p bot_for_my_conference/config
22
+ cd config/bot_for_my_conference
23
+ touch database.yml
24
+
25
+ If you want to use OAuth, register a new application on Twitter and put in consumer key (token) and secret in _oauth.yml_:
26
+ consumer:
27
+ token: my_apps_consumer_key
28
+ secret: my_apps_consumer_secrets
29
+
30
+ Don't worry now about request and access token/secret pairs, the bot will guide you the first time you launch it. And every time access token/secret will become invalid and need re-creating (as of June 2010, Twitter is not expiring access tokens, but they can be invalidated by removing the app).
31
+
32
+ If you want to use HTTP Auth (it's DEPRECATED by Twitter and will be no longer supported after August 2010), put the credentials for the twitter account in _bot.yml_:
33
+
34
+ login: my_conference_bot
35
+ password: secret
36
+
37
+ Put the database connection attributes in _database.yml_:
38
+
39
+ adapter: mysql
40
+ username: root
41
+ host: localhost
42
+ password:
43
+ database: my_conference_db
44
+
45
+ And create the table on the database that will hold the tweets:
46
+
47
+ hashtag_retweet_bot create_db_table
48
+
49
+ ## Run it
50
+
51
+ Now the only thing left to do is running the bot, telling it what tag to follow, like that:
52
+
53
+ hashtag_retweet_bot tag_to_follow
54
+
55
+ This will launch the bot with a default pause of 180 seconds. If you want a different time schedule you can specify other value for the seconds parameter, but I've experienced Twitter connection problems when trying to update every 60 seconds or less:
56
+
57
+ hashtag_retweet_bot tag_to_follow seconds_between_updates
58
+
59
+ Example:
60
+
61
+ hashtag_retweet_bot icecream
62
+ hashtag_retweet_bot icecream 240
63
+
64
+ ## Live examples
65
+
66
+ Some twitterbots using hashtag_retweet_bot:
67
+
68
+ * [@euruko_bot](http://twitter.com/euruko_bot)
69
+ * [@confrorbot](http://twitter.com/confrorbot)
70
+ * [The bot for the Budapest Ruby User Group](http://twitter.com/budapestrb)
71
+
72
+ ## Credits
73
+
74
+ Original idea and script by [Mark Connell](http://github.com/mconnell) for Scotland on Rails 2009. Customization for Euruko '09, and some improvements by [Jaime Iniesta](http://github.com/jaimeiniesta). Some improvements and gemification by [Balint Erdi](http://github.com/balinterdi).
75
+ Customization for Euruko '10 and further work (OAuth support, refactoring etc.) by [Tomasz Stachewicz](http://github.com/tomash)
76
+
77
+ Please send feedback and bug reports to <balint.erdi@gmail.com>
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('hashtag_retweet_bot', '0.1.3') do |p|
6
+ p.description = "Script that listens to a tag and retweets messages with that tag. Originally made for Scotland on Rails '09 by Mark Connell (http://github.com/rubaidh)"
7
+ p.url = "http://github.com/jaimeiniesta/hashtag_retweet_bot"
8
+ p.author = "Jaime Iniesta"
9
+ p.email = "jaimeiniesta@gmail.com"
10
+ p.ignore_pattern = ["tmp/*", "config/*", "script/*", "*.txt", "pkg"]
11
+ p.development_dependencies = ["twibot >=0.1.7", "activerecord", "pauldix-feedzirra >=0.0.12"]
12
+ p.runtime_dependencies = ["twibot >=0.1.7", "activerecord", "pauldix-feedzirra >=0.0.12"]
13
+ end
14
+
15
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'bot')
4
+
5
+ if ARGV.length < 1
6
+ puts "Usage: hashtag_retweet_bot [tag_to_watch] [seconds_between_updates]"
7
+ puts "If you haven't created the database table, run:"
8
+ puts "hashtag_retweet_bot create_db_table"
9
+ exit
10
+ end
11
+
12
+ tag = ARGV[0]
13
+ seconds = ARGV[1] || 180
14
+ if tag.downcase == 'create_db_table'
15
+ puts "Creating the database"
16
+ require File.join(File.dirname(__FILE__), '..', 'create_db_table')
17
+ else
18
+ puts "Launching the twitterbot to track \##{tag} every #{seconds} seconds"
19
+ bot = HashtagRetweetBot.new(tag, seconds.to_i)
20
+ bot.run
21
+ end
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'active_record'
3
+ require 'yaml'
4
+
5
+ adapter_attrs = YAML.load(File.open('config/database.yml') { |f| f.read })
6
+ ActiveRecord::Base.establish_connection(adapter_attrs)
7
+
8
+ ActiveRecord::Schema.define do
9
+ create_table(:tweets, :force => true) do |t|
10
+ t.string :twitter_id
11
+ t.datetime :published
12
+ t.string :link
13
+ t.string :title
14
+ t.string :content
15
+ t.string :author_name
16
+ t.string :author_uri
17
+ t.boolean :tweeted
18
+ end
19
+ end
data/feed.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'feedzirra' # feed helper
3
+
4
+ feed = Feedzirra::Feed.fetch_and_parse("http://search.twitter.com/search.atom?q=+%23euruko")
5
+
6
+ feed.entries.each do |entry|
7
+
8
+ puts "entry #{entry.inspect}"
9
+
10
+ end
@@ -0,0 +1,50 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{hashtag_retweet_bot}
5
+ s.version = "0.2.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Balint Erdi", "Jaime Iniesta", "Tomasz Stachewicz"]
9
+ s.date = %q{2010-06-19}
10
+ s.default_executable = %q{hashtag_retweet_bot}
11
+ s.description = %q{Script that listens to a tag and retweets messages with that tag. Supports both OAuth and HTTPAuth authentication strategies. Retweets using Twitter's native RT feature. Originally made for Scotland on Rails '09 by Mark Connell (http://github.com/rubaidh). Refactored and reworked after Euruko '10 by Tomasz Stachewicz (http://github.com/tomash)}
12
+ s.email = %q{t.stachewicz@gmail.com}
13
+ s.executables = ["hashtag_retweet_bot"]
14
+ s.extra_rdoc_files = ["bin/hashtag_retweet_bot", "lib/bot.rb", "README.markdown"]
15
+ s.files = ["bin/hashtag_retweet_bot", "create_db_table.rb", "feed.rb", "hashtag_retweet_bot.gemspec", "lib/bot.rb", "Manifest", "Rakefile", "README.markdown"]
16
+ s.homepage = %q{http://github.com/tomash/hashtag_retweet_bot}
17
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Hashtag_retweet_bot", "--main", "README.markdown"]
18
+ s.require_paths = ["lib"]
19
+ s.rubyforge_project = %q{hashtag_retweet_bot}
20
+ s.rubygems_version = %q{1.3.3}
21
+ s.summary = %q{Script that listens to a tag and retweets messages with that tag.}
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 3
26
+
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
+ s.add_runtime_dependency(%q<twitter>, [">= 0.9.7"])
29
+ s.add_runtime_dependency(%q<activerecord>, [">= 0"])
30
+ s.add_runtime_dependency(%q<feedzirra>, [">= 0.0.23"])
31
+ s.add_development_dependency(%q<twitter>, [">= 0.9.7"])
32
+ s.add_development_dependency(%q<activerecord>, [">= 0"])
33
+ s.add_development_dependency(%q<feedzirra>, [">= 0.0.23"])
34
+ else
35
+ s.add_dependency(%q<twitter>, [">= 0.9.7"])
36
+ s.add_dependency(%q<activerecord>, [">= 0"])
37
+ s.add_dependency(%q<feedzirra>, [">= 0.0.23"])
38
+ s.add_dependency(%q<twitter>, [">= 0.9.7"])
39
+ s.add_dependency(%q<activerecord>, [">= 0"])
40
+ s.add_dependency(%q<feedzirra>, [">= 0.0.23"])
41
+ end
42
+ else
43
+ s.add_dependency(%q<twitter>, [">= 0.9.7"])
44
+ s.add_dependency(%q<activerecord>, [">= 0"])
45
+ s.add_dependency(%q<feedzirra>, [">= 0.0.23"])
46
+ s.add_dependency(%q<twitter>, [">= 0.9.7"])
47
+ s.add_dependency(%q<activerecord>, [">= 0"])
48
+ s.add_dependency(%q<feedzirra>, [">= 0.0.23"])
49
+ end
50
+ end
@@ -0,0 +1,123 @@
1
+ require "rubygems"
2
+
3
+ require 'active_record' # db
4
+ require 'feedzirra' # feed helper
5
+ require 'yaml'
6
+ require 'twitter'
7
+ require File.join(File.dirname(__FILE__), 'hash')
8
+
9
+ class Tweets < ActiveRecord::Base
10
+ end
11
+
12
+ ###
13
+ # What we want the bot to do
14
+ ###
15
+ # 1. Listen to an rss feed and store that stuff
16
+ # 2. Work out which tweets need to be tweeted by the bot
17
+ # 3. send the tweets and mark them as 'tweeted'
18
+ # 4. repeat ad nauseam every x seconds (as indicated, 180 is recommended)
19
+ #
20
+
21
+ class HashtagRetweetBot
22
+ def initialize(tag, seconds=180)
23
+ @tag = tag
24
+ @seconds = seconds
25
+ @client = nil
26
+ end
27
+
28
+ def authorize
29
+ if(File.exist?('config/oauth.yml'))
30
+ puts "Found config/oauth.yml, using OAuth."
31
+ authorize_using_oauth
32
+ elsif(File.exist?('config/bot.yml'))
33
+ puts "Using HTTP Auth (DEPRECATED)."
34
+ authorize_using_httpauth
35
+ else
36
+ puts "No config file (neither oauth.yml nor bot.yml) found in config/, exiting..."
37
+ exit
38
+ end
39
+ end
40
+
41
+ def authorize_using_oauth
42
+ oauth_config = YAML.load(File.open('config/oauth.yml') { |f| f.read }).symbolize_keys!
43
+ oauth = Twitter::OAuth.new(oauth_config[:consumer][:token], oauth_config[:consumer][:secret])
44
+ oauth.authorize_from_access(oauth_config[:access][:token], oauth_config[:access][:secret])
45
+
46
+ @client = Twitter::Base.new(oauth)
47
+ puts "Logged in successfully using OAuth, bot should be working now."
48
+ #@client.update("Heyo from OAuth app at #{Time.now}")
49
+ rescue Twitter::Unauthorized
50
+ puts "It seems the access token are no longer valid, we need to get new ones."
51
+ regenerate_oauth(oauth_config)
52
+ end
53
+
54
+ def authorize_using_httpauth
55
+ http_config = YAML.load(File.open('config/bot.yml') { |f| f.read }).symbolize_keys!
56
+ httpauth = Twitter::HTTPAuth.new(http_config[:login], http_config[:password])
57
+ @client = Twitter::Base.new(httpauth)
58
+ puts "Logged in successfully using HTTP Auth, bot should be working now."
59
+ #@client.update("Heyo from HTTP Auth app at #{Time.now}")
60
+ end
61
+
62
+ def regenerate_oauth(oauth_config)
63
+ oauth = Twitter::OAuth.new(oauth_config[:consumer][:token], oauth_config[:consumer][:secret])
64
+ request_token = oauth.request_token
65
+ puts request_token.authorize_url
66
+ puts "Visit the above link, grant access and type in PIN: "
67
+ STDOUT.flush
68
+ pin = STDIN.gets.chomp
69
+ access_token = request_token.get_access_token(:oauth_verifier => pin)
70
+
71
+ oauth_config[:access] = {:token => access_token.token, :secret => access_token.secret}
72
+
73
+ File.open('config/oauth.yml', 'w') { |f| YAML.dump(oauth_config, f)}
74
+ puts "New access token saved, please re-run the bot."
75
+ end
76
+
77
+
78
+ def run
79
+ authorize
80
+
81
+ adapter_attrs = YAML.load(File.open('config/database.yml') { |f| f.read })
82
+ ActiveRecord::Base.establish_connection(adapter_attrs)
83
+
84
+ feed_thread = Thread.new do
85
+ while(true != false)
86
+ begin
87
+ # fetch the feed
88
+ feed = get_tweets_tagged_with(@tag)
89
+ feed.entries.reverse.each do |entry|
90
+ tweet = Tweets.find_or_create_by_twitter_id(
91
+ :twitter_id => entry.id,
92
+ :published => entry.published,
93
+ :title => entry.title,
94
+ :content => entry.content,
95
+ :link => entry.url
96
+ )
97
+
98
+ if tweet.tweeted.blank?
99
+ id_extractor = /\d+$/
100
+ tid = id_extractor.match(tweet.twitter_id).to_s
101
+ @client.retweet(tid)
102
+ puts "retweeted #{tid} at #{Time.now.to_s(:long)}" # poor mans logging
103
+ tweet.update_attribute(:tweeted, true)
104
+ end
105
+ end
106
+ rescue => exception
107
+ puts exception.to_s
108
+ #puts exception.backtrace
109
+ end
110
+ sleep(@seconds)
111
+ end
112
+ end
113
+
114
+ feed_thread.join
115
+ end
116
+
117
+ private
118
+ def get_tweets_tagged_with(tag)
119
+ Feedzirra::Feed.fetch_and_parse("http://search.twitter.com/search.atom?q=+%23#{tag}")
120
+ end
121
+
122
+ end # class
123
+
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hashtag_retweet_bot
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
+ platform: ruby
11
+ authors:
12
+ - Balint Erdi
13
+ - Jaime Iniesta
14
+ - Tomasz Stachewicz
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-06-19 00:00:00 +02:00
20
+ default_executable: hashtag_retweet_bot
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: twitter
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ segments:
30
+ - 0
31
+ - 9
32
+ - 7
33
+ version: 0.9.7
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: activerecord
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: feedzirra
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 0
57
+ - 0
58
+ - 23
59
+ version: 0.0.23
60
+ type: :runtime
61
+ version_requirements: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ name: twitter
64
+ prerelease: false
65
+ requirement: &id004 !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ segments:
70
+ - 0
71
+ - 9
72
+ - 7
73
+ version: 0.9.7
74
+ type: :development
75
+ version_requirements: *id004
76
+ - !ruby/object:Gem::Dependency
77
+ name: activerecord
78
+ prerelease: false
79
+ requirement: &id005 !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ segments:
84
+ - 0
85
+ version: "0"
86
+ type: :development
87
+ version_requirements: *id005
88
+ - !ruby/object:Gem::Dependency
89
+ name: feedzirra
90
+ prerelease: false
91
+ requirement: &id006 !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ segments:
96
+ - 0
97
+ - 0
98
+ - 23
99
+ version: 0.0.23
100
+ type: :development
101
+ version_requirements: *id006
102
+ description: Script that listens to a tag and retweets messages with that tag. Supports both OAuth and HTTPAuth authentication strategies. Retweets using Twitter's native RT feature. Originally made for Scotland on Rails '09 by Mark Connell (http://github.com/rubaidh). Refactored and reworked after Euruko '10 by Tomasz Stachewicz (http://github.com/tomash)
103
+ email: t.stachewicz@gmail.com
104
+ executables:
105
+ - hashtag_retweet_bot
106
+ extensions: []
107
+
108
+ extra_rdoc_files:
109
+ - bin/hashtag_retweet_bot
110
+ - lib/bot.rb
111
+ - README.markdown
112
+ files:
113
+ - bin/hashtag_retweet_bot
114
+ - create_db_table.rb
115
+ - feed.rb
116
+ - hashtag_retweet_bot.gemspec
117
+ - lib/bot.rb
118
+ - Manifest
119
+ - Rakefile
120
+ - README.markdown
121
+ has_rdoc: true
122
+ homepage: http://github.com/tomash/hashtag_retweet_bot
123
+ licenses: []
124
+
125
+ post_install_message:
126
+ rdoc_options:
127
+ - --line-numbers
128
+ - --inline-source
129
+ - --title
130
+ - Hashtag_retweet_bot
131
+ - --main
132
+ - README.markdown
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ segments:
140
+ - 0
141
+ version: "0"
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ segments:
147
+ - 1
148
+ - 2
149
+ version: "1.2"
150
+ requirements: []
151
+
152
+ rubyforge_project: hashtag_retweet_bot
153
+ rubygems_version: 1.3.6
154
+ signing_key:
155
+ specification_version: 3
156
+ summary: Script that listens to a tag and retweets messages with that tag.
157
+ test_files: []
158
+