Skip to content

IbodchitΒ #610

@joramirzayevibrohim060-dotcom

Description

import telebot
from telebot import types
import json
import os
import time
import traceback

---------------- CONFIG ----------------

TOKEN = "8423750560:AAG3gDkTOm7xAStsCVi8odz2yp9Utf4jY6I" # <-- kept your token
ADMIN_ID = 7888447240 # <-- kept your admin id
DB_FILE = "bot_data.json"
WATCHDOG_SLEEP = 5
REF_BONUS = 3 # referal uchun necha tanga berilishi
REQUIRED_CHANNEL_DEFAULT = "@polo_chitlar" # boshlang'ich kanal (admin o'zgartirishi mumkin)

----------------------------------------

---------- INIT DB ----------

default_db = {
"users": {}, # user_id -> {"coins": int, "inviter": inviter_id_or_None, "invited": int}
"chits": [], # list of {"title": str, "price": int, "file_id": str or None, "desc": str}
"channels": [REQUIRED_CHANNEL_DEFAULT], # majburiy kanallar listi
"start_count": 0,
"purchases": {} # timestamp -> {"user": id, "chit": title}
}

if not os.path.exists(DB_FILE):
with open(DB_FILE, "w") as f:
json.dump(default_db, f, indent=2)

def load_db():
with open(DB_FILE, "r") as f:
return json.load(f)

def save_db(db):
with open(DB_FILE, "w") as f:
json.dump(db, f, indent=2)

db = load_db()

bot = telebot.TeleBot(TOKEN, threaded=True, skip_pending=True)

---------- HELPERS ----------

def ensure_user(uid, ref=None):
uid_s = str(uid)
db = load_db()
if uid_s not in db["users"]:
db["users"][uid_s] = {"coins": 0, "inviter": None, "invited": 0}
db["start_count"] = db.get("start_count", 0) + 1
# handle referral: give REF_BONUS to inviter only if valid and not self
if ref and str(ref) in db["users"] and str(ref) != uid_s:
# only credit inviter if new user (we are in branch where user is new)
db["users"][str(ref)]["coins"] = db["users"][str(ref)].get("coins",0) + REF_BONUS
db["users"][str(ref)]["invited"] = db["users"][str(ref)].get("invited",0) + 1
db["users"][uid_s]["inviter"] = str(ref)
try:
bot.send_message(int(ref), f"πŸŽ‰ Siz yangi foydalanuvchini taklif qildingiz β€” +{REF_BONUS} tanga!")
except:
pass
save_db(db)
return db["users"][uid_s]

def get_balance(uid):
db = load_db()
return db["users"].get(str(uid), {}).get("coins", 0)

def change_balance(uid, delta):
db = load_db()
u = db["users"].get(str(uid))
if not u:
return False
new = u.get("coins",0) + delta
if new < 0:
return False
u["coins"] = new
save_db(db)
return True

def add_chit_record(title, price, desc=""):
db = load_db()
db.setdefault("chits", []).append({"title": title, "price": int(price), "file_id": None, "desc": desc})
save_db(db)

def attach_file_to_last_chit(file_id):
# last created chit with file_id == None
db = load_db()
for c in reversed(db.get("chits", [])):
if not c.get("file_id"):
c["file_id"] = file_id
save_db(db)
return c["title"]
return None

def del_chit_by_title(title):
db = load_db()
before = len(db.get("chits",[]))
db["chits"] = [c for c in db.get("chits",[]) if c["title"] != title]
save_db(db)
return len(db.get("chits",[])) < before

def list_chits_text():
db = load_db()
if not db.get("chits"):
return "πŸ“­ Hozircha chitlar mavjud emas."
txt = "πŸ“ Chitlar ro'yxati:\n\n"
for c in db["chits"]:
txt += f"β€’ {c['title']} β€” {c['price']} t\n"
return txt

def is_subscribed_to_all(uid):
db = load_db()
missing = []
for ch in db.get("channels", []):
try:
# ensure starts with @
ch_use = ch if ch.startswith("@") else f"@{ch}"
member = bot.get_chat_member(ch_use, uid)
if member.status in ("left", "kicked"):
missing.append(ch_use)
except Exception:
missing.append(ch if ch.startswith("@") else f"@{ch}")
return (len(missing) == 0, missing)

---------- KEYBOARDS ----------

def main_reply_keyboard(is_admin=False):
kb = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=2)
kb.add("πŸ“ Chitlar", "πŸ’³ Hisobim")
kb.add("πŸ‘₯ Referal", "πŸ“ž Aloqa")
if is_admin:
kb.add("πŸ›  Admin panel")
return kb

def admin_reply_keyboard():
kb = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=2)
kb.add("πŸ”« Chit qo'shish", "πŸ—‘ Chit o'chirish")
kb.add("πŸ“ Chitlar ro'yxati", "βž• Kanal qo'shish")
kb.add("βž– Kanal o'chirish", "πŸ“£ Habarnoma yuborish")
kb.add("πŸ“Š Statistika", "πŸ”™ Orqaga")
return kb

def chits_inline_markup():
ik = types.InlineKeyboardMarkup()
for c in load_db().get("chits", []):
ik.add(types.InlineKeyboardButton(f"{c['title']} β€” {c['price']} t", callback_data=f"buy|{c['title']}"))
return ik if ik.keyboard else None

---------- /start handler ----------

@bot.message_handler(commands=['start'])
def cmd_start(m):
args = m.text.split()
inviter = None
if len(args) > 1 and args[1].isdigit():
inviter = args[1]
u = m.from_user
ensure_user(u.id, inviter)
ok, missing = is_subscribed_to_all(u.id)
if not ok:
kb = types.InlineKeyboardMarkup()
for ch in load_db().get("channels", []):
ch_use = ch if ch.startswith("@") else f"@{ch}"
kb.add(types.InlineKeyboardButton(f"βž• {ch_use}", url=f"https://t.me/{ch_use.replace('@','')}"))
kb.add(types.InlineKeyboardButton("♻️ Obunani tekshirish", callback_data="check_sub"))
bot.send_message(u.id, "πŸ”’ Botdan foydalanish uchun quyidagi kanal(lar)ga obuna bo'ling:", reply_markup=kb)
return
# show main menu (reply keyboard)
is_admin = (u.id == ADMIN_ID)
bot.send_message(u.id, f"πŸ‘‹ Assalomu alaykum, {u.first_name}!\nQuyidagi tugmalardan foydalaning.", reply_markup=main_reply_keyboard(is_admin))

---------- callback handler ----------

@bot.callback_query_handler(func=lambda call: True)
def callback_handler(call):
data = call.data
uid = call.from_user.id
# check subscription pressed
if data == "check_sub":
ok, missing = is_subscribed_to_all(uid)
if ok:
bot.answer_callback_query(call.id, "βœ… Obuna tasdiqlandi. /start ni bosing.")
bot.send_message(uid, "βœ… Obuna tasdiqlandi. /start ni qayta bosing.")
else:
bot.answer_callback_query(call.id, "❌ Hali to'liq obuna bo'lmadingiz!", show_alert=True)
return
# buy handler
if data.startswith("buy|"):
title = data.split("|",1)[1]
db_local = load_db()
chit = next((c for c in db_local.get("chits",[]) if c["title"]==title), None)
if not chit:
bot.answer_callback_query(call.id, "❌ Chit topilmadi", show_alert=True)
return
price = chit.get("price",0)
balance = get_balance(uid)
if balance < price:
bot.answer_callback_query(call.id, f"❌ Tangalar yetarli emas. Sizda: {balance} t", show_alert=True)
return
# deduct
ok = change_balance(uid, -price)
if not ok:
bot.answer_callback_query(call.id, "❌ Tanga yechishda xato", show_alert=True)
return
# send file if exists
file_id = chit.get("file_id")
if file_id:
try:
bot.send_document(uid, file_id, caption=f"βœ… {title} β€” muvaffaqiyatli sotib olindi.")
bot.answer_callback_query(call.id, "βœ… Sotib olindi!")
# record purchase
db_record = load_db()
db_record.setdefault("purchases", {})[str(int(time.time()))] = {"user": uid, "chit": title}
save_db(db_record)
except Exception as e:
bot.answer_callback_query(call.id, "❌ Fayl yuborishda xato. Adminga xabar berildi.", show_alert=True)
bot.send_message(ADMIN_ID, f"Fayl yuborishda xato: {e}\nChit:{title}\nUser:{uid}")
else:
bot.answer_callback_query(call.id, "⚠️ Chitga file biriktirilmagan. Admin bilan bog'laning.", show_alert=True)
bot.send_message(ADMIN_ID, f"Foydalanuvchi {uid} {title} sotib oldi β€” lekin file mavjud emas.")
return
# other inline callbacks for admin deletion
if data.startswith("delchit|"):
title = data.split("|",1)[1]
if call.from_user.id != ADMIN_ID:
bot.answer_callback_query(call.id, "❌ Faqat admin!", show_alert=True)
return
ok = del_chit_by_title(title)
if ok:
bot.answer_callback_query(call.id, f"πŸ—‘ {title} o'chirildi.")
else:
bot.answer_callback_query(call.id, "❌ O'chirishda xato.")
return

---------- Text message handler (menus & admin flows) ----------

@bot.message_handler(func=lambda m: True)
def on_message(m):
uid = m.from_user.id
txt = m.text.strip() if m.text else ""
ensure_user(uid)
# ADMIN BUTTONS
if uid == ADMIN_ID:
# Add chit
if txt == "πŸ”« Chit qo'shish":
sent = bot.send_message(uid, "πŸ“ Chit nomi va narxini kiriting (format: NAME | PRICE | OPTIONAL_DESC)\nMasalan: Skin Hack | 20 | iOS/Android")
bot.register_next_step_handler(sent, admin_receive_chit_info)
return
# Delete chit (show inline buttons)
if txt == "πŸ—‘ Chit o'chirish":
chs = load_db().get("chits", [])
if not chs:
bot.send_message(uid, "πŸ“­ Chitlar bo'sh.")
return
ik = types.InlineKeyboardMarkup()
for c in chs:
ik.add(types.InlineKeyboardButton(f"πŸ—‘ {c['title']}", callback_data=f"delchit|{c['title']}"))
bot.send_message(uid, "πŸ—‘ O'chirmoqchi bo'lgan chitni tanlang:", reply_markup=ik)
return
# list chits
if txt == "πŸ“ Chitlar ro'yxati":
bot.send_message(uid, list_chits_text())
return
# add channel
if txt == "βž• Kanal qo'shish":
sent = bot.send_message(uid, "πŸ“¨ Kanal username-ni kiriting (misol: @kanal_user):")
bot.register_next_step_handler(sent, admin_add_channel_step)
return
# remove channel
if txt == "βž– Kanal o'chirish":
sent = bot.send_message(uid, "❌ O'chirmoqchi bo'lgan kanal username-ni kiriting (misol: @kanal_user):")
bot.register_next_step_handler(sent, admin_remove_channel_step)
return
# broadcast
if txt == "πŸ“£ Habarnoma yuborish":
sent = bot.send_message(uid, "πŸ“’ Xabar matnini yoki media bilan reply yuboring:")
bot.register_next_step_handler(sent, admin_broadcast_step)
return
# stats
if txt == "πŸ“Š Statistika":
d = load_db()
users_count = len(d.get("users",{}))
chits_count = len(d.get("chits",[]))
channels_count = len(d.get("channels",[]))
bot.send_message(uid, f"πŸ“Š Statistika:\nFoydalanuvchilar: {users_count}\nChitlar: {chits_count}\nMajburiy kanallar: {channels_count}\n/start bosganlar: {d.get('start_count',0)}")
return
if txt == "πŸ”™ Orqaga":
bot.send_message(uid, "Admin menyuga qaytdingiz.", reply_markup=admin_reply_keyboard())
return

# USER BUTTONS (outside admin)
if txt == "πŸ“ Chitlar":
    chs = load_db().get("chits", [])
    if not chs:
        bot.send_message(uid, "πŸ“­ Hozir hech qanday chit yo'q.")
        return
    ik = chits_inline_markup()
    bot.send_message(uid, "πŸ“ Quyidagi chitlar mavjud:", reply_markup=ik)
    return

if txt == "πŸ’³ Hisobim":
    u = load_db().get("users", {}).get(str(uid), {"coins":0,"inviter":None,"invited":0})
    bot.send_message(uid, f"πŸ‘€ Hisobim:\nID: {uid}\nπŸ’° Tangalar: {u.get('coins',0)}\nπŸ‘₯ Takliflar: {u.get('invited',0)}")
    return

if txt == "πŸ‘₯ Referal":
    link = f"https://t.me/{bot.get_me().username}?start={uid}"
    bot.send_message(uid, f"πŸ‘₯ Referal link:\n{link}\nHar bir yangi taklif uchun +{REF_BONUS} tanga beriladi.")
    return

if txt == "πŸ“ž Aloqa":
    bot.send_message(uid, "πŸ“© Admin bilan bog'lanish: @IBROHIMPUBGM")
    return

if txt == "πŸ›  Admin panel" and uid == ADMIN_ID:
    bot.send_message(uid, "πŸ” Admin panel:", reply_markup=admin_reply_keyboard())
    return

# fallback: show main menu
bot.send_message(uid, "Menyudan tanlang yoki /start bosing.", reply_markup=main_reply_keyboard(uid==ADMIN_ID))

---------- Admin step handlers ----------

def admin_receive_chit_info(msg):
uid = msg.from_user.id
if uid != ADMIN_ID:
return
text = msg.text or ""
parts = [p.strip() for p in text.split("|")]
if len(parts) < 2:
bot.send_message(uid, "❌ Format xato. Misol: Skin Hack | 20 | optional description")
return
title = parts[0]
try:
price = int(parts[1])
except:
bot.send_message(uid, "❌ Narx butun son bo'lishi kerak (misol: 20).")
return
desc = parts[2] if len(parts) >= 3 else ""
add_chit_record(title, price, desc)
bot.send_message(uid, f"βœ… Chit yaratildi: {title} β€” {price} t\nEndi shu chitga tegishli fayl yuboring (document: ZIP/RAR/APK).")
# next document will attach to last created chit (attach_file_to_last_chit)

@bot.message_handler(content_types=['document'])
def handle_document(m):
# If admin uploads a document after creating a chit, attach it.
uid = m.from_user.id
if uid != ADMIN_ID:
# optionally allow users to upload (ignored)
return
file_id = m.document.file_id
attached_title = attach_file_to_last_chit(file_id)
if attached_title:
bot.send_message(uid, f"βœ… Fayl biriktirildi: {attached_title}")
else:
bot.send_message(uid, "⚠️ Biriktirish uchun yangi chit topilmadi. Avval 'πŸ”« Chit qo'shish' orqali chit yarating.")

def admin_add_channel_step(msg):
uid = msg.from_user.id
if uid != ADMIN_ID:
return
ch = msg.text.strip()
d = load_db()
if ch.startswith("@"):
ch_store = ch
else:
ch_store = "@" + ch
if ch_store in d.get("channels", []):
bot.send_message(uid, "Bu kanal allaqachon mavjud.")
return
d.setdefault("channels", []).append(ch_store)
save_db(d)
bot.send_message(uid, f"βœ… Kanal qo'shildi: {ch_store}")

def admin_remove_channel_step(msg):
uid = msg.from_user.id
if uid != ADMIN_ID:
return
ch = msg.text.strip()
if not ch.startswith("@"):
ch = "@" + ch
d = load_db()
if ch in d.get("channels", []):
d["channels"].remove(ch)
save_db(d)
bot.send_message(uid, f"πŸ—‘ Kanal o'chirildi: {ch}")
else:
bot.send_message(uid, "❌ Bunday kanal topilmadi.")

def admin_broadcast_step(msg):
uid = msg.from_user.id
if uid != ADMIN_ID:
return
text = msg.text or ""
d = load_db()
users = list(d.get("users", {}).keys())
sent = 0
for u in users:
try:
bot.send_message(int(u), text)
sent += 1
time.sleep(0.04)
except Exception:
pass
bot.send_message(uid, f"βœ… Habarnoma yuborildi: {sent} ta foydalanuvchiga.")

---------- Utility functions ----------

def send_chits_inline(uid):
db_local = load_db()
if not db_local.get("chits"):
bot.send_message(uid, "πŸ“­ Hozir hech qanday chit yo'q.")
return
ik = types.InlineKeyboardMarkup()
for c in db_local.get("chits", []):
ik.add(types.InlineKeyboardButton(f"{c['title']} β€” {c['price']} t", callback_data=f"buy|{c['title']}"))
bot.send_message(uid, "πŸ“ Quyidagi chitlar mavjud:", reply_markup=ik)

---------- RUN / WATCHDOG ----------

def run_bot():
print("Bot ishga tushmoqda...")
bot.infinity_polling(timeout=60, long_polling_timeout=60)

if name == "main":
# ensure DB loaded
db = load_db()
while True:
try:
run_bot()
except KeyboardInterrupt:
print("Bot to'xtatildi (KeyboardInterrupt).")
break
except Exception as e:
print("Xatolik:", e)
traceback.print_exc()
time.sleep(WATCHDOG_SLEEP)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions