←︎ booster :: 7c68368


1
commit 7c683687119d32dec413d005c0d3e76c69a25b02
2
Author: acidvegas <acid.vegas@acid.vegas>
3
Date:   Thu Apr 9 21:54:54 2020 -0400
4
5
    Revived and fixed a lot of things
6
---
7
 LICENSE              |   2 +-
8
 README.md            |  12 +++-
9
 booster/booster.py   | 153 ++++++++++++++++++++++++++++++++++++++++++----
10
 booster/config.py    |  35 +++++------
11
 booster/debug.py     |  70 ---------------------
12
 booster/functions.py |  21 -------
13
 booster/twitter.py   | 168 ---------------------------------------------------
14
 7 files changed, 167 insertions(+), 294 deletions(-)
15
16
diff --git a/LICENSE b/LICENSE
17
index 69997e8..d521bd0 100644
18
--- a/LICENSE
19
+++ b/LICENSE
20
@@ -1,6 +1,6 @@
21
 ISC License
22
 
23
-Copyright (c) 2019, acidvegas <acid.vegas@acid.vegas>
24
+Copyright (c) 2020, acidvegas <acid.vegas@acid.vegas>
25
 
26
 Permission to use, copy, modify, and/or distribute this software for any
27
 purpose with or without fee is hereby granted, provided that the above
28
diff --git a/README.md b/README.md
29
index a2a5e96..327f18d 100644
30
--- a/README.md
31
+++ b/README.md
32
@@ -1,6 +1,15 @@
33
+# Booster
34
+> twitter bot that builds followers
35
+
36
 ## Requirments
37
+- [Python](https://www.python.org/downloads/) *(**Note:** This script was developed to be used with the latest version of Python)*
38
 - [Tweepy](http://pypi.python.org/pypi/tweepy)
39
 
40
+## Information
41
+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.
42
+
43
+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.
44
+
45
 ## Instructions
46
 Create a Twitter account & [sign up](http://dev.twitter.com/apps/new) for a new developer application.
47
 
48
@@ -18,6 +27,5 @@ Edit your `config.py` and change the Twitter API settings.
49
 
50
 ## Mirrors
51
 - [acid.vegas](https://acid.vegas/booster) *(main)*
52
-- [SuperNETs](https://git.supernets.org/acidvegas/booster)
53
 - [GitHub](https://github.com/acidvegas/booster)
54
-- [GitLab](https://gitlab.com/acidvegas/booster)
55
+- [GitLab](https://gitlab.com/acidvegas/booster)
56
diff --git a/booster/booster.py b/booster/booster.py
57
index 7176c93..675cc90 100644
58
--- a/booster/booster.py
59
+++ b/booster/booster.py
60
@@ -2,19 +2,148 @@
61
 # Booster Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/booster)
62
 # booster.py
63
 
64
+import random
65
+import threading
66
+import time
67
 import sys
68
 
69
 sys.dont_write_bytecode = True
70
 
71
-import debug
72
-
73
-debug.info()
74
-if not debug.check_version(3):
75
-	debug.error_exit('Requires Python version 3 to run!')
76
-if debug.check_privileges():
77
-	debug.error_exit('Do not run as admin/root!')
78
-debug.check_imports()
79
-debug.check_config()
80
-import twitter
81
-twitter.Booster().run()
82
-debug.keep_alive()
83
+import config
84
+
85
+class Booster(object):
86
+	def __init__(self):
87
+		self.api = None
88
+		self.me  = None
89
+
90
+	def run(self):
91
+		self.login()
92
+		self.stats()
93
+		threading.Thread(target=self.loop_boost).start()
94
+		threading.Thread(target=self.loop_favorite).start()
95
+		threading.Thread(target=self.loop_follow).start()
96
+		threading.Thread(target=self.loop_search).start()
97
+		threading.Thread(target=self.loop_trend).start()
98
+
99
+	def login(self):
100
+		try:
101
+			auth = tweepy.OAuthHandler(config.api.consumer_key, config.api.consumer_secret)
102
+			auth.set_access_token(config.api.access_token, config.api.access_token_secret)
103
+			self.api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True)
104
+			self.me = self.api.me()
105
+		except tweepy.TweepError as ex:
106
+			raise SystemExit(f'Failed to login to Twitter! ({ex!s})')
107
+
108
+	def loop_boost(self):
109
+		while True:
110
+			try:
111
+				if 'boost_tweet' in locals():
112
+					self.api.destroy_status(boost_tweet.id)
113
+				boost_tweet = self.api.update_status('RT for followers! #' + ' #'.join(random.sample(config.settings.keywords, len(config.settings.keywords))))
114
+				print('[+] - Reposted boost tweet.')
115
+			except tweepy.TweepError as ex:
116
+				print(f'[!] - Error occured in the boost loop ({ex!s})')
117
+			finally:
118
+				time.sleep(60*5)
119
+
120
+	def loop_favorite(self):
121
+		while True:
122
+			try:
123
+				for tweet in tweepy.Cursor(self.api.home_timeline, exclude_replies=True).items(50):
124
+					if tweet.user.screen_name != self.me.screen_name:
125
+						if not tweet.favorited:
126
+							if random.choice((True, False, False, False, False)):
127
+								self.api.create_favorite(tweet.id)
128
+								print('[+] - Favorited a friends tweet!')
129
+					time.sleep(60*60)
130
+			except tweepy.TweepError as ex:
131
+				print(f'[!] - Error occured in the favorite loop! ({ex!s})')
132
+			finally:
133
+				time.sleep(60*15)
134
+
135
+	def loop_follow(self):
136
+		while True:
137
+			try:
138
+				followers = self.api.followers_ids(self.me.screen_name)
139
+				friends = self.api.friends_ids(self.me.screen_name)
140
+				non_friends = [friend for friend in followers if friend not in friends]
141
+				print(f'[~] - Following back {len(non_friends)} supporters...')
142
+				for follower in non_friends:
143
+					self.api.create_friendship(follower)
144
+					print('[+] - Followed back a follower!')
145
+					if config.settings.message:
146
+						self.api.send_direct_message(screen_name=follower, text=self.message)
147
+					time.sleep(60*60)
148
+			except tweepy.TweepError as ex:
149
+				print(f'[!] - Error occured in the follow loop! ({ex!s})')
150
+			finally:
151
+				time.sleep(60*15)
152
+
153
+	def loop_search(self):
154
+		while True:
155
+			try:
156
+				query = random.choice(config.settings.keywords)
157
+				for item in self.api.search(q='#' + query, count=50, lang='en', result_type='recent'):
158
+					if not item.user.following and not item.favorited:
159
+						try:
160
+							self.api.create_favorite(item.id)
161
+							self.api.create_friendship(item.user.screen_name)
162
+							print('[+] - Followed a booster twitter!')
163
+						except tweepy.TweepError as ex:
164
+							print('[!] - Unknown error occured in the search loop! ({ex!s})')
165
+					time.sleep(60*60)
166
+			except tweepy.TweepError as ex:
167
+				debug.error('Error occured in the search loop!', ex)
168
+			finally:
169
+				time.sleep(60*15)
170
+
171
+	def loop_trend(self):
172
+		while True:
173
+			try:
174
+				trends = self.api.trends_place(str(config.settings.woeid))
175
+				hashtags = [x['name'] for x in trends[0]['trends'] if x['name'].startswith('#')]
176
+				for trend in hashtags:
177
+					for item in self.api.search(q=trend, count=5, lang='en', result_type='top'):
178
+						self.api.update_status(item.tweet)
179
+						time.sleep(60*60)
180
+			except tweepy.TweepError as ex:
181
+				print('[!] - Error occured in the trend loop! ({ex!s})')
182
+			finally:
183
+				time.sleep(60*15)
184
+
185
+	def loop_unfollow(self):
186
+		try:
187
+			followers = self.api.followers_ids(self.me.screen_name)
188
+			friends   = self.api.friends_ids(self.me.screen_name)
189
+			non_friends = [friend for friend in friends if friend not in followers]
190
+			non_friends.reverse()
191
+			print(f'[~] - Unfollowing {len(non_friends)} unsupporting friends...')
192
+			for friend in non_friends:
193
+				self.api.destroy_friendship(friend)
194
+				print('[+] - Unfollowed an unsupporting friend!')
195
+				time.sleep(60*30)
196
+		except tweepy.TweepError as ex:
197
+			debug.error('Error occured in the unfollow loop!', ex)
198
+
199
+	def stats(self):
200
+		print('[~] - SceenName  : ' + self.me.screen_name)
201
+		print('[~] - Registered : ' + self.me.created_at)
202
+		print('[~] - Favorites  : ' + self.me.favourites_count)
203
+		print('[~] - Following  : ' + self.me.friends_count)
204
+		print('[~] - Followers  : ' + self.me.followers_count)
205
+		print('[~] - Tweets     : ' + self.me.statuses_count)
206
+
207
+# Main
208
+print('#'*56)
209
+print('#{:^54}#'.format(''))
210
+print('#{:^54}#'.format('Booster Twitter Bot'))
211
+print('#{:^54}#'.format('Developed by acidvegas in Python'))
212
+print('#{:^54}#'.format('https://acid.vegas/booster'))
213
+print('#{:^54}#'.format(''))
214
+print('#'*56)
215
+try:
216
+	import tweepy
217
+except ImportError:
218
+	raise SystemExit('Failed to import the Tweepy library! (http://pypi.python.org/pypi/tweepy)')
219
+Booster.run()
220
+while True:input('')
221
diff --git a/booster/config.py b/booster/config.py
222
index 0a9a261..f4b4504 100644
223
--- a/booster/config.py
224
+++ b/booster/config.py
225
@@ -2,25 +2,20 @@
226
 # Booster Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/booster)
227
 # config.py
228
 
229
-# API Settings
230
-consumer_key        = 'CHANGEME'
231
-consumer_secret     = 'CHANGEME'
232
-access_token        = 'CHANGEME'
233
-access_token_secret = 'CHANGEME'
234
+class api:
235
+	consumer_key        = 'CHANGEME'
236
+	consumer_secret     = 'CHANGEME'
237
+	access_token        = 'CHANGEME'
238
+	access_token_secret = 'CHANGEME'
239
 
240
-# Boost Keywords
241
-boost_keywords = ['500aday','autofollow','autofollowback','f4f','follow','follow4follow','followback','followtrain','instantfollow','instantfollowback','teamfollowback','wefollowback']
242
+class throttle:
243
+	favorite = 75
244
+	follow   = 75
245
+	message  = 750
246
+	tweet    = 750
247
+	unfollow = 75
248
 
249
-# Throttling
250
-max_favorites = 75  # Only use up to 100  to avoid suspension.
251
-max_follows   = 75  # Only use up to 100  to avoid suspension.
252
-max_messages  = 750 # Only use up to 1000 to avoid suspension.
253
-max_tweets    = 750 # Only use up to 1000 to avoid suspension.
254
-max_unfollows = 75  # Only use up to 100  to avoid suspension.
255
-
256
-# Messaging
257
-send_message = False # Send a message to anyone who follows you.
258
-message      = 'Thank you for following our Twitter account!'
259
-
260
-# Where On Earth ID's (http://www.woeidlookup.com/)
261
-woeid = 23424975 # United States
262
+class settings:
263
+	keywords = ['500aday','autofollow','autofollowback','f4f','follow','follow4follow','followback','followtrain','instantfollow','instantfollowback','teamfollowback','wefollowback']
264
+	message  = 'Thank you for following our Twitter account!' # Set to None to disable sending messages to new followers
265
+	woeid    = 23424975 # Where On Earth ID (http://www.woeidlookup.com/)
266
diff --git a/booster/debug.py b/booster/debug.py
267
deleted file mode 100644
268
index 8220cc5..0000000
269
--- a/booster/debug.py
270
+++ /dev/null
271
@@ -1,70 +0,0 @@
272
-#!/usr/bin/env python
273
-# Booster Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/booster)
274
-# debug.py
275
-
276
-import ctypes
277
-import os
278
-import sys
279
-import time
280
-
281
-import config
282
-
283
-def action(msg):
284
-	print(f'{get_time()} | [#] - {msg}')
285
-
286
-def alert(msg):
287
-	print(f'{get_time()} | [+] - {msg}')
288
-
289
-def check_config():
290
-	if 'CHANGEME' in (config.consumer_key, config.consumer_secret, config.access_token, config.access_token_secret):
291
-		error_exit('Edit your config file!')
292
-
293
-def check_imports():
294
-	try:
295
-		import tweepy
296
-	except ImportError:
297
-		error_exit('Failed to import the Tweepy library! (http://pypi.python.org/pypi/tweepy)')
298
-
299
-def check_privileges():
300
-	if check_windows():
301
-		return True if ctypes.windll.shell32.IsUserAnAdmin() != 0 else return False
302
-	else:
303
-		return True if os.getuid() == 0 or os.geteuid() == 0 else return False
304
-
305
-def check_version(major):
306
-	return True if sys.version_info.major == major else return False
307
-
308
-def check_windows():
309
-	return True if os.name == 'nt' else return False
310
-
311
-def clear():
312
-	os.system('cls') if check_windows() else os.system('clear')
313
-
314
-def error(msg, reason=None):
315
-	print(f'{get_time()} | [!] - {msg} ({str(reason)})') if reason else print(f'{get_time()} | [!] - {msg}')
316
-
317
-def error_exit(msg):
318
-	raise SystemExit(f'{get_time()} | [!] - {msg}')
319
-
320
-def get_time():
321
-	return time.strftime('%I:%M:%S')
322
-
323
-def get_windows():
324
-	return True if os.name == 'nt' else False
325
-
326
-def info():
327
-	clear()
328
-	print(''.rjust(56, '#'))
329
-	print('#{0}#'.format(''.center(54)))
330
-	print('#{0}#'.format('Booster Twitter Bot'.center(54)))
331
-	print('#{0}#'.format('Developed by acidvegas in Python'.center(54)))
332
-	print('#{0}#'.format('https://acid.vegas/booster'.center(54)))
333
-	print('#{0}#'.format(''.center(54)))
334
-	print(''.rjust(56, '#'))
335
-
336
-def keep_alive():
337
-	try:
338
-		while True:
339
-			input('')
340
-	except KeyboardInterrupt:
341
-		sys.exit()
342
diff --git a/booster/functions.py b/booster/functions.py
343
deleted file mode 100644
344
index 6033fa7..0000000
345
--- a/booster/functions.py
346
+++ /dev/null
347
@@ -1,21 +0,0 @@
348
-#!/usr/bin/env python
349
-# Booster Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/booster)
350
-# functions.py
351
-
352
-import datetime
353
-import random
354
-import urllib.request
355
-
356
-def get_day():
357
-	return datetime.datetime.today().weekday()
358
-
359
-def get_source(url):
360
-	req = urllib.request.Request(url)
361
-	req.add_header('User-Agent', 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)')
362
-	source = urllib.request.urlopen(req, timeout=10)
363
-	charset = source.headers.get_content_charset()
364
-	if charset:
365
-	return source.read().decode(charset) if charset else return source.read().decode()
366
-
367
-def random_int(min, max):
368
-	return random.randint(min, max)
369
diff --git a/booster/twitter.py b/booster/twitter.py
370
deleted file mode 100644
371
index 8ee255b..0000000
372
--- a/booster/twitter.py
373
+++ /dev/null
374
@@ -1,168 +0,0 @@
375
-#!/usr/bin/env python
376
-# Booster Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/booster)
377
-# twitter.py
378
-
379
-import random
380
-import threading
381
-import time
382
-
383
-import tweepy
384
-
385
-import config
386
-import debug
387
-import functions
388
-
389
-class Booster(object):
390
-	def __init__(self):
391
-		self.api           = None
392
-		self.me            = None
393
-		self.favorites     = 0
394
-		self.max_favorites = config.max_favorites
395
-		self.follows       = 0
396
-		self.max_follows   = config.max_follows
397
-		self.messages      = 0
398
-		self.max_messages  = config.max_messages
399
-		self.tweets        = 0
400
-		self.max_tweets    = config.max_tweets
401
-		self.unfollows     = 0
402
-		self.max_unfollows = config.max_unfollows
403
-		self.send_message  = config.send_message
404
-		self.message       = config.message
405
-
406
-	def run(self):
407
-		self.login()
408
-		threading.Thread(target=self.loop_boost).start()
409
-		threading.Thread(target=self.loop_favorite).start()
410
-		threading.Thread(target=self.loop_follow).start()
411
-		threading.Thread(target=self.loop_search).start()
412
-		threading.Thread(target=self.loop_trend).start()
413
-
414
-	def login(self):
415
-		try:
416
-			auth = tweepy.OAuthHandler(config.consumer_key, config.consumer_secret)
417
-			auth.set_access_token(config.access_token, config.access_token_secret)
418
-			self.api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True)
419
-			self.me  = self.api.me()
420
-		except tweepy.TweepError as ex:
421
-			debug.error_exit('Failed to login to Twitter! ({0})'.format(str(ex)))
422
-
423
-	def loop_boost(self):
424
-		while True:
425
-			try:
426
-				if 'boost_tweet' in locals(): self.api.destroy_status(boost_tweet.id)
427
-				boost_tweet = self.api.update_status('RT for followers! #' + ' #'.join(config.boost_keywords))
428
-				self.tweets += 1
429
-				debug.alert('Re-posted boost tweet.')
430
-			except tweepy.TweepError as ex:
431
-				debug.error('Error occured in the boost loop', ex)
432
-			finally:
433
-				random.shuffle(config.boost_keywords)
434
-				time.sleep(60*5)
435
-
436
-	def loop_favorite(self):
437
-		while True:
438
-			try:
439
-				for tweet in tweepy.Cursor(self.api.home_timeline, exclude_replies=True).items(50):
440
-					if tweet.user.screen_name != self.me.screen_name:
441
-						if not tweet.favorited:
442
-							if random.choice((True, False, False, False, False)):
443
-								self.api.create_favorite(tweet.id)
444
-								self.favorites += 1
445
-								debug.alert('Favorited a friends tweet!')
446
-					time.sleep(30)
447
-			except tweepy.TweepError as ex:
448
-				debug.error('Error occured in the favorite loop!', ex)
449
-			finally:
450
-				time.sleep(60*15)
451
-
452
-	def loop_follow(self):
453
-		while True:
454
-			try:
455
-				followers = self.api.followers_ids(self.me.screen_name)
456
-				friends   = self.api.friends_ids(self.me.screen_name)
457
-				non_friends = [friend for friend in followers if friend not in friends]
458
-				debug.action('Following back {0} supporters...'.format(len(non_friends)))
459
-				for follower in non_friends:
460
-					self.api.create_friendship(follower)
461
-					self.follows += 1
462
-					debug.alert('Followed back a follower!')
463
-					if self.follows >= self.max_follows:
464
-						break
465
-					if self.send_message:
466
-						self.api.send_direct_message(screen_name=follower, text=self.message)
467
-					time.sleep(30)
468
-			except tweepy.TweepError as ex:
469
-				debug.error('Error occured in the follow loop!', ex)
470
-			finally:
471
-				time.sleep(60*15)
472
-
473
-	def loop_search(self):
474
-		while True:
475
-			try:
476
-				query = random.choice(config.boost_keywords)
477
-				for item in self.api.search(q='#' + query, count=50, lang='en', result_type='recent'):
478
-					if not item.user.following and not item.favorited:
479
-						try:
480
-							self.api.create_favorite(item.id)
481
-							self.api.create_friendship(item.user.screen_name)
482
-							self.favorites += 1
483
-							self.follows += 1
484
-							debug.alert('Followed a booster twitter!')
485
-						except tweepy.TweepError as ex:
486
-							debug.error('Unknown error occured in the search loop!', ex)
487
-					time.sleep(30)
488
-			except tweepy.TweepError as ex:
489
-				debug.error('Error occured in the search loop!', ex)
490
-			finally:
491
-				time.sleep(60*15)
492
-
493
-	def loop_trend(self):
494
-		while True:
495
-			try:
496
-				trends   = self.api.trends_place(str(config.woeid))
497
-				hashtags = [x['name'] for x in trends[0]['trends'] if x['name'].startswith('#')]
498
-				for trend in hashtags:
499
-					for item in self.api.search(q=trend, count=5, lang='en', result_type='top'):
500
-						self.api.update_status(item.tweet)
501
-						time.sleep(30)
502
-			except tweepy.TweepError as ex:
503
-				debug.error('Error occured in the trend loop!', ex)
504
-			finally:
505
-				time.sleep(60*15)
506
-
507
-	def loop_unfollow(self):
508
-		try:
509
-			followers = self.api.followers_ids(self.me.screen_name)
510
-			friends   = self.api.friends_ids(self.me.screen_name)
511
-			non_friends = [friend for friend in friends if friend not in followers]
512
-			non_friends.reverse()
513
-			debug.action('Unfollowing {0} unsupporting friends...'.format(len(non_friends)))
514
-			for friend in non_friends:
515
-				self.api.destroy_friendship(friend)
516
-				self.unfollows += 1
517
-				debug.alert('Unfollowed an unsupporting friend!')
518
-				if self.unfollows == self.max_unfollows:
519
-					break
520
-				else:
521
-					time.sleep(60*functions.random_int(10,15))
522
-		except tweepy.TweepError as ex:
523
-			debug.error('Error occured in the unfollow loop!', ex)
524
-		finally:
525
-			self.unfollows = 0
526
-
527
-	def ratio_check(self):
528
-		if self.follows >= max_follows:
529
-			time.sleep(86400)
530
-		if self.me.friends_count >= 2000:
531
-			ratio = self.me.friends_count + (self.me.followers_count/10)
532
-			if self.me.friends_count >= ratio:
533
-				debug.action('Following to follower ratio is off! Starting the unfollow loop...')
534
-				unfollow_loop()
535
-
536
-	def stats(self):
537
-		debug.action('SceenName  : ' + self.me.screen_name)
538
-		debug.action('Registered : ' + self.me.created_at)
539
-		debug.action('Favorites  : ' + self.me.favourites_count)
540
-		debug.action('Following  : ' + self.me.friends_count)
541
-		debug.action('Followers  : ' + self.me.followers_count)
542
-		debug.action('Tweets     : ' + self.me.statuses_count)