booster

- twitter bot that builds followers
git clone git://git.acid.vegas/booster.git
Log | Files | Refs | Archive | README | LICENSE

commit 7c683687119d32dec413d005c0d3e76c69a25b02
parent d9f8aa3cce0c7c148da8055eab8570a62089e500
Author: acidvegas <acid.vegas@acid.vegas>
Date: Thu, 9 Apr 2020 21:54:54 -0400

Revived and fixed a lot of things

Diffstat:
MLICENSE | 2+-
MREADME.md | 13+++++++++++--
Mbooster/booster.py | 154++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mbooster/config.py | 35+++++++++++++++--------------------
Dbooster/debug.py | 71-----------------------------------------------------------------------
Dbooster/functions.py | 21---------------------
Dbooster/twitter.py | 169-------------------------------------------------------------------------------

7 files changed, 169 insertions(+), 296 deletions(-)

diff --git a/LICENSE b/LICENSE
@@ -1,6 +1,6 @@
 ISC License
 
-Copyright (c) 2019, acidvegas <acid.vegas@acid.vegas>
+Copyright (c) 2020, acidvegas <acid.vegas@acid.vegas>
 
 Permission to use, copy, modify, and/or distribute this software for any
 purpose with or without fee is hereby granted, provided that the above
diff --git a/README.md b/README.md
@@ -1,6 +1,15 @@
+# Booster
+> twitter bot that builds followers
+
 ## Requirments
+- [Python](https://www.python.org/downloads/) *(**Note:** This script was developed to be used with the latest version of Python)*
 - [Tweepy](http://pypi.python.org/pypi/tweepy)
 
+## Information
+This bot will build you followers on Twitter automatically by doing a number of things. Every 5 minutes the bot will tweet a status with a bunch of "follow-for-follow" type hashtags. This way anyone searching for those hashtags to gain follows will always see your tweet as one of the most recent. Before it posts a new tweet, it will delete the previous tweet, so you dont spam your followers. All of the hashtags the bot tweets for followers are also searched for on Twitter and the most recent are followed and favorited. It will favorite tweets of the people you follow. Anyone that follows your Twitter will be followed back, and optionally messaged. People who you follow that are not following you back are unfollowed eventually. Trending tweets are randomly stolen and tweeted as your own.
+
+Everything this bot does is extremely throttles to prevent getting your account suspended. It is meant to be running 24/7 without any interaction needed.
+
 ## Instructions
 Create a Twitter account & [sign up](http://dev.twitter.com/apps/new) for a new developer application.
 
@@ -18,6 +27,5 @@ Edit your `config.py` and change the Twitter API settings.
 
 ## Mirrors
 - [acid.vegas](https://acid.vegas/booster) *(main)*
-- [SuperNETs](https://git.supernets.org/acidvegas/booster)
 - [GitHub](https://github.com/acidvegas/booster)
-- [GitLab](https://gitlab.com/acidvegas/booster)
+- [GitLab](https://gitlab.com/acidvegas/booster)
+\ No newline at end of file
diff --git a/booster/booster.py b/booster/booster.py
@@ -2,19 +2,148 @@
 # Booster Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/booster)
 # booster.py
 
+import random
+import threading
+import time
 import sys
 
 sys.dont_write_bytecode = True
 
-import debug
-
-debug.info()
-if not debug.check_version(3):
-	debug.error_exit('Requires Python version 3 to run!')
-if debug.check_privileges():
-	debug.error_exit('Do not run as admin/root!')
-debug.check_imports()
-debug.check_config()
-import twitter
-twitter.Booster().run()
-debug.keep_alive()
+import config
+
+class Booster(object):
+	def __init__(self):
+		self.api = None
+		self.me  = None
+
+	def run(self):
+		self.login()
+		self.stats()
+		threading.Thread(target=self.loop_boost).start()
+		threading.Thread(target=self.loop_favorite).start()
+		threading.Thread(target=self.loop_follow).start()
+		threading.Thread(target=self.loop_search).start()
+		threading.Thread(target=self.loop_trend).start()
+
+	def login(self):
+		try:
+			auth = tweepy.OAuthHandler(config.api.consumer_key, config.api.consumer_secret)
+			auth.set_access_token(config.api.access_token, config.api.access_token_secret)
+			self.api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True)
+			self.me = self.api.me()
+		except tweepy.TweepError as ex:
+			raise SystemExit(f'Failed to login to Twitter! ({ex!s})')
+
+	def loop_boost(self):
+		while True:
+			try:
+				if 'boost_tweet' in locals():
+					self.api.destroy_status(boost_tweet.id)
+				boost_tweet = self.api.update_status('RT for followers! #' + ' #'.join(random.sample(config.settings.keywords, len(config.settings.keywords))))
+				print('[+] - Reposted boost tweet.')
+			except tweepy.TweepError as ex:
+				print(f'[!] - Error occured in the boost loop ({ex!s})')
+			finally:
+				time.sleep(60*5)
+
+	def loop_favorite(self):
+		while True:
+			try:
+				for tweet in tweepy.Cursor(self.api.home_timeline, exclude_replies=True).items(50):
+					if tweet.user.screen_name != self.me.screen_name:
+						if not tweet.favorited:
+							if random.choice((True, False, False, False, False)):
+								self.api.create_favorite(tweet.id)
+								print('[+] - Favorited a friends tweet!')
+					time.sleep(60*60)
+			except tweepy.TweepError as ex:
+				print(f'[!] - Error occured in the favorite loop! ({ex!s})')
+			finally:
+				time.sleep(60*15)
+
+	def loop_follow(self):
+		while True:
+			try:
+				followers = self.api.followers_ids(self.me.screen_name)
+				friends = self.api.friends_ids(self.me.screen_name)
+				non_friends = [friend for friend in followers if friend not in friends]
+				print(f'[~] - Following back {len(non_friends)} supporters...')
+				for follower in non_friends:
+					self.api.create_friendship(follower)
+					print('[+] - Followed back a follower!')
+					if config.settings.message:
+						self.api.send_direct_message(screen_name=follower, text=self.message)
+					time.sleep(60*60)
+			except tweepy.TweepError as ex:
+				print(f'[!] - Error occured in the follow loop! ({ex!s})')
+			finally:
+				time.sleep(60*15)
+
+	def loop_search(self):
+		while True:
+			try:
+				query = random.choice(config.settings.keywords)
+				for item in self.api.search(q='#' + query, count=50, lang='en', result_type='recent'):
+					if not item.user.following and not item.favorited:
+						try:
+							self.api.create_favorite(item.id)
+							self.api.create_friendship(item.user.screen_name)
+							print('[+] - Followed a booster twitter!')
+						except tweepy.TweepError as ex:
+							print('[!] - Unknown error occured in the search loop! ({ex!s})')
+					time.sleep(60*60)
+			except tweepy.TweepError as ex:
+				debug.error('Error occured in the search loop!', ex)
+			finally:
+				time.sleep(60*15)
+
+	def loop_trend(self):
+		while True:
+			try:
+				trends = self.api.trends_place(str(config.settings.woeid))
+				hashtags = [x['name'] for x in trends[0]['trends'] if x['name'].startswith('#')]
+				for trend in hashtags:
+					for item in self.api.search(q=trend, count=5, lang='en', result_type='top'):
+						self.api.update_status(item.tweet)
+						time.sleep(60*60)
+			except tweepy.TweepError as ex:
+				print('[!] - Error occured in the trend loop! ({ex!s})')
+			finally:
+				time.sleep(60*15)
+
+	def loop_unfollow(self):
+		try:
+			followers = self.api.followers_ids(self.me.screen_name)
+			friends   = self.api.friends_ids(self.me.screen_name)
+			non_friends = [friend for friend in friends if friend not in followers]
+			non_friends.reverse()
+			print(f'[~] - Unfollowing {len(non_friends)} unsupporting friends...')
+			for friend in non_friends:
+				self.api.destroy_friendship(friend)
+				print('[+] - Unfollowed an unsupporting friend!')
+				time.sleep(60*30)
+		except tweepy.TweepError as ex:
+			debug.error('Error occured in the unfollow loop!', ex)
+
+	def stats(self):
+		print('[~] - SceenName  : ' + self.me.screen_name)
+		print('[~] - Registered : ' + self.me.created_at)
+		print('[~] - Favorites  : ' + self.me.favourites_count)
+		print('[~] - Following  : ' + self.me.friends_count)
+		print('[~] - Followers  : ' + self.me.followers_count)
+		print('[~] - Tweets     : ' + self.me.statuses_count)
+
+# Main
+print('#'*56)
+print('#{:^54}#'.format(''))
+print('#{:^54}#'.format('Booster Twitter Bot'))
+print('#{:^54}#'.format('Developed by acidvegas in Python'))
+print('#{:^54}#'.format('https://acid.vegas/booster'))
+print('#{:^54}#'.format(''))
+print('#'*56)
+try:
+	import tweepy
+except ImportError:
+	raise SystemExit('Failed to import the Tweepy library! (http://pypi.python.org/pypi/tweepy)')
+Booster.run()
+while True:input('')
+\ No newline at end of file
diff --git a/booster/config.py b/booster/config.py
@@ -2,25 +2,20 @@
 # Booster Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/booster)
 # config.py
 
-# API Settings
-consumer_key        = 'CHANGEME'
-consumer_secret     = 'CHANGEME'
-access_token        = 'CHANGEME'
-access_token_secret = 'CHANGEME'
+class api:
+	consumer_key        = 'CHANGEME'
+	consumer_secret     = 'CHANGEME'
+	access_token        = 'CHANGEME'
+	access_token_secret = 'CHANGEME'
 
-# Boost Keywords
-boost_keywords = ['500aday','autofollow','autofollowback','f4f','follow','follow4follow','followback','followtrain','instantfollow','instantfollowback','teamfollowback','wefollowback']
+class throttle:
+	favorite = 75
+	follow   = 75
+	message  = 750
+	tweet    = 750
+	unfollow = 75
 
-# Throttling
-max_favorites = 75  # Only use up to 100  to avoid suspension.
-max_follows   = 75  # Only use up to 100  to avoid suspension.
-max_messages  = 750 # Only use up to 1000 to avoid suspension.
-max_tweets    = 750 # Only use up to 1000 to avoid suspension.
-max_unfollows = 75  # Only use up to 100  to avoid suspension.
-
-# Messaging
-send_message = False # Send a message to anyone who follows you.
-message      = 'Thank you for following our Twitter account!'
-
-# Where On Earth ID's (http://www.woeidlookup.com/)
-woeid = 23424975 # United States
+class settings:
+	keywords = ['500aday','autofollow','autofollowback','f4f','follow','follow4follow','followback','followtrain','instantfollow','instantfollowback','teamfollowback','wefollowback']
+	message  = 'Thank you for following our Twitter account!' # Set to None to disable sending messages to new followers
+	woeid    = 23424975 # Where On Earth ID (http://www.woeidlookup.com/)
diff --git a/booster/debug.py b/booster/debug.py
@@ -1,70 +0,0 @@
-#!/usr/bin/env python
-# Booster Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/booster)
-# debug.py
-
-import ctypes
-import os
-import sys
-import time
-
-import config
-
-def action(msg):
-	print(f'{get_time()} | [#] - {msg}')
-
-def alert(msg):
-	print(f'{get_time()} | [+] - {msg}')
-
-def check_config():
-	if 'CHANGEME' in (config.consumer_key, config.consumer_secret, config.access_token, config.access_token_secret):
-		error_exit('Edit your config file!')
-
-def check_imports():
-	try:
-		import tweepy
-	except ImportError:
-		error_exit('Failed to import the Tweepy library! (http://pypi.python.org/pypi/tweepy)')
-
-def check_privileges():
-	if check_windows():
-		return True if ctypes.windll.shell32.IsUserAnAdmin() != 0 else return False
-	else:
-		return True if os.getuid() == 0 or os.geteuid() == 0 else return False
-
-def check_version(major):
-	return True if sys.version_info.major == major else return False
-
-def check_windows():
-	return True if os.name == 'nt' else return False
-
-def clear():
-	os.system('cls') if check_windows() else os.system('clear')
-
-def error(msg, reason=None):
-	print(f'{get_time()} | [!] - {msg} ({str(reason)})') if reason else print(f'{get_time()} | [!] - {msg}')
-
-def error_exit(msg):
-	raise SystemExit(f'{get_time()} | [!] - {msg}')
-
-def get_time():
-	return time.strftime('%I:%M:%S')
-
-def get_windows():
-	return True if os.name == 'nt' else False
-
-def info():
-	clear()
-	print(''.rjust(56, '#'))
-	print('#{0}#'.format(''.center(54)))
-	print('#{0}#'.format('Booster Twitter Bot'.center(54)))
-	print('#{0}#'.format('Developed by acidvegas in Python'.center(54)))
-	print('#{0}#'.format('https://acid.vegas/booster'.center(54)))
-	print('#{0}#'.format(''.center(54)))
-	print(''.rjust(56, '#'))
-
-def keep_alive():
-	try:
-		while True:
-			input('')
-	except KeyboardInterrupt:
-		sys.exit()
-\ No newline at end of file
diff --git a/booster/functions.py b/booster/functions.py
@@ -1,21 +0,0 @@
-#!/usr/bin/env python
-# Booster Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/booster)
-# functions.py
-
-import datetime
-import random
-import urllib.request
-
-def get_day():
-	return datetime.datetime.today().weekday()
-
-def get_source(url):
-	req = urllib.request.Request(url)
-	req.add_header('User-Agent', 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)')
-	source = urllib.request.urlopen(req, timeout=10)
-	charset = source.headers.get_content_charset()
-	if charset:
-	return source.read().decode(charset) if charset else return source.read().decode()
-
-def random_int(min, max):
-	return random.randint(min, max)
diff --git a/booster/twitter.py b/booster/twitter.py
@@ -1,168 +0,0 @@
-#!/usr/bin/env python
-# Booster Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/booster)
-# twitter.py
-
-import random
-import threading
-import time
-
-import tweepy
-
-import config
-import debug
-import functions
-
-class Booster(object):
-	def __init__(self):
-		self.api           = None
-		self.me            = None
-		self.favorites     = 0
-		self.max_favorites = config.max_favorites
-		self.follows       = 0
-		self.max_follows   = config.max_follows
-		self.messages      = 0
-		self.max_messages  = config.max_messages
-		self.tweets        = 0
-		self.max_tweets    = config.max_tweets
-		self.unfollows     = 0
-		self.max_unfollows = config.max_unfollows
-		self.send_message  = config.send_message
-		self.message       = config.message
-
-	def run(self):
-		self.login()
-		threading.Thread(target=self.loop_boost).start()
-		threading.Thread(target=self.loop_favorite).start()
-		threading.Thread(target=self.loop_follow).start()
-		threading.Thread(target=self.loop_search).start()
-		threading.Thread(target=self.loop_trend).start()
-
-	def login(self):
-		try:
-			auth = tweepy.OAuthHandler(config.consumer_key, config.consumer_secret)
-			auth.set_access_token(config.access_token, config.access_token_secret)
-			self.api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True)
-			self.me  = self.api.me()
-		except tweepy.TweepError as ex:
-			debug.error_exit('Failed to login to Twitter! ({0})'.format(str(ex)))
-
-	def loop_boost(self):
-		while True:
-			try:
-				if 'boost_tweet' in locals(): self.api.destroy_status(boost_tweet.id)
-				boost_tweet = self.api.update_status('RT for followers! #' + ' #'.join(config.boost_keywords))
-				self.tweets += 1
-				debug.alert('Re-posted boost tweet.')
-			except tweepy.TweepError as ex:
-				debug.error('Error occured in the boost loop', ex)
-			finally:
-				random.shuffle(config.boost_keywords)
-				time.sleep(60*5)
-
-	def loop_favorite(self):
-		while True:
-			try:
-				for tweet in tweepy.Cursor(self.api.home_timeline, exclude_replies=True).items(50):
-					if tweet.user.screen_name != self.me.screen_name:
-						if not tweet.favorited:
-							if random.choice((True, False, False, False, False)):
-								self.api.create_favorite(tweet.id)
-								self.favorites += 1
-								debug.alert('Favorited a friends tweet!')
-					time.sleep(30)
-			except tweepy.TweepError as ex:
-				debug.error('Error occured in the favorite loop!', ex)
-			finally:
-				time.sleep(60*15)
-
-	def loop_follow(self):
-		while True:
-			try:
-				followers = self.api.followers_ids(self.me.screen_name)
-				friends   = self.api.friends_ids(self.me.screen_name)
-				non_friends = [friend for friend in followers if friend not in friends]
-				debug.action('Following back {0} supporters...'.format(len(non_friends)))
-				for follower in non_friends:
-					self.api.create_friendship(follower)
-					self.follows += 1
-					debug.alert('Followed back a follower!')
-					if self.follows >= self.max_follows:
-						break
-					if self.send_message:
-						self.api.send_direct_message(screen_name=follower, text=self.message)
-					time.sleep(30)
-			except tweepy.TweepError as ex:
-				debug.error('Error occured in the follow loop!', ex)
-			finally:
-				time.sleep(60*15)
-
-	def loop_search(self):
-		while True:
-			try:
-				query = random.choice(config.boost_keywords)
-				for item in self.api.search(q='#' + query, count=50, lang='en', result_type='recent'):
-					if not item.user.following and not item.favorited:
-						try:
-							self.api.create_favorite(item.id)
-							self.api.create_friendship(item.user.screen_name)
-							self.favorites += 1
-							self.follows += 1
-							debug.alert('Followed a booster twitter!')
-						except tweepy.TweepError as ex:
-							debug.error('Unknown error occured in the search loop!', ex)
-					time.sleep(30)
-			except tweepy.TweepError as ex:
-				debug.error('Error occured in the search loop!', ex)
-			finally:
-				time.sleep(60*15)
-
-	def loop_trend(self):
-		while True:
-			try:
-				trends   = self.api.trends_place(str(config.woeid))
-				hashtags = [x['name'] for x in trends[0]['trends'] if x['name'].startswith('#')]
-				for trend in hashtags:
-					for item in self.api.search(q=trend, count=5, lang='en', result_type='top'):
-						self.api.update_status(item.tweet)
-						time.sleep(30)
-			except tweepy.TweepError as ex:
-				debug.error('Error occured in the trend loop!', ex)
-			finally:
-				time.sleep(60*15)
-
-	def loop_unfollow(self):
-		try:
-			followers = self.api.followers_ids(self.me.screen_name)
-			friends   = self.api.friends_ids(self.me.screen_name)
-			non_friends = [friend for friend in friends if friend not in followers]
-			non_friends.reverse()
-			debug.action('Unfollowing {0} unsupporting friends...'.format(len(non_friends)))
-			for friend in non_friends:
-				self.api.destroy_friendship(friend)
-				self.unfollows += 1
-				debug.alert('Unfollowed an unsupporting friend!')
-				if self.unfollows == self.max_unfollows:
-					break
-				else:
-					time.sleep(60*functions.random_int(10,15))
-		except tweepy.TweepError as ex:
-			debug.error('Error occured in the unfollow loop!', ex)
-		finally:
-			self.unfollows = 0
-
-	def ratio_check(self):
-		if self.follows >= max_follows:
-			time.sleep(86400)
-		if self.me.friends_count >= 2000:
-			ratio = self.me.friends_count + (self.me.followers_count/10)
-			if self.me.friends_count >= ratio:
-				debug.action('Following to follower ratio is off! Starting the unfollow loop...')
-				unfollow_loop()
-
-	def stats(self):
-		debug.action('SceenName  : ' + self.me.screen_name)
-		debug.action('Registered : ' + self.me.created_at)
-		debug.action('Favorites  : ' + self.me.favourites_count)
-		debug.action('Following  : ' + self.me.friends_count)
-		debug.action('Followers  : ' + self.me.followers_count)
-		debug.action('Tweets     : ' + self.me.statuses_count)
-\ No newline at end of file