im trying to make a bot that can track invitation to my telegram channel and give credit for each invitation people gonna make. after with that credit earned they can buy fortnite account.
TELEGRAM_BOT_TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN")
if not TELEGRAM_BOT_TOKEN:
logger.error("Telegram Bot Token not found.")
exit(1)
DATABASE_NAME = 'fortnite_invites.db'
ADMIN_USER_IDS = [123456789] # Replace with your Telegram User ID
CHANNEL_USERNAME = "@your_channel_username" # Replace with your channel's username
INVITE_CREDITS = 10
def get_db_connection():
conn = None
try:
conn = sqlite3.connect(DATABASE_NAME, check_same_thread=False)
cursor = conn.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, username TEXT, credits INTEGER)''')
cursor.execute('''CREATE TABLE IF NOT EXISTS accounts (id INTEGER PRIMARY KEY AUTOINCREMENT, account_info TEXT, price INTEGER)''')
conn.commit()
except sqlite3.Error as e:
logger.error(f"DB connection error: {e}")
if conn:
conn.close()
return None
return conn
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
user = update.message.from_user
conn = get_db_connection()
if not conn:
await update.message.reply_text("Database error.")
return
try:
cursor = conn.cursor()
cursor.execute("INSERT OR IGNORE INTO users (id, username, credits) VALUES (?, ?, 0)", (user.id, user.username))
conn.commit()
if context.args:
referrer_id = int(context.args[0])
if referrer_id != user.id:
cursor.execute("SELECT id FROM users WHERE id = ?", (referrer_id,))
referrer = cursor.fetchone()
if referrer:
conn.execute("UPDATE users SET credits = credits + ? WHERE id = ?", (INVITE_CREDITS, referrer_id))
conn.commit()
await context.bot.send_message(referrer_id, f"? {user.username} joined using your invite link! You earned {INVITE_CREDITS} credits.")
await update.message.reply_text(f"Welcome, {user.username}! Invite friends to the channel and earn credits to buy Fortnite accounts.\nUse /invite to get your link and /credits to check your balance.")
except sqlite3.Error as e:
logger.error(f"Start command error: {e}")
await update.message.reply_text("Error processing your start command.")
conn.rollback()
finally:
conn.close()
async def invite(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
user_id = update.message.from_user.id
invite_link = f"https://t.me/{context.bot.username}?start={user_id}"
await update.message.reply_text(f"Share this link to invite others: {invite_link}")
async def credits(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
conn = get_db_connection()
if not conn:
await update.message.reply_text("Database error.")
return
try:
cursor = conn.cursor()
cursor.execute("SELECT credits FROM users WHERE id = ?", (update.message.from_user.id,))
credits_data = cursor.fetchone()
credits = credits_data[0] if credits_data else 0
await update.message.reply_text(f"Your credits: {credits}")
except sqlite3.Error as e:
logger.error(f"Credits command error: {e}")
await update.message.reply_text("Error fetching your credits.")
finally:
conn.close()
async def buyaccount(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
conn = get_db_connection()
if not conn:
await update.message.reply_text("Database error.")
return
try:
user_id = update.message.from_user.id
cursor = conn.cursor()
cursor.execute("SELECT credits FROM users WHERE id = ?", (user_id,))
credits_data = cursor.fetchone()
if not credits_data:
await update.message.reply_text("User not found.")
return
credits = credits_data[0]
if not context.args:
await update.message.reply_text("Please specify the account ID you want to buy.")
return
try:
account_id = int(context.args[0])
cursor.execute("SELECT account_info, price FROM accounts WHERE id = ?", (account_id,))
account = cursor.fetchone()
if not account:
await update.message.reply_text("Account not found.")
return
account_info, price = account
if credits >= price:
conn.execute("UPDATE users SET credits = credits - ? WHERE id = ?", (price, user_id))
conn.commit()
await update.message.reply_text(f"Successfully purchased:\n{account_info}\nYour remaining credits: {credits - price}")
else:
await update.message.reply_text("Insufficient credits.")
except ValueError:
await update.message.reply_text("Invalid account ID.")
except sqlite3.Error as e:
logger.error(f"Buy account error: {e}")
await update.message.reply_text("Error processing your purchase.")
conn.rollback()
finally:
conn.close()
async def addaccount(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if update.message.from_user.id not in ADMIN_USER_IDS:
await update.message.reply_text("Unauthorized.")
return
conn = get_db_connection()
if not conn:
await update.message.reply_text("Database error.")
return
if len(context.args) < 2:
await update.message.reply_text("Usage: /addaccount <account_info> <price>")
return
try:
price = int(context.args[-1])
account_info = " ".join(context.args[:-1])
conn.execute("INSERT INTO accounts (account_info, price) VALUES (?, ?)", (account_info, price))
conn.commit()
await update.message.reply_text("Account added successfully.")
except ValueError:
await update.message.reply_text("Invalid price.")
except sqlite3.Error as e:
logger.error(f"Add account error: {e}")
await update.message.reply_text("Error adding account.")
conn.rollback()
finally:
conn.close()
async def listaccounts(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
conn = get_db_connection()
if not conn:
await update.message.reply_text("Database error.")
return
try:
cursor = conn.cursor()
cursor.execute("SELECT id, account_info, price FROM accounts")
accounts = cursor.fetchall()
if not accounts:
await update.message.reply_text("No accounts available yet.")
return
message = "Available Fortnite Accounts:\n"
for acc_id, info, price in accounts:
message += f"ID: {acc_id}, Info: {info}, Price: {price} credits\n"
await update.message.reply_text(message)
except sqlite3.Error as e:
logger.error(f"List accounts error: {e}")
await update.message.reply_text("Error fetching accounts.")
finally:
conn.close()
async def handle_member_updates(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if update.chat_member and update.chat_member.new_chat_member.user.id != context.bot.id:
user = update.chat_member.new_chat_member.user
conn = get_db_connection()
if not conn:
return
try:
cursor = conn.cursor()
cursor.execute("INSERT OR IGNORE INTO users (id, username, credits) VALUES (?, ?, 0)", (user.id, user.username))
conn.commit()
logger.info(f"New member joined the channel: {user.username} ({user.id})")
# Consider if you want to award credits for direct channel joins as well
except sqlite3.Error as e:
logger.error(f"Error handling new member: {e}")
conn.rollback()
finally:
conn.close()
async def main() -> None:
if not TELEGRAM_BOT_TOKEN:
return
app = ApplicationBuilder().token(TELEGRAM_BOT_TOKEN).build()
hi i just came across your thread.
the issue is that you are trying to run main() asynchronously which doesnt work within ptb library 20.
instead dont define main function as async dont run it with async aswell:
fix for your issue
Code:
def main() -> None:
if not TELEGRAM_BOT_TOKEN:
return
app = ApplicationBuilder().token(TELEGRAM_BOT_TOKEN).build()