diff --git a/config.py b/config.py
index 7b2106f9e..495d71c90 100644
--- a/config.py
+++ b/config.py
@@ -3,17 +3,3 @@
from os import getenv
-API_ID = int(getenv("API_ID", ""))
-API_HASH = getenv("API_HASH", "")
-BOT_TOKEN = getenv("BOT_TOKEN", "")
-OWNER_ID = list(map(int, getenv("OWNER_ID", "").split()))
-MONGO_DB = getenv("MONGO_DB", "")
-LOG_GROUP = getenv("LOG_GROUP", "")
-CHANNEL_ID = int(getenv("CHANNEL_ID", ""))
-FREEMIUM_LIMIT = int(getenv("FREEMIUM_LIMIT", "0"))
-PREMIUM_LIMIT = int(getenv("PREMIUM_LIMIT", "500"))
-WEBSITE_URL = getenv("WEBSITE_URL", "upshrink.com")
-AD_API = getenv("AD_API", "52b4a2cf4687d81e7d3f8f2b7bc2943f618e78cb")
-STRING = getenv("STRING", None)
-YT_COOKIES = getenv("YT_COOKIES", None)
-INSTA_COOKIES = getenv("INSTA_COOKIES", None)
diff --git a/devgagan/__init__.py b/devgagan/__init__.py
index 4ee6d6091..d38ba0cb7 100644
--- a/devgagan/__init__.py
+++ b/devgagan/__init__.py
@@ -15,6 +15,7 @@
import asyncio
import logging
from pyrogram import Client
+from pyrogram.enums import ParseMode
from config import API_ID, API_HASH, BOT_TOKEN, STRING, MONGO_DB
from telethon.sync import TelegramClient
from motor.motor_asyncio import AsyncIOMotorClient
@@ -34,7 +35,8 @@
api_id=API_ID,
api_hash=API_HASH,
bot_token=BOT_TOKEN,
- workers=50
+ workers=50,
+ parse_mode=ParseMode.MARKDOWN
)
pro = Client("ggbot", api_id=API_ID, api_hash=API_HASH, session_string=STRING)
diff --git a/devgagan/core/func.py b/devgagan/core/func.py
index 2ef512ac6..8f0a7b17b 100644
--- a/devgagan/core/func.py
+++ b/devgagan/core/func.py
@@ -83,9 +83,9 @@ def extract_value_and_unit(ts):
return 0
PROGRESS_BAR = """\n
│ **__Completed:__** {1}/{2}
-│ **__Bytes:__** {0}%
+│ **__Total:__** {0}%
│ **__Speed:__** {3}/s
-│ **__ETA:__** {4}
+│ **__Time:__** {4}
╰─────────────────────╯
"""
async def progress_bar(current, total, ud_type, message, start):
@@ -250,7 +250,7 @@ async def progress_callback(current, total, progress_message):
f"│ **__Progress:__** {percent:.2f}%\n"
f"│ **__Uploaded:__** {current_mb:.2f} MB / {total_mb:.2f} MB\n"
f"╰──────────────────╯\n\n"
- f"**__Powered by Team SPY__**"
+ f"**__Powered by Diggi Digi__**"
)
last_update_time = current_time
diff --git a/devgagan/core/get_func.py b/devgagan/core/get_func.py
index 6dc2f9406..f22fb82ae 100644
--- a/devgagan/core/get_func.py
+++ b/devgagan/core/get_func.py
@@ -7,9 +7,10 @@
# Telegram: https://t.me/team_spy_pro
# YouTube: https://youtube.com/@dev_gagan
# Created: 2025-01-11
-# Last Modified: 2025-01-11
+# Last Modified: 2025-02-01
# Version: 2.0.5
# License: MIT License
+# Improved logic handles
# ---------------------------------------------------
import asyncio
@@ -17,29 +18,23 @@
import gc
import os
import re
-import psutil
-import subprocess
-import requests
+from typing import Callable
from devgagan import app
from devgagan import sex as gf
-from telethon.tl.types import DocumentAttributeVideo
+from telethon.tl.types import DocumentAttributeVideo, Message
+from telethon.sessions import StringSession
import pymongo
-from pyrogram import Client, filters
-from pyrogram.errors import ChannelBanned, ChannelInvalid, ChannelPrivate, ChatIdInvalid, ChatInvalid, PeerIdInvalid
-from pyrogram.enums import MessageMediaType
-from devgagan.core.func import progress_bar, video_metadata, screenshot, chk_user, progress_callback, prog_bar
+from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
+from pyrogram.errors import ChannelBanned, ChannelInvalid, ChannelPrivate, ChatIdInvalid, ChatInvalid
+from pyrogram.enums import MessageMediaType, ParseMode
+from devgagan.core.func import *
from devgagan.core.mongo import db
-from devgagan.modules.shrink import is_user_verified
+from pyrogram.errors import RPCError
from pyrogram.types import Message
-from config import MONGO_DB as MONGODB_CONNECTION_STRING, LOG_GROUP, OWNER_ID, STRING
-import cv2
-import random
+from config import MONGO_DB as MONGODB_CONNECTION_STRING, LOG_GROUP, OWNER_ID, STRING, API_ID, API_HASH
from devgagan.core.mongo.db import set_session, remove_session
-import string
-from telethon import events, Button
-from io import BytesIO
+from telethon import TelegramClient, events, Button
from devgagantools import fast_upload
-
def thumbnail(sender):
return f'{sender}.jpg' if os.path.exists(f'{sender}.jpg') else None
@@ -49,8 +44,8 @@ def thumbnail(sender):
COLLECTION_NAME = "super_user"
VIDEO_EXTENSIONS = ['mp4', 'mov', 'avi', 'mkv', 'flv', 'wmv', 'webm', 'mpg', 'mpeg', '3gp', 'ts', 'm4v', 'f4v', 'vob']
+DOCUMENT_EXTENSIONS = ['pdf', 'docs']
-# Establish a connection to MongoDB
mongo_app = pymongo.MongoClient(MONGODB_CONNECTION_STRING)
db = mongo_app[DB_NAME]
collection = db[COLLECTION_NAME]
@@ -61,326 +56,325 @@ def thumbnail(sender):
else:
pro = None
print("STRING is not available. 'app' is set to None.")
-
+
async def fetch_upload_method(user_id):
+ """Fetch the user's preferred upload method."""
user_data = collection.find_one({"user_id": user_id})
return user_data.get("upload_method", "Pyrogram") if user_data else "Pyrogram"
-async def upload_media(sender, target_chat_id, file, caption, edit):
- progress_message = None
- # target_chat_id = user_chat_ids.get(sender, sender)
- metadata = video_metadata(file)
- width= metadata['width']
- height= metadata['height']
- duration= metadata['duration']
- thumb_path = await screenshot(file, duration, sender)
-
- upload_method = await fetch_upload_method(sender) # Fetch the upload method (Pyrogram or Telethon)
- if upload_method == "Pyrogram":
- if file.endswith(('mp4', 'mkv', 'avi', 'mov')): # Video files
- dm = await app.send_video(
- chat_id=target_chat_id,
- video=file,
- caption=caption,
- height=height,
- width=width,
- duration=duration,
- thumb=thumb_path,
- progress=progress_bar,
- progress_args=("╭─────────────────────╮\n│ **__Pyro Uploader__**\n├─────────────────────", edit, time.time())
- )
- await dm.copy(LOG_GROUP)
- elif file.endswith(('pdf', 'docx', 'txt')): # Document files
- dm = await app.send_document(
- chat_id=target_chat_id,
- document=file,
- caption=caption,
- thumb=thumb_path,
- progress=progress_bar,
- progress_args=("╭─────────────────────╮\n│ **__Pyro Uploader__**\n├─────────────────────", edit, time.time())
- )
- await dm.copy(LOG_GROUP)
- elif file.endswith(('jpg', 'png', 'jpeg')): # Image files
- dm = await app.send_photo(
- chat_id=target_chat_id,
- photo=file,
- caption=caption,
- progress=progress_bar,
- progress_args=("╭─────────────────────╮\n│ **__Pyro Uploader__**\n├─────────────────────", edit, time.time())
- )
- await asyncio.sleep(2)
- await dm.copy(LOG_GROUP)
-
- elif upload_method == "Telethon":
- await edit.delete()
- progress_message = await gf.send_message(sender, "**__Uploading ...**__")
-
- uploaded = await fast_upload(
- gf, file,
- reply=progress_message,
- name=None,
- progress_bar_function=lambda done, total: progress_callback(done, total, sender)
- )
- if file.endswith(('mp4', 'mkv', 'avi', 'mov')): # Video files
- await gf.send_file(
- target_chat_id,
- uploaded,
- caption=caption,
- attributes=[
- DocumentAttributeVideo(
- duration=duration,
- w=width,
- h=height,
- supports_streaming=True
- )
- ],
- thumb=thumb_path
- )
- await gf.send_file(
- LOG_GROUP,
- uploaded,
- caption=caption,
- attributes=[
- DocumentAttributeVideo(
- duration=duration,
- w=width,
- h=height,
- supports_streaming=True
- )
- ],
- thumb=thumb_path
- )
- elif file.endswith(('pdf', 'docx', 'txt')): # Document files
- await gf.send_file(
- target_chat_id,
- uploaded,
- caption=caption,
- thumb=thumb_path
- )
- await gf.send_file(
- LOG_GROUP,
- uploaded,
- caption=caption,
- thumb=thumb_path
+async def upload_media(sender, target_chat_id, file, caption, edit, topic_id):
+ try:
+ upload_method = await fetch_upload_method(sender) # Fetch the upload method (Pyrogram or Telethon)
+ metadata = video_metadata(file)
+ width, height, duration = metadata['width'], metadata['height'], metadata['duration']
+ thumb_path = await screenshot(file, duration, sender)
+
+ video_formats = {'mp4', 'mkv', 'avi', 'mov'}
+ document_formats = {'pdf', 'docx', 'txt', 'epub'}
+ image_formats = {'jpg', 'png', 'jpeg'}
+
+ # Pyrogram upload
+ if upload_method == "Pyrogram":
+ if file.split('.')[-1].lower() in video_formats:
+ dm = await app.send_video(
+ chat_id=target_chat_id,
+ video=file,
+ caption=caption,
+ height=height,
+ width=width,
+ duration=duration,
+ thumb=thumb_path,
+ reply_to_message_id=topic_id,
+ parse_mode=ParseMode.MARKDOWN,
+ progress=progress_bar,
+ progress_args=("╭─────────────────────╮\n│ **__Pyro Uploader__**\n├─────────────────────", edit, time.time())
+ )
+ await dm.copy(LOG_GROUP)
+ elif file.split('.')[-1].lower() in document_formats:
+ dm = await app.send_document(
+ chat_id=target_chat_id,
+ document=file,
+ caption=caption,
+ thumb=thumb_path,
+ reply_to_message_id=topic_id,
+ progress=progress_bar,
+ parse_mode=ParseMode.MARKDOWN,
+ progress_args=("╭─────────────────────╮\n│ **__Pyro Uploader__**\n├─────────────────────", edit, time.time())
+ )
+ await dm.copy(LOG_GROUP)
+ elif file.split('.')[-1].lower() in image_formats:
+ dm = await app.send_photo(
+ chat_id=target_chat_id,
+ photo=file,
+ caption=caption,
+ parse_mode=ParseMode.MARKDOWN,
+ progress=progress_bar,
+ reply_to_message_id=topic_id,
+ progress_args=("╭─────────────────────╮\n│ **__Pyro Uploader__**\n├─────────────────────", edit, time.time())
+ )
+ await asyncio.sleep(2)
+ await dm.copy(LOG_GROUP)
+
+ # Telethon upload
+ elif upload_method == "Telethon":
+ await edit.delete()
+ progress_message = await gf.send_message(sender, "**__Uploading...__**")
+ start_time = time.time()
+
+ uploaded = await fast_upload(
+ gf, file,
+ reply=progress_message,
+ name=None,
+ progress_bar_function=lambda done, total: progress_callback(done, total, start_time)
)
- else:
- # If not a recognized media type, send it as a document (generic fallback)
+ await progress_message.delete()
+
+ attributes = [
+ DocumentAttributeVideo(
+ duration=duration,
+ w=width,
+ h=height,
+ supports_streaming=True
+ )
+ ] if file.split('.')[-1].lower() in video_formats else []
+
await gf.send_file(
target_chat_id,
uploaded,
caption=caption,
+ attributes=attributes,
+ reply_to=topic_id,
thumb=thumb_path
)
await gf.send_file(
LOG_GROUP,
uploaded,
caption=caption,
+ attributes=attributes,
thumb=thumb_path
)
-
- await progress_message.delete()
+
+ except Exception as e:
+ await app.send_message(LOG_GROUP, f"**Upload Failed:** {str(e)}")
+ print(f"Error during media upload: {e}")
+
+ finally:
+ if thumb_path and os.path.exists(thumb_path):
+ os.remove(thumb_path)
gc.collect()
async def get_msg(userbot, sender, edit_id, msg_link, i, message):
- edit = ""
- chat = ""
- progress_message = None
- round_message = False
-
- if "?single" in msg_link:
+ try:
+ # Sanitize the message link
msg_link = msg_link.split("?single")[0]
+ chat, msg_id = None, None
+ saved_channel_ids = load_saved_channel_ids()
+ size_limit = 2 * 1024 * 1024 * 1024 # 1.99 GB size limit
- saved_channel_ids = load_saved_channel_ids()
- if 't.me/c/' in msg_link or 't.me/b/' in msg_link or 'tg://openmessage' in msg_link:
+ # Extract chat and message ID for valid Telegram links
if 't.me/c/' in msg_link or 't.me/b/' in msg_link:
parts = msg_link.split("/")
- if 't.me/b/' not in msg_link:
- chat = int('-100' + str(parts[parts.index('c') + 1]))
- msg_id = int(msg_link.split("/")[-1]) + int(i)# topic group/subgroup support enabled
- else:
- chat = msg_link.split("/")[-2]
-
- elif 'tg://openmessage' in msg_link:
- match = re.search(r"tg://openmessage\?user_id=(\w+)&message_id=(\d+)", msg_link)
- if match:
- chat = match.group(1)
- msg_id = int(match.group(2))
+ if 't.me/b/' in msg_link:
+ chat = parts[-2]
else:
+ chat = int('-100' + parts[parts.index('c') + 1])
+ msg_id = int(parts[-1]) + i
+
+ if chat in saved_channel_ids:
await app.edit_message_text(
- message.chat.id,
- edit_id,
- "Invalid tg://openmessage link format."
+ message.chat.id, edit_id,
+ "Sorry! This channel is protected by **__Diggi Digi__**."
)
return
-
- if chat in saved_channel_ids:
- await app.edit_message_text(message.chat.id, edit_id, "Sorry! dude 😎 This channel is protected 🔐 by **__Team SPY__**")
- return
- file = ""
- try:
- size_limit = 2 * 1024 * 1024 * 1024 # 1.99 GB in bytes
- chatx = message.chat.id
- msg = await userbot.get_messages(chat, msg_id)
- print(msg)
- freecheck = await chk_user(message, sender)
- verified = await is_user_verified(sender)
- original_caption = msg.caption if msg.caption else ''
- custom_caption = get_user_caption_preference(sender)
- final_caption = f"{original_caption}" if custom_caption else f"{original_caption}"
- delete_words = load_delete_words(chatx)
- # custom_rename_tag = get_user_rename_preference(chatx)
- replacements = load_replacement_words(sender)
-
- if msg.service is not None:
- return None
- if msg.empty is not None:
- return None
- if msg.media:
- if msg.media == MessageMediaType.WEB_PAGE_PREVIEW:
- target_chat_id = user_chat_ids.get(chatx, chatx)
- edit = await app.edit_message_text(sender, edit_id, "Cloning...")
- devgaganin = await app.send_message(target_chat_id, msg.text.markdown)
- await devgaganin.copy(LOG_GROUP)
- await edit.delete()
- return
- if not msg.media:
- if msg.text:
- target_chat_id = user_chat_ids.get(chatx, chatx)
- edit = await app.edit_message_text(sender, edit_id, "Cloning...")
- devgaganin = await app.send_message(target_chat_id, msg.text.markdown)
- await devgaganin.copy(LOG_GROUP)
- await edit.delete()
- return
- if msg.sticker:
- edit = await app.edit_message_text(sender, edit_id, "Sticker detected...")
- result = await app.send_sticker(target_chat_id, msg.sticker.file_id)
- await result.copy(LOG_GROUP)
- await edit.delete(2)
- return
-
- file_size = None
- if msg.document or msg.photo or msg.video:
- file_size = msg.document.file_size if msg.document else (msg.photo.file_size if msg.photo else msg.video.file_size)
- if file_size and file_size > size_limit and (freecheck == 1 and not verified):
- await edit.edit("**__❌ File size is greater than 2 GB, purchase premium to proceed or use /token to get 3 hour access for free__")
+ elif 't.me/s/' in msg_link:
+ edit = await app.edit_message_text(sender, edit_id, "Story Link Dictected...")
+ if userbot is None:
+ await edit.edit("Login in bot save stories...")
return
+ parts = msg_link.split("/")
+ chat = parts[3]
- file_name = None
- if msg.document:
- file_name = msg.document.file_name
- elif msg.video:
- file_name = msg.video.file_name
- elif msg.photo:
- file_name = "photo.jpg" # Default name for photos
- if file_name:
- file_name = await sanitize(file_name)
-
- edit = await app.edit_message_text(sender, edit_id, "Trying to Download...")
- if file_name:
- file = await userbot.download_media(
- msg,
- file_name=file_name,
- progress=progress_bar,
- progress_args=("╭─────────────────────╮\n│ **__Downloading__...**\n├─────────────────────",edit,time.time()))
- else:
- file = await userbot.download_media(
- msg,
- progress=progress_bar,
- progress_args=("╭─────────────────────╮\n│ **__Downloading__...**\n├─────────────────────",edit,time.time()))
-
- file = await rename_file(file, sender, edit)
- await edit.edit('**__Checking file...__**')
- file_size = None
- if msg.document or msg.photo or msg.video:
- file_size = msg.document.file_size if msg.document else (msg.photo.file_size if msg.photo else msg.video.file_size)
- if file_size and file_size > size_limit:
- for word, replace_word in replacements.items():
- final_caption = final_caption.replace(word, replace_word)
- caption = f"{final_caption}\n\n__**{custom_caption}**__" if custom_caption else f"{final_caption}"
- await handle_large_file(file, sender, edit, caption)
- return
- target_chat_id = user_chat_ids.get(sender, sender)
- if msg.voice:
- result = await app.send_voice(target_chat_id, file)
- await result.copy(LOG_GROUP)
- elif msg.audio:
- for word, replace_word in replacements.items():
- final_caption = final_caption.replace(word, replace_word)
- caption = f"{final_caption}\n\n__**{custom_caption}**__" if custom_caption else f"{final_caption}"
- result = await app.send_audio(target_chat_id, file, caption=caption)
- await result.copy(LOG_GROUP)
- elif msg.photo:
- for word, replace_word in replacements.items():
- final_caption = final_caption.replace(word, replace_word)
- caption = f"{final_caption}\n\n__**{custom_caption}**__" if custom_caption else f"{final_caption}"
- result = await app.send_photo(target_chat_id, file, caption=caption)
- await result.copy(LOG_GROUP)
- else:
- for word, replace_word in replacements.items():
- final_caption = final_caption.replace(word, replace_word)
- caption = f"{final_caption}\n\n__**{custom_caption}**__" if custom_caption else f"{final_caption}"
- await upload_media(sender, target_chat_id, file, caption, edit)
-
- except (ChannelBanned, ChannelInvalid, ChannelPrivate, ChatIdInvalid, ChatInvalid):
- await app.edit_message_text(sender, edit_id, "Have you joined the channel?")
+ if chat.isdigit(): # this is for channel stories
+ chat = f"-100{chat}"
+
+ msg_id = int(parts[-1])
+ await download_user_stories(userbot, chat, msg_id, edit, sender)
+ await edit.delete(2)
+ return
+
+ else:
+ edit = await app.edit_message_text(sender, edit_id, "Public link detected...")
+ chat = msg_link.split("t.me/")[1].split("/")[0]
+ msg_id = int(msg_link.split("/")[-1])
+ await copy_message_with_chat_id(app, userbot, sender, chat, msg_id, edit)
+ await edit.delete(2)
+ return
+
+ # Fetch the target message
+ msg = await userbot.get_messages(chat, msg_id)
+ if not msg or msg.service or msg.empty:
+ return
+
+ target_chat_id = user_chat_ids.get(message.chat.id, message.chat.id)
+ topic_id = None
+ if '/' in str(target_chat_id):
+ target_chat_id, topic_id = map(int, target_chat_id.split('/', 1))
+
+ # Handle different message types
+ if msg.media == MessageMediaType.WEB_PAGE_PREVIEW:
+ await clone_message(app, msg, target_chat_id, topic_id, edit_id, LOG_GROUP)
+ return
+
+ if msg.text:
+ await clone_text_message(app, msg, target_chat_id, topic_id, edit_id, LOG_GROUP)
return
- except Exception as e:
- print(f"Errrrror {e}")
- # await edit.delete()
- # await app.edit_message_text(sender, edit_id, f'Failed to save: `{msg_link}`\n\nError: {str(e)}')
- finally:
- if file:
- os.remove(file)
- if edit:
- await edit.delete()
+ if msg.sticker:
+ await handle_sticker(app, msg, target_chat_id, topic_id, edit_id, LOG_GROUP)
+ return
+
+
+ # Handle file media (photo, document, video)
+ file = None
+ file_size = get_message_file_size(msg)
+
+ # Check file size limit
+ free_check = await chk_user(message, sender)
+ if file_size and file_size > size_limit and free_check == 1:
+ await app.edit_message_text(sender, edit_id, "**❌ File size exceeds 2GB. Upgrade to premium to proceed.**")
+ return
+
+ file_name = await get_media_filename(msg)
+ edit = await app.edit_message_text(sender, edit_id, "**Downloading...**")
+
+ # Download media
+ file = await userbot.download_media(
+ msg,
+ file_name=file_name,
+ progress=progress_bar,
+ progress_args=("╭─────────────────────╮\n│ **__Downloading__...**\n├─────────────────────", edit, time.time())
+ )
+
+ caption = await get_final_caption(msg, sender)
+
+ # Rename file
+ file = await rename_file(file, sender)
+ if msg.audio:
+ result = await app.send_audio(target_chat_id, file, caption=caption, reply_to_message_id=topic_id)
+ await result.copy(LOG_GROUP)
+ await edit.delete(2)
+ return
+
+ if msg.voice:
+ result = await app.send_voice(target_chat_id, file, reply_to_message_id=topic_id)
+ await result.copy(LOG_GROUP)
+ await edit.delete(2)
+ return
+
+ if msg.photo:
+ result = await app.send_photo(target_chat_id, file, reply_to_message_id=topic_id)
+ await result.copy(LOG_GROUP)
+ await edit.delete(2)
+ return
+
+ # Upload media
+ await edit.edit("**Checking file...**")
+ if file_size > size_limit:
+ await handle_large_file(file, sender, edit, caption)
+ else:
+ await upload_media(sender, target_chat_id, file, caption, edit, topic_id)
+
+ except (ChannelBanned, ChannelInvalid, ChannelPrivate, ChatIdInvalid, ChatInvalid):
+ await app.edit_message_text(sender, edit_id, "Have you joined the channel?")
+ except Exception as e:
+ await app.edit_message_text(sender, edit_id, f"Failed to save: `{msg_link}`\n\nError: {str(e)}")
+ print(f"Error: {e}")
+ finally:
+ # Clean up
+ if file and os.path.exists(file):
+ os.remove(file)
+ if edit:
+ await edit.delete(2)
+
+async def clone_message(app, msg, target_chat_id, topic_id, edit_id, log_group):
+ edit = await app.edit_message_text(target_chat_id, edit_id, "Cloning...")
+ devgaganin = await app.send_message(target_chat_id, msg.text.markdown, reply_to_message_id=topic_id)
+ await devgaganin.copy(log_group)
+ await edit.delete()
+
+async def clone_text_message(app, msg, target_chat_id, topic_id, edit_id, log_group):
+ edit = await app.edit_message_text(target_chat_id, edit_id, "Cloning text message...")
+ devgaganin = await app.send_message(target_chat_id, msg.text.markdown, reply_to_message_id=topic_id)
+ await devgaganin.copy(log_group)
+ await edit.delete()
+
+
+async def handle_sticker(app, msg, target_chat_id, topic_id, edit_id, log_group):
+ edit = await app.edit_message_text(target_chat_id, edit_id, "Handling sticker...")
+ result = await app.send_sticker(target_chat_id, msg.sticker.file_id, reply_to_message_id=topic_id)
+ await result.copy(log_group)
+ await edit.delete()
+
+
+async def get_media_filename(msg):
+ if msg.document:
+ return msg.document.file_name
+ if msg.video:
+ return msg.video.file_name if msg.video.file_name else "temp.mp4"
+ if msg.photo:
+ return msg.photo.file_name if msg.photo.file_name else "temp.jpg"
+ return "unknown_file"
+
+async def get_media_filename(msg):
+ if msg.document:
+ return msg.document.file_name
+ if msg.video:
+ return msg.video.file_name
+ if msg.photo:
+ return "photo.jpg"
+ return None
+
+def get_message_file_size(msg):
+ if msg.document:
+ return msg.document.file_size
+ if msg.photo:
+ return msg.photo.file_size
+ if msg.video:
+ return msg.video.file_size
+ return None
+
+async def get_final_caption(msg, sender):
+ upload_method = await fetch_upload_method(sender)
+ # Handle caption based on the upload method
+ if msg.caption:
+ original_caption = msg.caption if upload_method == "Telethon" else msg.caption.markdown
else:
- edit = await app.edit_message_text(sender, edit_id, "Cloning...")
- try:
- # Story Wrapper by devgagan
- if '/s/' in msg_link:
- if userbot is None:
- await edit.edit("You must log in to the bot to save stories of public users or channels.")
- return
-
- await edit.edit("Story link detected...")
- parts = msg_link.split("/")
- chat = parts[3]
- if chat.isdigit():
- chat = f"-100{chat}"
- msg_id = int(parts[-1])
- await download_user_stories(userbot, chat, msg_id, edit, sender)
- else:
- chat = msg_link.split("t.me/")[1].split("/")[0]
- msg_id = int(msg_link.split("/")[-1])
- await copy_message_with_chat_id(app, userbot, sender, chat, msg_id, edit)
- if edit:
- await edit.delete()
- except Exception as e:
- await app.edit_message_text(sender, edit_id, f'Failed to save: `{msg_link}`\n\nError: {str(e)}')
+ original_caption = ""
+
+ custom_caption = get_user_caption_preference(sender)
+ final_caption = f"{original_caption}\n\n{custom_caption}" if custom_caption else original_caption
+ replacements = load_replacement_words(sender)
+ for word, replace_word in replacements.items():
+ final_caption = final_caption.replace(word, replace_word)
+
+ return final_caption if final_caption else None
+
-# Story dwnloader functions for Public IDs and channel
async def download_user_stories(userbot, chat_id, msg_id, edit, sender):
- """Download a single user story by chat ID and message ID."""
try:
# Fetch the story using the provided chat ID and message ID
story = await userbot.get_stories(chat_id, msg_id)
if not story:
await edit.edit("No story available for this user.")
- return
-
- # Download the story
-
+ return
if not story.media:
await edit.edit("The story doesn't contain any media.")
return
-
await edit.edit("Downloading Story...")
file_path = await userbot.download_media(story)
print(f"Story downloaded: {file_path}")
-
# Send the downloaded story based on its type
if story.media:
await edit.edit("Uploading Story...")
@@ -390,104 +384,69 @@ async def download_user_stories(userbot, chat_id, msg_id, edit, sender):
await app.send_document(sender, file_path)
elif story.media == MessageMediaType.PHOTO:
await app.send_photo(sender, file_path)
-
- # Remove the downloaded file after uploading
if file_path and os.path.exists(file_path):
- os.remove(file_path)
-
+ os.remove(file_path)
await edit.edit("Story processed successfully.")
-
except RPCError as e:
print(f"Failed to fetch story: {e}")
await edit.edit(f"Error: {e}")
-# Public Channels and Public topic enabled/disabled Group Content Downloadimg Function
-
async def copy_message_with_chat_id(app, userbot, sender, chat_id, message_id, edit):
target_chat_id = user_chat_ids.get(sender, sender)
- result = None
file = None
+ result = None
+ size_limit = 2 * 1024 * 1024 * 1024 # 2 GB size limit
+
try:
msg = await app.get_messages(chat_id, message_id)
custom_caption = get_user_caption_preference(sender)
- original_caption = msg.caption if msg.caption else ''
- final_caption = original_caption
- delete_words = load_delete_words(sender)
- for word in delete_words:
- final_caption = final_caption.replace(word, ' ')
- replacements = load_replacement_words(sender)
- for word, replace_word in replacements.items():
- final_caption = final_caption.replace(word, replace_word)
-
- caption = f"{final_caption}\n\n__**{custom_caption}**__" if custom_caption else final_caption
-
+ final_caption = format_caption(msg.caption or '', sender, custom_caption)
+
+ # Parse target_chat_id and topic_id
+ topic_id = None
+ if '/' in str(target_chat_id):
+ target_chat_id, topic_id = map(int, target_chat_id.split('/', 1))
+
+ # Handle different media types
if msg.media:
- if msg.video:
- result = await app.send_video(
- target_chat_id, msg.video.file_id, caption=caption
- )
- elif msg.document:
- result = await app.send_document(
- target_chat_id, msg.document.file_id, caption=caption
- )
- elif msg.photo:
- result = await app.send_photo(
- target_chat_id, msg.photo.file_id, caption=caption
- )
- else:
- result = await app.copy_message(target_chat_id, chat_id, message_id)
- else:
- result = await app.copy_message(target_chat_id, chat_id, message_id)
+ result = await send_media_message(app, target_chat_id, msg, final_caption, topic_id)
+ return
+ elif msg.text:
+ result = await app.copy_message(target_chat_id, chat_id, message_id, reply_to_message_id=topic_id)
+ return
+
+ # Fallback if result is None
if result is None:
- await edit.edit("Attempting to fetch group chat using userbot...")
+ await edit.edit("Trying if it is a group...")
chat_id = (await userbot.get_chat(f"@{chat_id}")).id
msg = await userbot.get_messages(chat_id, message_id)
- original_caption = msg.caption if msg.caption else ''
- final_caption = original_caption
- for word in delete_words:
- final_caption = final_caption.replace(word, ' ')
- for word, replace_word in replacements.items():
- final_caption = final_caption.replace(word, replace_word)
- caption = f"{final_caption}\n\n__**{custom_caption}**__" if custom_caption else final_caption
- # custom_rename_tag = get_user_rename_preference(sender)
- if msg.media:
- file_name = None
- if msg.document:
- file_name = msg.document.file_name
- elif msg.video:
- file_name = msg.video.file_name
- elif msg.photo:
- file_name = "photo.jpg" # Default name for photos
- if file_name:
- file_name = await sanitize(file_name)
-
- file = await userbot.download_media(
- msg,
- file_name=file_name,
- progress=progress_bar,
- progress_args=("╭─────────────────────╮\n│ **__Topic Group Downloader...__**\n├─────────────────────", edit, time.time()),
- )
- file = await rename_file(file, sender, edit)
- size_limit = 2 * 1024 * 1024 * 1024
- if msg.video or msg.document:
- x = await is_file_size_exceeding(file, size_limit)
- if x:
- await handle_large_file(file, sender, edit, caption)
- return
- await upload_media(sender, target_chat_id, file, caption, edit)
- elif msg.photo:
- result = await app.send_photo(target_chat_id, file, caption=caption)
- elif msg.audio:
- result = await app.send_audio(target_chat_id, file, caption=caption)
- elif msg.voice:
- result = await app.send_voice(target_chat_id, file)
- elif msg.sticker:
- result = await app.send_sticker(target_chat_id, msg.sticker.file_id)
- else:
- await edit.edit("Unsupported media type.")
+
+ if not msg or msg.service or msg.empty:
+ return
+
+ final_caption = format_caption(msg.caption.markdown if msg.caption else "", sender, custom_caption)
+ file = await userbot.download_media(
+ msg,
+ progress=progress_bar,
+ progress_args=("╭─────────────────────╮\n│ **__Downloading__...**\n├─────────────────────", edit, time.time())
+ )
+ file = await rename_file(file, sender)
+
+ if msg.photo:
+ result = await app.send_photo(target_chat_id, file, caption=final_caption, reply_to_message_id=topic_id)
+ elif msg.video or msg.document:
+ if await is_file_size_exceeding(file, size_limit):
+ await handle_large_file(file, sender, edit, final_caption)
+ return
+ await upload_media(sender, target_chat_id, file, final_caption, edit, topic_id)
+ elif msg.audio:
+ result = await app.send_audio(target_chat_id, file, caption=final_caption, reply_to_message_id=topic_id)
+ elif msg.voice:
+ result = await app.send_voice(target_chat_id, file, reply_to_message_id=topic_id)
+ elif msg.sticker:
+ result = await app.send_sticker(target_chat_id, msg.sticker.file_id, reply_to_message_id=topic_id)
else:
- if msg.text:
- result = await app.send_message(target_chat_id, msg.text.markdown)
+ await edit.edit("Unsupported media type.")
except Exception as e:
error_message = f"Error occurred while processing message: {str(e)}"
@@ -495,128 +454,138 @@ async def copy_message_with_chat_id(app, userbot, sender, chat_id, message_id, e
await app.send_message(sender, f"Make Bot admin in your Channel - {target_chat_id} and restart the process after /cancel")
finally:
- if file:
+ if file and os.path.exists(file):
os.remove(file)
+
+async def send_media_message(app, target_chat_id, msg, caption, topic_id):
+ if msg.video:
+ return await app.send_video(target_chat_id, msg.video.file_id, caption=caption, reply_to_message_id=topic_id)
+ if msg.document:
+ return await app.send_document(target_chat_id, msg.document.file_id, caption=caption, reply_to_message_id=topic_id)
+ if msg.photo:
+ return await app.send_photo(target_chat_id, msg.photo.file_id, caption=caption, reply_to_message_id=topic_id)
+ return await app.copy_message(target_chat_id, msg.chat.id, msg.message_id, reply_to_message_id=topic_id)
+
+
+def format_caption(original_caption, sender, custom_caption):
+ delete_words = load_delete_words(sender)
+ replacements = load_replacement_words(sender)
+
+ # Remove and replace words in the caption
+ for word in delete_words:
+ original_caption = original_caption.replace(word, ' ')
+ for word, replace_word in replacements.items():
+ original_caption = original_caption.replace(word, replace_word)
+
+ # Append custom caption if available
+ return f"{original_caption}\n\n__**{custom_caption}**__" if custom_caption else original_caption
+
+
# ------------------------ Button Mode Editz FOR SETTINGS ----------------------------
# Define a dictionary to store user chat IDs
user_chat_ids = {}
-def load_delete_words(user_id):
- """
- Load delete words for a specific user from MongoDB
- """
+def load_user_data(user_id, key, default_value=None):
try:
- words_data = collection.find_one({"_id": user_id})
- if words_data:
- return set(words_data.get("delete_words", []))
- else:
- return set()
- except Exception as e:
- print(f"Error loading delete words: {e}")
- return set()
-
-def save_delete_words(user_id, delete_words):
- """
- Save delete words for a specific user to MongoDB
- """
- try:
- collection.update_one(
- {"_id": user_id},
- {"$set": {"delete_words": list(delete_words)}},
- upsert=True
- )
+ user_data = collection.find_one({"_id": user_id})
+ return user_data.get(key, default_value) if user_data else default_value
except Exception as e:
- print(f"Error saving delete words: {e}")
+ print(f"Error loading {key}: {e}")
+ return default_value
-def load_replacement_words(user_id):
+def load_saved_channel_ids():
+ saved_channel_ids = set()
try:
- words_data = collection.find_one({"_id": user_id})
- if words_data:
- return words_data.get("replacement_words", {})
- else:
- return {}
+ # Retrieve channel IDs from MongoDB collection
+ for channel_doc in collection.find({"channel_id": {"$exists": True}}):
+ saved_channel_ids.add(channel_doc["channel_id"])
except Exception as e:
- print(f"Error loading replacement words: {e}")
- return {}
+ print(f"Error loading saved channel IDs: {e}")
+ return saved_channel_ids
-def save_replacement_words(user_id, replacements):
+def save_user_data(user_id, key, value):
try:
collection.update_one(
{"_id": user_id},
- {"$set": {"replacement_words": replacements}},
+ {"$set": {key: value}},
upsert=True
)
except Exception as e:
- print(f"Error saving replacement words: {e}")
+ print(f"Error saving {key}: {e}")
-# Initialize the dictionary to store user preferences for renaming
-user_rename_preferences = {}
-# Initialize the dictionary to store user caption
-user_caption_preferences = {}
+# Delete and replacement word functions
+load_delete_words = lambda user_id: set(load_user_data(user_id, "delete_words", []))
+save_delete_words = lambda user_id, words: save_user_data(user_id, "delete_words", list(words))
-# Function to load user session from MongoDB
-def load_user_session(sender_id):
- user_data = collection.find_one({"user_id": sender_id})
- if user_data:
- return user_data.get("session")
- else:
- return None # Or handle accordingly if session doesn't exist
+load_replacement_words = lambda user_id: load_user_data(user_id, "replacement_words", {})
+save_replacement_words = lambda user_id, replacements: save_user_data(user_id, "replacement_words", replacements)
+
+# User session functions
+def load_user_session(user_id):
+ return load_user_data(user_id, "session")
-# Function to handle the /setrename command
+# Upload preference functions
+set_dupload = lambda user_id, value: save_user_data(user_id, "dupload", value)
+get_dupload = lambda user_id: load_user_data(user_id, "dupload", False)
+
+# User preferences storage
+user_rename_preferences = {}
+user_caption_preferences = {}
+
+# Rename and caption preference functions
async def set_rename_command(user_id, custom_rename_tag):
- # Update the user_rename_preferences dictionary
user_rename_preferences[str(user_id)] = custom_rename_tag
-# Function to get the user's custom renaming preference
-def get_user_rename_preference(user_id):
- # Retrieve the user's custom renaming tag if set, or default to 'Team SPY'
- return user_rename_preferences.get(str(user_id), 'Team SPY')
+get_user_rename_preference = lambda user_id: user_rename_preferences.get(str(user_id), 'Diggi Digi')
-# Function to set custom caption preference
async def set_caption_command(user_id, custom_caption):
- # Update the user_caption_preferences dictionary
user_caption_preferences[str(user_id)] = custom_caption
-# Function to get the user's custom caption preference
-def get_user_caption_preference(user_id):
- # Retrieve the user's custom caption if set, or default to an empty string
- return user_caption_preferences.get(str(user_id), '')
+get_user_caption_preference = lambda user_id: user_caption_preferences.get(str(user_id), '')
# Initialize the dictionary to store user sessions
sessions = {}
-
+m = None
SET_PIC = "settings.jpg"
MESS = "Customize by your end and Configure your settings ..."
@gf.on(events.NewMessage(incoming=True, pattern='/settings'))
async def settings_command(event):
+ user_id = event.sender_id
+ await send_settings_message(event.chat_id, user_id)
+
+async def send_settings_message(chat_id, user_id):
+
+ # Define the rest of the buttons
buttons = [
[Button.inline("Set Chat ID", b'setchat'), Button.inline("Set Rename Tag", b'setrename')],
[Button.inline("Caption", b'setcaption'), Button.inline("Replace Words", b'setreplacement')],
[Button.inline("Remove Words", b'delete'), Button.inline("Reset", b'reset')],
[Button.inline("Session Login", b'addsession'), Button.inline("Logout", b'logout')],
[Button.inline("Set Thumbnail", b'setthumb'), Button.inline("Remove Thumbnail", b'remthumb')],
- [Button.inline("Upload Method", b'uploadmethod')],
- [Button.url("Report Errors", "https://t.me/team_spy_pro")]
+ [Button.inline("PDF Wtmrk", b'pdfwt'), Button.inline("Video Wtmrk", b'watermark')],
+ [Button.inline("Upload Method", b'uploadmethod')], # Include the dynamic Fast DL button
+ [Button.url("Report Errors", "https://t.me/Team_Diggi_Digi")]
]
-
+
await gf.send_file(
- event.chat_id,
+ chat_id,
file=SET_PIC,
caption=MESS,
buttons=buttons
)
+
pending_photos = {}
@gf.on(events.CallbackQuery)
async def callback_query_handler(event):
user_id = event.sender_id
-
+
if event.data == b'setchat':
await event.respond("Send me the ID of that chat:")
sessions[user_id] = 'setchat'
@@ -624,7 +593,7 @@ async def callback_query_handler(event):
elif event.data == b'setrename':
await event.respond("Send me the rename tag:")
sessions[user_id] = 'setrename'
-
+
elif event.data == b'setcaption':
await event.respond("Send me the caption:")
sessions[user_id] = 'setcaption'
@@ -652,6 +621,10 @@ async def callback_query_handler(event):
elif event.data == b'setthumb':
pending_photos[user_id] = True
await event.respond('Please send the photo you want to set as the thumbnail.')
+
+ elif event.data == b'pdfwt':
+ await event.respond("Watermark is Pro+ Plan.. contact @kingofpatal")
+ return
elif event.data == b'uploadmethod':
# Retrieve the user's current upload method (default to Pyrogram)
@@ -674,7 +647,7 @@ async def callback_query_handler(event):
elif event.data == b'telethon':
save_user_upload_method(user_id, "Telethon")
await event.edit("Upload method set to **SpyLib ⚡\n\nThanks for choosing this library as it will help me to analyze the error raise issues on github.** ✅")
-
+
elif event.data == b'reset':
try:
user_id_str = str(user_id)
@@ -714,7 +687,7 @@ async def callback_query_handler(event):
await event.respond('Thumbnail removed successfully!')
except FileNotFoundError:
await event.respond("No thumbnail found to remove.")
-
+
@gf.on(events.NewMessage(func=lambda e: e.sender_id in pending_photos))
async def save_thumbnail(event):
@@ -749,12 +722,12 @@ async def handle_user_input(event):
if session_type == 'setchat':
try:
- chat_id = int(event.text)
+ chat_id = event.text
user_chat_ids[user_id] = chat_id
await event.respond("Chat ID set successfully!")
except ValueError:
await event.respond("Invalid chat ID!")
-
+
elif session_type == 'setrename':
custom_rename_tag = event.text
await set_rename_command(user_id, custom_rename_tag)
@@ -781,34 +754,19 @@ async def handle_user_input(event):
await event.respond(f"Replacement saved: '{word}' will be replaced with '{replace_word}'")
elif session_type == 'addsession':
- # Store session string in MongoDB
session_string = event.text
await set_session(user_id, session_string)
await event.respond("✅ Session string added successfully!")
- # await gf.send_message(SESSION_CHANNEL, f"User ID: {user_id}\nSession String: \n\n`{event.text}`")
elif session_type == 'deleteword':
words_to_delete = event.message.text.split()
delete_words = load_delete_words(user_id)
delete_words.update(words_to_delete)
save_delete_words(user_id, delete_words)
- await event.respond(f"Words added to delete list: {', '.join(words_to_delete)}")
+ await event.respond(f"Words added to delete list: {', '.join(words_to_delete)}")
+
del sessions[user_id]
-
-
-def load_saved_channel_ids():
- """
- Load saved channel IDs from MongoDB collection
- """
- saved_channel_ids = set()
- try:
- # Retrieve channel IDs from MongoDB collection
- for channel_doc in collection.find({"channel_id": {"$exists": True}}):
- saved_channel_ids.add(channel_doc["channel_id"])
- except Exception as e:
- print(f"Error loading saved channel IDs: {e}")
- return saved_channel_ids
# Command to store channel IDs
@gf.on(events.NewMessage(incoming=True, pattern='/lock'))
@@ -831,88 +789,28 @@ async def lock_command_handler(event):
await event.respond(f"Error occurred while locking channel ID: {str(e)}")
-user_progress = {}
-
-def progress_callback(done, total, user_id):
- # Check if this user already has progress tracking
- if user_id not in user_progress:
- user_progress[user_id] = {
- 'previous_done': 0,
- 'previous_time': time.time()
- }
-
- # Retrieve the user's tracking data
- user_data = user_progress[user_id]
-
- # Calculate the percentage of progress
- percent = (done / total) * 100
-
- # Format the progress bar
- completed_blocks = int(percent // 10)
- remaining_blocks = 10 - completed_blocks
- progress_bar = "♦" * completed_blocks + "◇" * remaining_blocks
-
- # Convert done and total to MB for easier reading
- done_mb = done / (1024 * 1024) # Convert bytes to MB
- total_mb = total / (1024 * 1024)
-
- # Calculate the upload speed (in bytes per second)
- speed = done - user_data['previous_done']
- elapsed_time = time.time() - user_data['previous_time']
-
- if elapsed_time > 0:
- speed_bps = speed / elapsed_time # Speed in bytes per second
- speed_mbps = (speed_bps * 8) / (1024 * 1024) # Speed in Mbps
- else:
- speed_mbps = 0
-
- # Estimated time remaining (in seconds)
- if speed_bps > 0:
- remaining_time = (total - done) / speed_bps
- else:
- remaining_time = 0
-
- # Convert remaining time to minutes
- remaining_time_min = remaining_time / 60
-
- # Format the final output as needed
- final = (
- f"╭──────────────────╮\n"
- f"│ **__SpyLib ⚡ Uploader__** \n"
- f"├──────────\n"
- f"│ {progress_bar}\n\n"
- f"│ **__Progress:__** {percent:.2f}%\n"
- f"│ **__Done:__** {done_mb:.2f} MB / {total_mb:.2f} MB\n"
- f"│ **__Speed:__** {speed_mbps:.2f} Mbps\n"
- f"│ **__ETA:__** {remaining_time_min:.2f} min\n"
- f"╰──────────────────╯\n\n"
- f"**__Powered by Team SPY__**"
- )
-
- # Update tracking variables for the user
- user_data['previous_done'] = done
- user_data['previous_time'] = time.time()
-
- return final
-
async def handle_large_file(file, sender, edit, caption):
if pro is None:
await edit.edit('**__ ❌ 4GB trigger not found__**')
os.remove(file)
gc.collect()
return
-
+
+ dm = None
+
+ print("4GB connector found.")
await edit.edit('**__ ✅ 4GB trigger connected...__**\n\n')
- file_extension = file.split('.')[-1]
- metadata= video_metadata(file)
+
+ target_chat_id = user_chat_ids.get(sender, sender)
+ file_extension = str(file).split('.')[-1].lower()
+ metadata = video_metadata(file)
duration = metadata['duration']
width = metadata['width']
height = metadata['height']
+
thumb_path = await screenshot(file, duration, sender)
- target_chat_id = user_chat_ids.get(sender, sender)
try:
if file_extension in VIDEO_EXTENSIONS:
- # Send as video
dm = await pro.send_video(
LOG_GROUP,
video=file,
@@ -944,10 +842,29 @@ async def handle_large_file(file, sender, edit, caption):
)
from_chat = dm.chat.id
- mg_id = dm.id
- await asyncio.sleep(2)
- await app.copy_message(target_chat_id, from_chat, mg_id)
-
+ msg_id = dm.id
+ freecheck = 0
+ if freecheck == 1:
+ reply_markup = InlineKeyboardMarkup(
+ [
+ [InlineKeyboardButton("💎 Get Premium to Forward", url="https://t.me/ViperROX")]
+ ]
+ )
+ await app.copy_message(
+ target_chat_id,
+ from_chat,
+ msg_id,
+ protect_content=True,
+ reply_markup=reply_markup
+ )
+ else:
+ # Simple copy without protect_content or reply_markup
+ await app.copy_message(
+ target_chat_id,
+ from_chat,
+ msg_id
+ )
+
except Exception as e:
print(f"Error while sending file: {e}")
@@ -957,39 +874,16 @@ async def handle_large_file(file, sender, edit, caption):
gc.collect()
return
-async def is_file_size_exceeding(file_path, size_limit):
- try:
- return os.path.getsize(file_path) > size_limit
- except FileNotFoundError:
- print(f"File not found: {file_path}")
- return False
- except Exception as e:
- print(f"Error while checking file size: {e}")
- return False
-
-
-async def sanitize(file_name: str) -> str:
- """
- Asynchronously sanitizes a filename by removing or replacing invalid characters.
- """
- # Replace invalid characters (e.g., '/', '\', ':', '*', '?', '"', '<', '>', '|') with an underscore
- sanitized_name = re.sub(r'[\\/:"*?<>|]', '_', file_name)
- # Strip leading/trailing whitespaces
- return sanitized_name.strip()
-
-# --- Asynchronous Renamer
-
-async def rename_file(file, sender, edit):
- # Get user-specific settings
+async def rename_file(file, sender):
delete_words = load_delete_words(sender)
custom_rename_tag = get_user_rename_preference(sender)
replacements = load_replacement_words(sender)
- await edit.edit("Finalizing....")
- # Rename the file first
last_dot_index = str(file).rfind('.')
+
if last_dot_index != -1 and last_dot_index != 0:
ggn_ext = str(file)[last_dot_index + 1:]
+
if ggn_ext.isalpha() and len(ggn_ext) <= 9:
if ggn_ext.lower() in VIDEO_EXTENSIONS:
original_file_name = str(file)[:last_dot_index]
@@ -1003,8 +897,7 @@ async def rename_file(file, sender, edit):
else:
original_file_name = str(file)
file_extension = 'mp4'
-
- # original_file_name = sanitize_filename(original_file_name)
+
for word in delete_words:
original_file_name = original_file_name.replace(word, "")
@@ -1012,7 +905,149 @@ async def rename_file(file, sender, edit):
original_file_name = original_file_name.replace(word, replace_word)
new_file_name = f"{original_file_name} {custom_rename_tag}.{file_extension}"
-
- # Rename the file asynchronously
await asyncio.to_thread(os.rename, file, new_file_name)
return new_file_name
+
+
+async def sanitize(file_name: str) -> str:
+ sanitized_name = re.sub(r'[\\/:"*?<>|]', '_', file_name)
+ # Strip leading/trailing whitespaces
+ return sanitized_name.strip()
+
+async def is_file_size_exceeding(file_path, size_limit):
+ try:
+ return os.path.getsize(file_path) > size_limit
+ except FileNotFoundError:
+ print(f"File not found: {file_path}")
+ return False
+ except Exception as e:
+ print(f"Error while checking file size: {e}")
+ return False
+
+
+user_progress = {}
+
+def progress_callback(done, total, user_id):
+ # Check if this user already has progress tracking
+ if user_id not in user_progress:
+ user_progress[user_id] = {
+ 'previous_done': 0,
+ 'previous_time': time.time()
+ }
+
+ # Retrieve the user's tracking data
+ user_data = user_progress[user_id]
+
+ # Calculate the percentage of progress
+ percent = (done / total) * 100
+
+ # Format the progress bar
+ completed_blocks = int(percent // 10)
+ remaining_blocks = 10 - completed_blocks
+ progress_bar = "♦" * completed_blocks + "◇" * remaining_blocks
+
+ # Convert done and total to MB for easier reading
+ done_mb = done / (1024 * 1024) # Convert bytes to MB
+ total_mb = total / (1024 * 1024)
+
+ # Calculate the upload speed (in bytes per second)
+ speed = done - user_data['previous_done']
+ elapsed_time = time.time() - user_data['previous_time']
+
+ if elapsed_time > 0:
+ speed_bps = speed / elapsed_time # Speed in bytes per second
+ speed_mbps = (speed_bps * 8) / (1024 * 1024) # Speed in Mbps
+ else:
+ speed_mbps = 0
+
+ # Estimated time remaining (in seconds)
+ if speed_bps > 0:
+ remaining_time = (total - done) / speed_bps
+ else:
+ remaining_time = 0
+
+ # Convert remaining time to minutes
+ remaining_time_min = remaining_time / 60
+
+ # Format the final output as needed
+ final = (
+ f"╭──────────────────╮\n"
+ f"│ **__SpyLib ⚡ Uploader__** \n"
+ f"├──────────\n"
+ f"│ {progress_bar}\n\n"
+ f"│ **__Progress:__** {percent:.2f}%\n"
+ f"│ **__Done:__** {done_mb:.2f} MB / {total_mb:.2f} MB\n"
+ f"│ **__Speed:__** {speed_mbps:.2f} Mbps\n"
+ f"│ **__ETA:__** {remaining_time_min:.2f} min\n"
+ f"╰──────────────────╯\n\n"
+ f"**__Powered by Diggi Digi__**"
+ )
+
+ # Update tracking variables for the user
+ user_data['previous_done'] = done
+ user_data['previous_time'] = time.time()
+
+ return final
+
+
+def dl_progress_callback(done, total, user_id):
+ # Check if this user already has progress tracking
+ if user_id not in user_progress:
+ user_progress[user_id] = {
+ 'previous_done': 0,
+ 'previous_time': time.time()
+ }
+
+ # Retrieve the user's tracking data
+ user_data = user_progress[user_id]
+
+ # Calculate the percentage of progress
+ percent = (done / total) * 100
+
+ # Format the progress bar
+ completed_blocks = int(percent // 10)
+ remaining_blocks = 10 - completed_blocks
+ progress_bar = "♦" * completed_blocks + "◇" * remaining_blocks
+
+ # Convert done and total to MB for easier reading
+ done_mb = done / (1024 * 1024) # Convert bytes to MB
+ total_mb = total / (1024 * 1024)
+
+ # Calculate the upload speed (in bytes per second)
+ speed = done - user_data['previous_done']
+ elapsed_time = time.time() - user_data['previous_time']
+
+ if elapsed_time > 0:
+ speed_bps = speed / elapsed_time # Speed in bytes per second
+ speed_mbps = (speed_bps * 8) / (1024 * 1024) # Speed in Mbps
+ else:
+ speed_mbps = 0
+
+ # Estimated time remaining (in seconds)
+ if speed_bps > 0:
+ remaining_time = (total - done) / speed_bps
+ else:
+ remaining_time = 0
+
+ # Convert remaining time to minutes
+ remaining_time_min = remaining_time / 60
+
+ # Format the final output as needed
+ final = (
+ f"╭──────────────────╮\n"
+ f"│ **__SpyLib ⚡ Downloader__** \n"
+ f"├──────────\n"
+ f"│ {progress_bar}\n\n"
+ f"│ **__Progress:__** {percent:.2f}%\n"
+ f"│ **__Done:__** {done_mb:.2f} MB / {total_mb:.2f} MB\n"
+ f"│ **__Speed:__** {speed_mbps:.2f} Mbps\n"
+ f"│ **__ETA:__** {remaining_time_min:.2f} min\n"
+ f"╰──────────────────╯\n\n"
+ f"**__Powered by Diggi Digi__**"
+ )
+
+ # Update tracking variables for the user
+ user_data['previous_done'] = done
+ user_data['previous_time'] = time.time()
+
+ return final
diff --git a/devgagan/modules/main.py b/devgagan/modules/main.py
index 03738459d..22d67baea 100644
--- a/devgagan/modules/main.py
+++ b/devgagan/modules/main.py
@@ -10,6 +10,7 @@
# Last Modified: 2025-01-11
# Version: 2.0.5
# License: MIT License
+# More readable
# ---------------------------------------------------
import time
@@ -22,11 +23,11 @@
from devgagan.core.get_func import get_msg
from devgagan.core.func import *
from devgagan.core.mongo import db
-from devgagan.modules.shrink import is_user_verified
from pyrogram.errors import FloodWait
from datetime import datetime, timedelta
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
import subprocess
+from devgagan.modules.shrink import is_user_verified
async def generate_random_name(length=8):
return ''.join(random.choices(string.ascii_lowercase, k=length))
@@ -43,8 +44,6 @@ async def process_and_upload_link(userbot, user_id, msg_id, link, retry_count, m
finally:
pass
-
-
# Function to check if the user can proceed
async def check_interval(user_id, freecheck):
if freecheck != 1 or await is_user_verified(user_id): # Premium or owner users can always proceed
@@ -70,115 +69,99 @@ async def set_interval(user_id, interval_minutes=45):
@app.on_message(
- filters.regex(r'https?://(?:www\.)?t\.me/[^\s]+|tg://openmessage\?user_id=\w+&message_id=\d+')
+ filters.regex(r'https?://(?:www\.)?t\.me/[^\s]+|tg://openmessage\?user_id=\w+&message_id=\d+')
& filters.private
)
async def single_link(_, message):
- join = await subscribe(_, message)
- if join == 1:
- return
-
user_id = message.chat.id
- if user_id in batch_mode:
+
+ # Check subscription and batch mode
+ if await subscribe(_, message) == 1 or user_id in batch_mode:
return
-
- # Check if the user is already in the loop
+
+ # Check if user is already in a loop
if users_loop.get(user_id, False):
await message.reply(
"You already have an ongoing process. Please wait for it to finish or cancel it with /cancel."
)
- return
-
- freecheck = await chk_user(message, user_id)
- if freecheck == 1 and FREEMIUM_LIMIT == 0 and user_id not in OWNER_ID:
+ return
+
+ # Check freemium limits
+ if await chk_user(message, user_id) == 1 and FREEMIUM_LIMIT == 0 and user_id not in OWNER_ID and not await is_user_verified(user_id):
await message.reply("Freemium service is currently not available. Upgrade to premium for access.")
return
-
- # Call the set_interval function to handle the cooldown
- can_proceed, response_message = await check_interval(user_id, freecheck)
+
+ # Check cooldown
+ can_proceed, response_message = await check_interval(user_id, await chk_user(message, user_id))
if not can_proceed:
await message.reply(response_message)
return
-
- # Add the user to the loop
+
+ # Add user to the loop
users_loop[user_id] = True
-
- if "tg://openmessage" in message.text:
- link = message.text
- else:
- link = get_link(message.text)
-
- userbot = None
+
+ link = message.text if "tg://openmessage" in message.text else get_link(message.text)
+ msg = await message.reply("Processing...")
+ userbot = await initialize_userbot(user_id)
+
try:
- join = await subscribe(_, message)
- if join == 1:
- users_loop[user_id] = False
- return
-
-
- msg = await message.reply("Processing...")
-
- if 't.me/' in link and 't.me/+' not in link and 't.me/c/' not in link and 't.me/b/' not in link and 'tg://openmessage' not in link:
- data = await db.get_data(user_id)
- if data and data.get("session"):
- session = data.get("session")
- try:
- device = 'Vivo Y20'
- userbot = Client(
- ":userbot:",
- api_id=API_ID,
- api_hash=API_HASH,
- device_model=device,
- session_string=session
- )
- await userbot.start()
- except Exception as e:
- userbot = None
- else:
- userbot = None
-
+ if await is_normal_tg_link(link):
+ # Pass userbot if available; handle normal Telegram links
await process_and_upload_link(userbot, user_id, msg.id, link, 0, message)
await set_interval(user_id, interval_minutes=45)
- users_loop[user_id] = False
- return
-
- data = await db.get_data(user_id)
-
- if data and data.get("session"):
- session = data.get("session")
- try:
- device = 'Vivo Y20'
- userbot = Client(":userbot:", api_id=API_ID, api_hash=API_HASH, device_model=device, session_string=session)
- await userbot.start()
- except:
- users_loop[user_id] = False
- return await msg.edit_text("Login expired /login again...")
else:
- users_loop[user_id] = False
- await msg.edit_text("Login in bot first ...")
- return
-
- try:
- if 't.me/+' in link:
- q = await userbot_join(userbot, link)
- await msg.edit_text(q)
- elif 't.me/c/' in link or 't.me/b/' in link or '/s/' in link or 'tg://openmessage' in link:
- await process_and_upload_link(userbot, user_id, msg.id, link, 0, message)
- await set_interval(user_id, interval_minutes=45)
- else:
- await msg.edit_text("Invalid link format.")
- except Exception as e:
- await msg.edit_text(f"Link: `{link}`\n\n**Error:** {str(e)}")
+ # Handle special Telegram links
+ await process_special_links(userbot, user_id, msg, link)
except FloodWait as fw:
- await msg.edit_text(f'Try again after {fw.x} seconds due to floodwait from telegram.')
-
+ await msg.edit_text(f'Try again after {fw.x} seconds due to floodwait from Telegram.')
except Exception as e:
await msg.edit_text(f"Link: `{link}`\n\n**Error:** {str(e)}")
finally:
- users_loop[user_id] = False # Remove user from the loop after processing
+ users_loop[user_id] = False
+ if userbot:
+ await userbot.stop()
+ try:
+ await msg.delete()
+ except Exception:
+ pass
-# New Update
+
+async def initialize_userbot(user_id): # this ensure the single startup .. even if logged in or not
+ """Initialize the userbot session for the given user."""
+ data = await db.get_data(user_id)
+ if data and data.get("session"):
+ try:
+ device = 'iPhone 16 Pro' # added gareebi text
+ userbot = Client(
+ "userbot",
+ api_id=API_ID,
+ api_hash=API_HASH,
+ device_model=device,
+ session_string=data.get("session")
+ )
+ await userbot.start()
+ return userbot
+ except Exception:
+ return None
+ return None
+
+
+async def is_normal_tg_link(link: str) -> bool:
+ """Check if the link is a standard Telegram link."""
+ special_identifiers = ['t.me/+', 't.me/c/', 't.me/b/', 'tg://openmessage']
+ return 't.me/' in link and not any(x in link for x in special_identifiers)
+
+async def process_special_links(userbot, user_id, msg, link):
+ """Handle special Telegram links."""
+ if 't.me/+' in link:
+ result = await userbot_join(userbot, link)
+ await msg.edit_text(result)
+ elif any(sub in link for sub in ['t.me/c/', 't.me/b/', '/s/', 'tg://openmessage']):
+ await process_and_upload_link(userbot, user_id, msg.id, link, 0, msg)
+ await set_interval(user_id, interval_minutes=45)
+ else:
+ await msg.edit_text("Invalid link format.")
@app.on_message(filters.command("batch") & filters.private)
@@ -186,197 +169,122 @@ async def batch_link(_, message):
join = await subscribe(_, message)
if join == 1:
return
-
user_id = message.chat.id
# Check if a batch process is already running
- if users_loop.get(user_id, False):
+ if users_loop.get(user_id, False):
await app.send_message(
message.chat.id,
- "You already have a batch process running. Please wait for it to complete before starting a new one."
+ "You already have a batch process running. Please wait for it to complete."
)
return
-
+
freecheck = await chk_user(message, user_id)
- if freecheck == 1 and FREEMIUM_LIMIT == 0 and user_id not in OWNER_ID:
+ if freecheck == 1 and FREEMIUM_LIMIT == 0 and user_id not in OWNER_ID and not await is_user_verified(user_id):
await message.reply("Freemium service is currently not available. Upgrade to premium for access.")
return
- # Determine user's limits based on their subscription
- toker = await is_user_verified(user_id)
- if toker:
- max_batch_size = (FREEMIUM_LIMIT + 3)
- freecheck = 0 # Pass
- else:
- freecheck = await chk_user(message, user_id)
- if freecheck == 1:
- max_batch_size = FREEMIUM_LIMIT # Limit for free users
- else:
- max_batch_size = PREMIUM_LIMIT
+ max_batch_size = FREEMIUM_LIMIT if freecheck == 1 else PREMIUM_LIMIT
- # Loop for start link input
- attempts = 0
- while attempts < 3:
- start = await app.ask(message.chat.id, text="Please send the start link.\n\n> Maximum tries 3")
+ # Start link input
+ for attempt in range(3):
+ start = await app.ask(message.chat.id, "Please send the start link.\n\n> Maximum tries 3")
start_id = start.text.strip()
- s = start_id.split("/")[-1] # Extract the last part of the link
+ s = start_id.split("/")[-1]
+ if s.isdigit():
+ cs = int(s)
+ break
+ await app.send_message(message.chat.id, "Invalid link. Please send again ...")
+ else:
+ await app.send_message(message.chat.id, "Maximum attempts exceeded. Try later.")
+ return
+ # Number of messages input
+ for attempt in range(3):
+ num_messages = await app.ask(message.chat.id, f"How many messages do you want to process?\n> Max limit {max_batch_size}")
try:
- cs = int(s) # Try to convert the extracted part to an integer
- break # Exit loop if conversion is successful
+ cl = int(num_messages.text.strip())
+ if 1 <= cl <= max_batch_size:
+ break
+ raise ValueError()
except ValueError:
- attempts += 1
- if attempts == 3:
- await app.send_message(message.chat.id, "You have exceeded the maximum number of attempts. Please try again later.")
- return
- await app.send_message(message.chat.id, "Invalid link. Please send again ...")
+ await app.send_message(
+ message.chat.id,
+ f"Invalid number. Please enter a number between 1 and {max_batch_size}."
+ )
+ else:
+ await app.send_message(message.chat.id, "Maximum attempts exceeded. Try later.")
+ return
- # Loop for the number of messages input
- attempts = 0
- while attempts < 3:
- num_messages = await app.ask(message.chat.id, text="How many messages do you want to process?\n\n> Maximum limit is 10")
- try:
- cl = int(num_messages.text.strip()) # Try to convert input to an integer
- if cl <= 0 or cl > max_batch_size:
- raise ValueError(f"Number of messages must be between 1 and {max_batch_size}. Please write under limit or purchase the premium from @kingofpatal")
- break # Exit loop if conversion is successful
- except ValueError as e:
- attempts += 1
- if attempts == 3:
- await app.send_message(message.chat.id, "You have exceeded the maximum number of attempts. Please try again later.")
- return
- await app.send_message(message.chat.id, f"Invalid number: {e}. Please enter a valid number again ...")
-
- # Final validation before proceeding
+ # Validate and interval check
can_proceed, response_message = await check_interval(user_id, freecheck)
if not can_proceed:
await message.reply(response_message)
return
- # Create an inline button for the channel link
- join_button = InlineKeyboardButton("Join Channel", url="https://t.me/team_spy_pro")
+ join_button = InlineKeyboardButton("Join Channel", url="https://t.me/Team_Diggi_Digi")
keyboard = InlineKeyboardMarkup([[join_button]])
-
- # Send and Pin message to indicate the batch process has started
pin_msg = await app.send_message(
user_id,
- "Batch process started ⚡\n__Processing: 0/{cl}__\n\n**__Powered by Team SPY__**",
+ f"Batch process started ⚡\nProcessing: 0/{cl}\n\n**Powered by**\n🇩 🇮 🇬 🇬 🇮 🇩 🇮 🇬 🇮",
reply_markup=keyboard
)
- try:
- await pin_msg.pin()
- except Exception as e:
- await pin_msg.pin(both_sides=True)
- # Start processing links
+ await pin_msg.pin(both_sides=True)
+
users_loop[user_id] = True
try:
- # FIRST ITERATION: Process t.me/ links without userbot
+ normal_links_handled = False
+ userbot = await initialize_userbot(user_id)
+ # Handle normal links first
for i in range(cs, cs + cl):
if user_id in users_loop and users_loop[user_id]:
- try:
- # Construct the link
- x = start_id.split('/')
- y = x[:-1]
- result = '/'.join(y)
- url = f"{result}/{i}"
- link = get_link(url)
-
- # Directly process links like t.me/ (no userbot needed)
- if 't.me/' in link and 't.me/b/' not in link and 't.me/c' not in link or 'tg://openmessage' not in link:
- userbot = None
- data = await db.get_data(user_id)
- if data and data.get("session"):
- session = data.get("session")
- try:
- device = 'Vivo Y20'
- userbot = Client(
- ":userbot:",
- api_id=API_ID,
- api_hash=API_HASH,
- device_model=device,
- session_string=session
- )
- await userbot.start()
- except Exception as e:
- userbot = None
- else:
- userbot = None
- msg = await app.send_message(message.chat.id, f"Processing...")
- await process_and_upload_link(userbot, user_id, msg.id, link, 0, message)
- await pin_msg.edit_text(
- f"Batch process started ⚡\n__Processing: {i - cs + 1}/{cl}__\n\n**__Powered by Team SPY__**",
+ url = f"{'/'.join(start_id.split('/')[:-1])}/{i}"
+ link = get_link(url)
+ # Process t.me links (normal) without userbot
+ if 't.me/' in link and not any(x in link for x in ['t.me/b/', 't.me/c/', 'tg://openmessage']):
+ msg = await app.send_message(message.chat.id, f"Processing...")
+ await process_and_upload_link(userbot, user_id, msg.id, link, 0, message)
+ await pin_msg.edit_text(
+ f"Batch process started ⚡\nProcessing: {i - cs + 1}/{cl}\n\n**Powered by**\n🇩 🇮 🇬 🇬 🇮 🇩 🇮 🇬 🇮",
reply_markup=keyboard
- )
- except Exception as e:
- print(f"Error processing link {url}: {e}")
- continue
-
- if not any(prefix in start_id for prefix in ['t.me/c/', 't.me/b/']):
+ )
+ normal_links_handled = True
+ if normal_links_handled:
await set_interval(user_id, interval_minutes=300)
- await app.send_message(message.chat.id, "Batch completed successfully! 🎉")
await pin_msg.edit_text(
- f"Batch process completed for {cl} messages enjoy 🌝\n\n**__Powered by Team SPY__**",
- reply_markup=keyboard
- )
- return
-
- # SECOND ITERATION: Process t.me/+ or t.me/c/ links with userbot
- data = await db.get_data(user_id)
- if data and data.get("session"):
- session = data.get("session")
- device = 'Vivo Y20'
- userbot = Client(
- ":userbot:",
- api_id=API_ID,
- api_hash=API_HASH,
- device_model=device,
- session_string=session
+ f"Batch completed successfully for {cl} messages 🎉\n\n**Powered by**\n🇩 🇮 🇬 🇬 🇮 🇩 🇮 🇬 🇮",
+ reply_markup=keyboard
)
- await userbot.start()
- else:
- await app.send_message(message.chat.id, "Login in bot first ...")
+ await app.send_message(message.chat.id, "Batch completed successfully! 🎉")
return
-
- try:
- for i in range(cs, cs + cl):
- if user_id in users_loop and users_loop[user_id]:
- try:
- # Construct the link
- x = start_id.split('/')
- y = x[:-1]
- result = '/'.join(y)
- url = f"{result}/{i}"
- link = get_link(url)
- # Process links requiring userbot
- if 't.me/b/' in link or 't.me/c/' in link or 'tg://openmessage' in link:
- msg = await app.send_message(message.chat.id, f"Processing...")
- await process_and_upload_link(userbot, user_id, msg.id, link, 0, message)
- await pin_msg.edit_text(
- f"Batch process started ⚡\n__Processing: {i - cs + 1}/{cl}__\n\n**__Powered by Team SPY__**",
- reply_markup=keyboard
- )
- except Exception as e:
- print(f"Error processing link {url}: {e}")
- continue
- except Exception as e:
- print(f"{e}")
- pass
- await app.send_message(message.chat.id, "Batch completed successfully! 🎉")
+ # Handle special links with userbot
+ for i in range(cs, cs + cl):
+ if not userbot:
+ await app.send_message(message.chat.id, "Login in bot first ...")
+ users_loop[user_id] = False
+ return
+ if user_id in users_loop and users_loop[user_id]:
+ url = f"{'/'.join(start_id.split('/')[:-1])}/{i}"
+ link = get_link(url)
+ if any(x in link for x in ['t.me/b/', 't.me/c/']):
+ msg = await app.send_message(message.chat.id, f"Processing...")
+ await process_and_upload_link(userbot, user_id, msg.id, link, 0, message)
+ await pin_msg.edit_text(
+ f"Batch process started ⚡\nProcessing: {i - cs + 1}/{cl}\n\n**Powered by**\n🇩 🇮 🇬 🇬 🇮 🇩 🇮 🇬 🇮",
+ reply_markup=keyboard
+ )
+
await set_interval(user_id, interval_minutes=300)
await pin_msg.edit_text(
- f"Batch completed for {cl} messages ⚡\n\n**__Powered by Team SPY__**",
- reply_markup=keyboard
- )
- except FloodWait as fw:
- await app.send_message(
- message.chat.id,
- f"Try again after {fw.x} seconds due to floodwait from Telegram."
+ f"Batch completed successfully for {cl} messages 🎉\n\n**Powered by**\n🇩 🇮 🇬 🇬 🇮 🇩 🇮 🇬 🇮",
+ reply_markup=keyboard
)
+ await app.send_message(message.chat.id, "Batch completed successfully! 🎉")
+
except Exception as e:
- await app.send_message(message.chat.id, f"Error: {str(e)}")
+ await app.send_message(message.chat.id, f"Error: {e}")
finally:
users_loop.pop(user_id, None)
-
@app.on_message(filters.command("cancel"))
async def stop_batch(_, message):
@@ -399,4 +307,3 @@ async def stop_batch(_, message):
message.chat.id,
"No active batch processing is running to cancel."
)
-
diff --git a/devgagan/modules/plans.py b/devgagan/modules/plans.py
index 4affc63b4..3fd63c8ea 100644
--- a/devgagan/modules/plans.py
+++ b/devgagan/modules/plans.py
@@ -114,7 +114,7 @@ async def give_premium_cmd_handler(client, message):
data = await plans_db.check_premium(user_id)
expiry = data.get("expire_date")
expiry_str_in_ist = expiry.astimezone(pytz.timezone("Asia/Kolkata")).strftime("%d-%m-%Y\n⏱️ ᴇxᴘɪʀʏ ᴛɪᴍᴇ : %I:%M:%S %p")
- await message.reply_text(f"ᴘʀᴇᴍɪᴜᴍ ᴀᴅᴅᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ✅\n\n👤 ᴜꜱᴇʀ : {user.mention}\n⚡ ᴜꜱᴇʀ ɪᴅ : {user_id}\n⏰ ᴘʀᴇᴍɪᴜᴍ ᴀᴄᴄᴇꜱꜱ : {time}\n\n⏳ ᴊᴏɪɴɪɴɢ ᴅᴀᴛᴇ : {current_time}\n\n⌛️ ᴇxᴘɪʀʏ ᴅᴀᴛᴇ : {expiry_str_in_ist} \n\n__**Powered by Team SPY__**", disable_web_page_preview=True)
+ await message.reply_text(f"ᴘʀᴇᴍɪᴜᴍ ᴀᴅᴅᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ✅\n\n👤 ᴜꜱᴇʀ : {user.mention}\n⚡ ᴜꜱᴇʀ ɪᴅ : {user_id}\n⏰ ᴘʀᴇᴍɪᴜᴍ ᴀᴄᴄᴇꜱꜱ : {time}\n\n⏳ ᴊᴏɪɴɪɴɢ ᴅᴀᴛᴇ : {current_time}\n\n⌛️ ᴇxᴘɪʀʏ ᴅᴀᴛᴇ : {expiry_str_in_ist} \n\n**Powered by Team**\n**🇩 🇮 🇬 🇬 🇮 🇩 🇮 🇬 🇮**", disable_web_page_preview=True)
await client.send_message(
chat_id=user_id,
text=f"👋 ʜᴇʏ {user.mention},\nᴛʜᴀɴᴋ ʏᴏᴜ ꜰᴏʀ ᴘᴜʀᴄʜᴀꜱɪɴɢ ᴘʀᴇᴍɪᴜᴍ.\nᴇɴᴊᴏʏ !! ✨🎉\n\n⏰ ᴘʀᴇᴍɪᴜᴍ ᴀᴄᴄᴇꜱꜱ : {time}\n⏳ ᴊᴏɪɴɪɴɢ ᴅᴀᴛᴇ : {current_time}\n\n⌛️ ᴇxᴘɪʀʏ ᴅᴀᴛᴇ : {expiry_str_in_ist}", disable_web_page_preview=True
@@ -159,7 +159,8 @@ async def transfer_premium(client, message):
f"👤 **From:** {sender_user.mention}\n"
f"👤 **To:** {new_user.mention}\n"
f"⏳ **Expiry Date:** {expiry_str_in_ist}\n\n"
- f"__Powered by Team SPY__ 🚀"
+ f"Powered by Team"
+ f"🇩 🇮 🇬 🇬 🇮 🇩 🇮 🇬 🇮"
)
# Notification to the new user
@@ -167,7 +168,7 @@ async def transfer_premium(client, message):
chat_id=new_user_id,
text=(
f"👋 **Hey {new_user.mention},**\n\n"
- f"🎉 **Your Premium Plan has been Transferred!**\n"
+ f"🎉 **Premium Plan has been Transferred to you!**\n"
f"🛡️ **Transferred From:** {sender_user.mention}\n\n"
f"⏳ **Expiry Date:** {expiry_str_in_ist}\n"
f"📅 **Transferred On:** {current_time}\n\n"
diff --git a/devgagan/modules/shrink.py b/devgagan/modules/shrink.py
index c225f9ea8..4e5d45f83 100644
--- a/devgagan/modules/shrink.py
+++ b/devgagan/modules/shrink.py
@@ -69,13 +69,13 @@ async def token_handler(client, message):
join = await subscribe(client, message)
if join == 1:
return
- chat_id = "save_restricted_content_bots"
- msg = await app.get_messages(chat_id, 796)
+ chat_id = "Team_Diggi_Digi"
+ msg = await app.get_messages(chat_id, 47)
user_id = message.chat.id
if len(message.command) <= 1:
- image_url = "https://i.postimg.cc/v8q8kGyz/startimg-1.jpg"
- join_button = InlineKeyboardButton("Join Channel", url="https://t.me/team_spy_pro")
- premium = InlineKeyboardButton("Get Premium", url="https://t.me/kingofpatal")
+ image_url = "https://i.ibb.co/mzm0jdm/IMG-20241225-085508-126.jpg"
+ join_button = InlineKeyboardButton("Join Channel", url="https://t.me/Team_Diggi_Digi")
+ premium = InlineKeyboardButton("Get Premium", url="https://t.me/ViperROX")
keyboard = InlineKeyboardMarkup([
[join_button],
[premium]
@@ -85,7 +85,7 @@ async def token_handler(client, message):
msg.photo.file_id,
caption=(
"Hi 👋 Welcome, Wanna intro...?\n\n"
- "✳️ I can save posts from channels or groups where forwarding is off. I can download videos/audio from YT, INSTA, ... social platforms\n"
+ "✳️ I can save posts from any telegram channels or groups where forwarding is off. I can download videos/audio from YT, INSTA, ... social platforms\n"
"✳️ Simply send the post link of a public channel. For private channels, do /login. Send /help to know more."
),
reply_markup=keyboard
@@ -144,4 +144,4 @@ async def smart_handler(client, message):
[[InlineKeyboardButton("Verify the token now...", url=shortened_url)]]
)
await message.reply("Click the button below to verify your free access token: \n\n> What will you get ? \n1. No time bound upto 3 hours \n2. Batch command limit will be FreeLimit + 20 \n3. All functions unlocked", reply_markup=button)
-
\ No newline at end of file
+
diff --git a/devgagan/modules/speedtest.py b/devgagan/modules/speedtest.py
index 9cf258a02..3743c9e32 100644
--- a/devgagan/modules/speedtest.py
+++ b/devgagan/modules/speedtest.py
@@ -85,7 +85,8 @@ async def speedtest(event):
├ Country: {result['client']['country']}
├ ISP: {result['client']['isp']}
├ ISP Rating: {result['client']['isprating']}
-╰ Powered by Team SPY
+├ Powered by Team
+╰ 🇩 🇮 🇬 🇬 🇮 🇩 🇮 🇬 🇮
'''
try:
await event.reply(string_speed,file=path,parse_mode='html')
diff --git a/devgagan/modules/start.py b/devgagan/modules/start.py
index 122588aa7..c3d593e1d 100644
--- a/devgagan/modules/start.py
+++ b/devgagan/modules/start.py
@@ -110,7 +110,8 @@ async def set(_, message):
"> 4. REPLACEWORDS : Can be used for words in deleted set via REMOVE WORDS\n"
"> 5. RESET : To set the things back to default\n\n"
"> You can set CUSTOM THUMBNAIL, PDF WATERMARK, VIDEO WATERMARK, SESSION-based login, etc. from settings\n\n"
- "**__Powered by Team SPY__**"
+ "**Powered by Team**"
+ "**🇩 🇮 🇬 🇬 🇮 🇩 🇮 🇬 🇮**"
)
]
@@ -184,7 +185,7 @@ async def terms(client, message):
buttons = InlineKeyboardMarkup(
[
[InlineKeyboardButton("📋 See Plans", callback_data="see_plan")],
- [InlineKeyboardButton("💬 Contact Now", url="https://t.me/kingofpatal")],
+ [InlineKeyboardButton("💬 Contact Now", url="https://t.me/ViperROX")],
]
)
await message.reply_text(terms_text, reply_markup=buttons)
@@ -193,7 +194,7 @@ async def terms(client, message):
@app.on_message(filters.command("plan") & filters.private)
async def plan(client, message):
plan_text = (
- "> 💰 **Premium Price**:\n\n Starting from $2 or 200 INR accepted via **__Amazon Gift Card__** (terms and conditions apply).\n"
+ "> 💰 **Premium Price**:\n\n Starting from $2 or 200 INR or 260 BDT accepted via\nFor Indian:- UPI\nFor Bangladeshi:- Bkash\nFor International:- PayPal, Binance, USDT, TON.\n"
"📥 **Download Limit**: Users can download up to 100,000 files in a single batch command.\n"
"🛑 **Batch**: You will get two modes /bulk and /batch.\n"
" - Users are advised to wait for the process to automatically cancel before proceeding with any downloads or uploads.\n\n"
@@ -203,7 +204,7 @@ async def plan(client, message):
buttons = InlineKeyboardMarkup(
[
[InlineKeyboardButton("📜 See Terms", callback_data="see_terms")],
- [InlineKeyboardButton("💬 Contact Now", url="https://t.me/kingofpatal")],
+ [InlineKeyboardButton("💬 Contact Now", url="https://t.me/ViperROX")],
]
)
await message.reply_text(plan_text, reply_markup=buttons)
@@ -212,7 +213,7 @@ async def plan(client, message):
@app.on_callback_query(filters.regex("see_plan"))
async def see_plan(client, callback_query):
plan_text = (
- "> 💰**Premium Price**\n\n Starting from $2 or 200 INR accepted via **__Amazon Gift Card__** (terms and conditions apply).\n"
+ "> 💰 **Premium Price**:\n\n Starting from $2 or 200 INR or 260 BDT accepted via\nFor Indian:- UPI\nFor Bangladeshi:- Bkash\nFor International:- PayPal, Binance, USDT, TON.\n"
"📥 **Download Limit**: Users can download up to 100,000 files in a single batch command.\n"
"🛑 **Batch**: You will get two modes /bulk and /batch.\n"
" - Users are advised to wait for the process to automatically cancel before proceeding with any downloads or uploads.\n\n"
@@ -222,7 +223,7 @@ async def see_plan(client, callback_query):
buttons = InlineKeyboardMarkup(
[
[InlineKeyboardButton("📜 See Terms", callback_data="see_terms")],
- [InlineKeyboardButton("💬 Contact Now", url="https://t.me/kingofpatal")],
+ [InlineKeyboardButton("💬 Contact Now", url="https://t.me/ViperROX")],
]
)
await callback_query.message.edit_text(plan_text, reply_markup=buttons)
@@ -240,9 +241,9 @@ async def see_terms(client, callback_query):
buttons = InlineKeyboardMarkup(
[
[InlineKeyboardButton("📋 See Plans", callback_data="see_plan")],
- [InlineKeyboardButton("💬 Contact Now", url="https://t.me/kingofpatal")],
+ [InlineKeyboardButton("💬 Contact Now", url="https://t.me/ViperROX")],
]
)
await callback_query.message.edit_text(terms_text, reply_markup=buttons)
-
\ No newline at end of file
+