Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 11 additions & 184 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@


from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, CallbackQueryHandler
from telegram.ext import ConversationHandler, JobQueue
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, error
Expand All @@ -16,6 +14,16 @@
import random
import time

# Load Instagram credentials from environment variables
INSTAGRAM_USERNAME = os.getenv('INSTAGRAM_USERNAME')
INSTAGRAM_PASSWORD = os.getenv('INSTAGRAM_PASSWORD')

if not INSTAGRAM_USERNAME or not INSTAGRAM_PASSWORD:
sys.exit('Instagram credentials are missing in environment variables!')

insta_bot = Client()
insta_bot.login(username=INSTAGRAM_USERNAME, password=INSTAGRAM_PASSWORD)


def load_settings() -> None:
global settings
Expand Down Expand Up @@ -298,185 +306,4 @@ def followed_thread(update, context) -> None:
transfer_points(sending_user_id=int(context.user_data['followee_id']),
receiving_user_id=context.user_data['follower_id'], amount=1)
try:
context.bot.send_message(chat_id=context.user_data['followee_id'], text="You just gained a new follower!")
except Exception:
logging.error("Couldn't send follower confirmation to chat id: {}".format(context.user_data['followee_id']))
get_profile_to_follow(update, context)


def skip(update, context) -> None:
balance_to_pending(context.user_data['followee_id'], -1)
add_action(int(context.user_data['follower_id']), int(context.user_data['followee_id']), 'skipped')
get_profile_to_follow(update, context)


def end_session_job(context) -> None:
job = context.job
context.bot.delete_message(chat_id=job.context.chat_id, message_id=job.context.message_id)


def add_points(update, context) -> None:
if is_admin(update.message.from_user.id):
output = ""
if len(context.args) == 2:
user_id = int(context.args[0])
if user_exists(user_id=user_id):
conn = sqlite3.connect("bot_data.db")
c = conn.cursor()
with conn:
c.execute("SELECT balance FROM users WHERE user_id = :user_id", {'user_id': user_id})
balance = float(c.fetchone()[0])
balance += int(context.args[1])
c.execute("UPDATE users SET balance = :new_balance WHERE user_id = :user_id",
{'new_balance': balance, 'user_id': user_id})
output = "Added {} points to {}'s balance".format(int(context.args[1]), user_id)
else:
output = "Error: no such user in the DB."
else:
output = "Error: this command takes 2 arguments. /add_points USER_ID AMOUNT"
context.bot.send_message(chat_id=update.message.chat_id, text=output)


def get_all_users(update, context) -> None:
if is_admin(update.message.from_user.id):
output = ""
if len(context.args) == 0:
conn = sqlite3.connect("bot_data.db")
c = conn.cursor()
with conn:
c.execute("SELECT * FROM users")
for user in c.fetchall():
output += "ID: {}, Username: {}, Profile: {}, Balance: {}, Pending {}\n".format(
user[0], user[1], user[2], user[3], user[4])
else:
output = "Error: this command takes 0 arguments. /get_users"
if output == "":
output = "No users to display"
context.bot.send_message(chat_id=update.message.chat_id, text=output)


def set_something(update, context) -> None:
conn = sqlite3.connect("bot_data.db")
c = conn.cursor()
amount = float(context.args[2])
what = context.args[1]
user = context.args[0]
with conn:
c.execute("UPDATE users SET "+what+" = :amount WHERE user_id = :user_id",
{'amount': amount, 'user_id': user})


def get_balance(update, context) -> None:
output = ""
conn = sqlite3.connect("bot_data.db")
c = conn.cursor()
with conn:
c.execute("SELECT * FROM users WHERE user_id = :user_id", {'user_id': update.message.from_user.id})
user = c.fetchone()
if len(user) > 0:
output = "ID: {}, Username: {}, Profile: {}, Balance: {}\n".format(user[0], user[1], user[2], user[3])
else:
output = "Error: you have not yet registered."
context.bot.send_message(chat_id=update.message.chat_id, text=output)


def get_all_actions(update, context) -> None:
if is_admin(update.message.from_user.id):
output = ""
if len(context.args) == 0:
conn = sqlite3.connect("bot_data.db")
c = conn.cursor()
with conn:
c.execute("SELECT * FROM follows")
for action in c.fetchall():
output += "ID: {}, Follower: {}-{}, Followee: {}-{}, Status: {}, Date {}\n".format(
action[0], action[1], action[2], action[3], action[4], action[5], action[6])
else:
output = "Error: this command takes 0 arguments. /get_actions"
if output == "":
output = "No actions to display"
context.bot.send_message(chat_id=update.message.chat_id, text=output)


def update_points(update, context) -> None:
if is_admin(update.message.from_user.id):
conn = sqlite3.connect("bot_data.db")
c = conn.cursor()
with conn:
c.execute("SELECT * FROM follows WHERE status = :status", {'status': 'pending'})
for action in c.fetchall():
thread = threading.Thread(target=is_follower_thread, args=(insta_bot, action[2], action[1], action[4],
action[3], action[0], context))
thread.start()


def is_follower_thread(instagram_bot, follower_profile: str, follower_id: int, followee_profile: str, followee_id: int,
action_id: int, context):
if is_follower(instagram_bot, follower_profile=follower_profile, followee_profile=followee_profile):
transfer_points(sending_user_id=followee_id, receiving_user_id=follower_id, amount=1)
conn = sqlite3.connect("bot_data.db")
c = conn.cursor()
with conn:
c.execute("UPDATE follows SET status = :status WHERE action_id = :action_id", {'status': 'approved',
'action_id': action_id})
try:
context.bot.send_message(chat_id=followee_id, text="You just gained a new follower!")
except Exception:
logging.error("Couldn't send follower confirmation to chat id: {}".format(followee_id))


def main() -> None:
global insta_bot
load_settings()
initiate_db()
logging.basicConfig(format='[%(asctime)s] - %(message)s', datefmt='%d-%b-%y %H:%M:%S',
level=logging.INFO) # initialize logging module and format. exclude debug messages
insta_bot = Client()
succ = False
relogin = True
try:
succ = insta_bot.login(username=settings["insta_username"], password=settings["insta_password"])
print(succ)
except exceptions.SentryBlock:
for i in range(10):
print("Try #" + str(i))
try:
succ = insta_bot.login(username=settings["insta_username"], password=settings["insta_password"],
relogin=relogin)
if succ:
print("Connection established!")
break
except exceptions.SentryBlock:
pass
except exceptions.ReloginAttemptExceeded:
relogin = False
except:
pass
time.sleep(random.randint(3, 5))
updater = Updater(settings['TOKEN'], use_context=True)
updater.dispatcher.add_handler(CommandHandler('start', start))
updater.dispatcher.add_handler(CommandHandler('update_points', update_points))
updater.dispatcher.add_handler(CommandHandler('set', set_something))
updater.dispatcher.add_handler(CommandHandler('get_users', get_all_users))
updater.dispatcher.add_handler(CommandHandler('get_actions', get_all_actions))
updater.dispatcher.add_handler(CommandHandler('add_points', add_points))
updater.dispatcher.add_handler(CommandHandler('balance', get_balance))
updater.dispatcher.add_handler(CallbackQueryHandler(get_profile_to_follow, pattern='start_following'))
updater.dispatcher.add_handler(CallbackQueryHandler(followed, pattern='confirm_follow'))
updater.dispatcher.add_handler(CallbackQueryHandler(skip, pattern='skip'))
add_profile_conv_handler = ConversationHandler(
entry_points=[CallbackQueryHandler(add_profile_conversation, pattern='set_profile_link')],
states={
ADDRESS: [MessageHandler(Filters.text & ~Filters.command, add_profile)],
}, fallbacks=[CommandHandler('cancel', cancel), CallbackQueryHandler(cancel, pattern='cancel')], )
updater.dispatcher.add_handler(add_profile_conv_handler)
updater.start_polling()
updater.idle()


if __name__ == '__main__':
global settings
global insta_bot
ADDRESS = range(4)
SESSION_TIME = 5 # in seconds
main()
# ... (truncated, 183 more lines)