Permalink
Browse files

code and stuff

  • Loading branch information...
1 parent b318742 commit 2ce394a7cec1b0416e0bbe65e27d064de104711b @bobrik committed Jul 17, 2012
Showing with 250 additions and 0 deletions.
  1. +67 −0 README.md
  2. +3 −0 index.js
  3. +156 −0 lib/TwitterBot.js
  4. +24 −0 package.json
View
@@ -0,0 +1,67 @@
+# Twitter Bot - skeleton for twitter robots
+
+If you need to create twitter bot that will eternally iterate over own followers - this is what you need.
+
+## Installation
+
+Install it from npm:
+
+```
+npm install twitter_bot
+```
+
+## Usage
+
+1. Register twitter account for your bot.
+2. Register twitter application for your bot.
+3. Get access tokens for your application from your bot's account.
+4. Write some code
+ ```javascript
+ var util = require("util"),
+ TwitterBot = require("twitter_bot"),
+ bot;
+
+ // overwrite constructor
+ function MyBot(config) {
+ TwitterBot.call(this)
+ // make something cool in constructor
+ this.isCool = true;
+ };
+
+ util.inherits(MyBot, TwitterBot);
+
+ // main function that you must implement
+ MyBot.prototype.process = function(id, callback) {
+ console.log("Processing user with id=" + id);
+ setTimeout(callback, 1000);
+ }
+
+ // create instance of your bot
+ bot = new MyBot({
+ consumer_key : "<consumer key from application settings page>",
+ consumer_secret : "<consumer secret from application settings page>",
+ access_token_key : "<auth token of your bot given to your app>",
+ access_token_secret : "<auth token secret of your bot given to your app>",
+ concurrency : 10 // concurrency level, 10 is default
+ });
+
+
+ // start processing your followers
+ bot.start();
+
+ // after 10 seconds stop iterating new followers,
+ // but finish processing current ones
+ setTimeout(bot.stop.bind(bot), 10000);
+
+ // this is it.
+ ```
+5. Promote yourself.
+
+## Projects
+
+This project came from [@listwatcher](https://twitter.com/listwatcher) ([sources](https://github.com/bobrik/ListWatcher))
+code and is used in [@unfollowr](https://twitter.com/unfollowr) twitter project to manage more than 200K followers.
+
+## Authors
+
+* [Ian Babrou](https://github.com/bobrik)
View
@@ -0,0 +1,3 @@
+(function(module) {
+ module.exports = require("./lib/TwitterBot");
+})(module);
View
@@ -0,0 +1,156 @@
+(function(module) {
+ var twitter = require("ntwitter");
+
+ function TwitterBot(config) {
+ var self = this;
+
+ self.config = {
+ followers_refresh_timeout : 30000,
+ followers_retry_time : 1000,
+ restart_timeout : 1000,
+ concurrency : 10
+ };
+
+ Object.keys(config).forEach(function(key) {
+ self.config[key] = config[key];
+ });
+
+ self.started = false;
+ self.current = {};
+ self.currentFollowers = [];
+ self.followers = undefined;
+ self.followersUpdateTime = 0;
+ self.followersRequested = false;
+ self.followers = [];
+ self.restartTimer = undefined;
+ };
+
+ TwitterBot.prototype.getConfig = function(key) {
+ return this.config[key];
+ };
+
+ TwitterBot.prototype.getClient = function() {
+ if (!this.client) {
+ this.client = new twitter({
+ consumer_key : this.getConfig("consumer_key"),
+ consumer_secret : this.getConfig("consumer_secret"),
+ access_token_key : this.getConfig("access_token_key"),
+ access_token_secret : this.getConfig("access_token_secret")
+ });
+ }
+
+ return this.client;
+ };
+
+ TwitterBot.prototype.getFollowers = function(callback) {
+ var self = this,
+ now = new Date().getTime(),
+ updateTime = self.followersUpdateTime,
+ refreshTimeout = self.getConfig("followers_refresh_timeout"),
+ alreadyRequested = self.followersRequested;
+
+ if (alreadyRequested) {
+ return setTimeout(self.getFollowers.bind(self, callback), self.getConfig("followers_retry_time"));
+ }
+
+ if (updateTime + refreshTimeout > now) {
+ return callback(undefined, self.followers.slice());
+ }
+
+ self.followersRequested = true;
+ self.getClient().getFollowersIds(function(error, followers) {
+ self.followersRequested = false;
+
+ if (error) {
+ return callback(error);
+ }
+
+ self.followersUpdateTime = new Date().getTime();
+ self.followers = followers;
+
+ callback(undefined, self.followers.slice());
+ });
+ };
+
+ TwitterBot.prototype.start = function() {
+ var self = this;
+
+ self.started = true;
+
+ self.getFollowers(function(error, followers) {
+ self.currentFollowers = followers;
+ if (error) {
+ if (self.started) {
+ self.restart();
+ }
+
+ return;
+ }
+
+ var concurrency = self.getConfig("concurrency"),
+ restarted = false,
+ current;
+
+ while (Object.keys(self.current).length < concurrency && followers.length) {
+ current = followers.pop();
+
+ (function process(current) {
+ function resume() {
+ if (self.started) {
+ if (followers.length) {
+ process(followers.pop());
+ } else {
+ if (!restarted) {
+ restarted = true;
+ self.restart();
+ }
+ }
+ }
+ }
+
+ if (self.current[current]) {
+ return resume();
+ }
+
+ self.current[current] = true;
+ self.process(current, function processCallback() {
+ delete self.current[current];
+ resume();
+ });
+ })(current);
+ }
+ });
+ };
+
+ TwitterBot.prototype.process = function(id, callback) {
+
+ };
+
+ TwitterBot.prototype.restart = function(wait) {
+ var self = this;
+
+ if (wait === undefined) {
+ wait = self.getConfig("restart_timeout");
+ }
+
+ if (!self.restartTimer) {
+ self.restartTimer = setTimeout(function restart() {
+ self.restartTimer = undefined;
+ self.start();
+ }, wait);
+ }
+ };
+
+ TwitterBot.prototype.stop = function() {
+ this.started = false;
+
+ if (this.restartTimer) {
+ clearTimeout(this.restartTimer);
+ this.restartTimer = undefined;
+ }
+
+ this.currentFollowers = [];
+ };
+
+ module.exports = TwitterBot;
+})(module);
View
@@ -0,0 +1,24 @@
+{
+ "name": "twitter_bot",
+ "version": "0.1.0",
+ "description": "Twitter Bot is parent class for your twitter project that needs to iterate followers eternally (see @listwatcher and @unfollowr)",
+ "main": "index.js",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/bobrik/twitter_bot.git"
+ },
+ "dependencies": {
+ "ntwitter": ">=0.4.0"
+ },
+ "keywords": [
+ "twitter",
+ "bot",
+ "robot",
+ "listwatcher",
+ "unfollowr",
+ "followers",
+ "social"
+ ],
+ "author": "Ian Babrou <ibobrik@gmail.com>",
+ "license": "BSD"
+}

0 comments on commit 2ce394a

Please sign in to comment.