AI wrapper and twitter plugin (#465)
* Ultroid 2025 Co-authored-by: New-dev0 <New-dev0@users.noreply.github.com> Co-authored-by: Amit Sharma <buddhhu@users.noreply.github.com> Co-authored-by: TechiError <techierror@users.noreply.github.com> Co-authored-by: Aditya <me@xditya.me> Co-authored-by: Arnab Paryali <Arnabxd@users.noreply.github.com> Co-authored-by: hellboi_atul <hellboi-atul@users.noreply.github.com> Co-authored-by: sppidy <sppidy@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
396
plugins/aiwrapper.py
Normal file
396
plugins/aiwrapper.py
Normal file
@@ -0,0 +1,396 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
||||
|
||||
"""
|
||||
✘ Commands Available -
|
||||
|
||||
• `{i}gemini <prompt>`
|
||||
Get response from Google Gemini.
|
||||
|
||||
• `{i}antr <prompt>`
|
||||
Get response from Anthropic Claude.
|
||||
|
||||
• `{i}gpt <prompt>`
|
||||
Get response from OpenAI GPT.
|
||||
|
||||
• `{i}deepseek <prompt>`
|
||||
Get response from DeepSeek AI.
|
||||
|
||||
Set custom models using:
|
||||
• OPENAI_MODEL
|
||||
• ANTHROPIC_MODEL
|
||||
• GEMINI_MODEL
|
||||
• DEEPSEEK_MODEL
|
||||
"""
|
||||
|
||||
import json
|
||||
from . import LOGS, eor, get_string, udB, ultroid_cmd, async_searcher
|
||||
import aiohttp
|
||||
import asyncio
|
||||
|
||||
|
||||
ENDPOINTS = {
|
||||
"gpt": "https://api.openai.com/v1/chat/completions",
|
||||
"antr": "https://api.anthropic.com/v1/messages",
|
||||
"gemini": "https://generativelanguage.googleapis.com/v1/models/gemini-pro:generateContent",
|
||||
"deepseek": "https://api.deepseek.com/chat/completions"
|
||||
}
|
||||
|
||||
DEFAULT_MODELS = {
|
||||
"gpt": "gpt-3.5-turbo",
|
||||
"antr": "claude-3-opus-20240229",
|
||||
"gemini": "gemini-pro",
|
||||
"deepseek": "deepseek-chat"
|
||||
}
|
||||
|
||||
|
||||
def get_model(provider):
|
||||
"""Get model name from database or use default"""
|
||||
model_keys = {
|
||||
"gpt": "OPENAI_MODEL",
|
||||
"antr": "ANTHROPIC_MODEL",
|
||||
"gemini": "GEMINI_MODEL",
|
||||
"deepseek": "DEEPSEEK_MODEL"
|
||||
}
|
||||
return udB.get_key(model_keys[provider]) or DEFAULT_MODELS[provider]
|
||||
|
||||
|
||||
async def stream_response(msg, text):
|
||||
"""Stream response by editing message"""
|
||||
current = ""
|
||||
# Split into chunks of ~100 characters at word boundaries
|
||||
words = text.split()
|
||||
chunks = []
|
||||
current_chunk = []
|
||||
|
||||
for word in words:
|
||||
current_chunk.append(word)
|
||||
if len(" ".join(current_chunk)) > 100:
|
||||
chunks.append(" ".join(current_chunk[:-1]))
|
||||
current_chunk = [word]
|
||||
if current_chunk:
|
||||
chunks.append(" ".join(current_chunk))
|
||||
|
||||
for chunk in chunks:
|
||||
current += chunk + " "
|
||||
try:
|
||||
await msg.edit(current)
|
||||
except Exception:
|
||||
pass
|
||||
await asyncio.sleep(0.5)
|
||||
return current
|
||||
|
||||
|
||||
async def get_ai_response(provider, prompt, api_key, stream=False):
|
||||
"""Get response from AI provider"""
|
||||
try:
|
||||
headers = {"Content-Type": "application/json"}
|
||||
model = get_model(provider)
|
||||
|
||||
if provider == "gpt":
|
||||
headers["Authorization"] = f"Bearer {api_key}"
|
||||
data = {
|
||||
"model": model,
|
||||
"messages": [{"role": "user", "content": prompt}],
|
||||
"stream": stream
|
||||
}
|
||||
if not stream:
|
||||
response = await async_searcher(
|
||||
ENDPOINTS[provider],
|
||||
headers=headers,
|
||||
post=True,
|
||||
json=data,
|
||||
re_json=True
|
||||
)
|
||||
yield response["choices"][0]["message"]["content"]
|
||||
return
|
||||
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.post(
|
||||
ENDPOINTS[provider],
|
||||
headers=headers,
|
||||
json=data
|
||||
) as resp:
|
||||
async for line in resp.content:
|
||||
if line:
|
||||
try:
|
||||
json_line = json.loads(line.decode('utf-8').strip().strip('data:').strip())
|
||||
if 'choices' in json_line and json_line['choices']:
|
||||
content = json_line['choices'][0].get('delta', {}).get('content', '')
|
||||
if content:
|
||||
yield content
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
elif provider == "antr":
|
||||
headers["x-api-key"] = api_key
|
||||
headers["anthropic-version"] = "2023-06-01"
|
||||
data = {
|
||||
"model": model,
|
||||
"messages": [{"role": "user", "content": prompt}],
|
||||
"stream": stream
|
||||
}
|
||||
if not stream:
|
||||
response = await async_searcher(
|
||||
ENDPOINTS[provider],
|
||||
headers=headers,
|
||||
post=True,
|
||||
json=data,
|
||||
re_json=True
|
||||
)
|
||||
yield response["content"][0]["text"]
|
||||
return
|
||||
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.post(
|
||||
ENDPOINTS[provider],
|
||||
headers=headers,
|
||||
json=data
|
||||
) as resp:
|
||||
async for line in resp.content:
|
||||
if line:
|
||||
try:
|
||||
json_line = json.loads(line.decode('utf-8').strip())
|
||||
if 'content' in json_line:
|
||||
content = json_line['content'][0]['text']
|
||||
if content:
|
||||
yield content
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
elif provider == "gemini":
|
||||
params = {"key": api_key}
|
||||
data = {
|
||||
"contents": [{
|
||||
"parts": [{"text": prompt}]
|
||||
}]
|
||||
}
|
||||
response = await async_searcher(
|
||||
ENDPOINTS[provider],
|
||||
params=params,
|
||||
headers=headers,
|
||||
post=True,
|
||||
json=data,
|
||||
re_json=True
|
||||
)
|
||||
text = response["candidates"][0]["content"]["parts"][0]["text"]
|
||||
if not stream:
|
||||
yield text
|
||||
return
|
||||
|
||||
# Simulate streaming by yielding chunks
|
||||
words = text.split()
|
||||
buffer = []
|
||||
for word in words:
|
||||
buffer.append(word)
|
||||
if len(' '.join(buffer)) > 20: # Adjust chunk size as needed
|
||||
yield ' '.join(buffer) + ' '
|
||||
buffer = []
|
||||
if buffer:
|
||||
yield ' '.join(buffer)
|
||||
|
||||
elif provider == "deepseek":
|
||||
headers["Authorization"] = f"Bearer {api_key}"
|
||||
data = {
|
||||
"model": model,
|
||||
"messages": [{"role": "user", "content": prompt}],
|
||||
"stream": stream
|
||||
}
|
||||
if not stream:
|
||||
response = await async_searcher(
|
||||
ENDPOINTS[provider],
|
||||
headers=headers,
|
||||
post=True,
|
||||
json=data,
|
||||
re_json=True
|
||||
)
|
||||
yield response["choices"][0]["message"]["content"]
|
||||
return
|
||||
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.post(
|
||||
ENDPOINTS[provider],
|
||||
headers=headers,
|
||||
json=data
|
||||
) as resp:
|
||||
async for line in resp.content:
|
||||
if line:
|
||||
try:
|
||||
json_line = json.loads(line.decode('utf-8').strip())
|
||||
if 'choices' in json_line and json_line['choices']:
|
||||
content = json_line['choices'][0].get('delta', {}).get('content', '')
|
||||
if content:
|
||||
yield content
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
except Exception as e:
|
||||
LOGS.exception(e)
|
||||
yield f"Error: {str(e)}"
|
||||
|
||||
|
||||
@ultroid_cmd(pattern="gemini( (.*)|$)")
|
||||
async def gemini_ai(event):
|
||||
"""Use Google Gemini"""
|
||||
prompt = event.pattern_match.group(1).strip()
|
||||
if not prompt:
|
||||
return await event.eor("❌ Please provide a prompt!")
|
||||
|
||||
api_key = udB.get_key("GEMINI_API_KEY")
|
||||
if not api_key:
|
||||
return await event.eor("⚠️ Please set Gemini API key using `setdb GEMINI_API_KEY your_api_key`")
|
||||
|
||||
msg = await event.eor("🤔 Thinking...")
|
||||
model = get_model("gemini")
|
||||
|
||||
header = (
|
||||
"🤖 **Google Gemini**\n"
|
||||
f"**Model:** `{model}`\n"
|
||||
"➖➖➖➖➖➖➖➖➖➖\n\n"
|
||||
f"**🔍 Prompt:**\n{prompt}\n\n"
|
||||
"**💡 Response:**\n"
|
||||
)
|
||||
|
||||
if event.client.me.bot:
|
||||
await msg.edit(header)
|
||||
response = ""
|
||||
async for chunk in get_ai_response("gemini", prompt, api_key, stream=True):
|
||||
response += chunk
|
||||
try:
|
||||
await msg.edit(header + response)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
response = ""
|
||||
async for chunk in get_ai_response("gemini", prompt, api_key, stream=True):
|
||||
response += chunk
|
||||
try:
|
||||
await msg.edit(header + response)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@ultroid_cmd(pattern="antr( (.*)|$)")
|
||||
async def anthropic_ai(event):
|
||||
"""Use Anthropic Claude"""
|
||||
prompt = event.pattern_match.group(1).strip()
|
||||
if not prompt:
|
||||
return await event.eor("❌ Please provide a prompt!")
|
||||
|
||||
api_key = udB.get_key("ANTHROPIC_KEY")
|
||||
if not api_key:
|
||||
return await event.eor("⚠️ Please set Anthropic API key using `setdb ANTHROPIC_KEY your_api_key`")
|
||||
|
||||
msg = await event.eor("🤔 Thinking...")
|
||||
model = get_model("antr")
|
||||
|
||||
formatted_response = (
|
||||
"🧠 **Anthropic Claude**\n"
|
||||
f"**Model:** `{model}`\n"
|
||||
"➖➖➖➖➖➖➖➖➖➖\n\n"
|
||||
f"**🔍 Prompt:**\n{prompt}\n\n"
|
||||
f"**💡 Response:**\n"
|
||||
)
|
||||
|
||||
if event.client.me.bot:
|
||||
await msg.edit(formatted_response)
|
||||
response = ""
|
||||
async for chunk in get_ai_response("antr", prompt, api_key, stream=True):
|
||||
response += chunk
|
||||
try:
|
||||
await msg.edit(formatted_response + response)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
response = ""
|
||||
async for chunk in get_ai_response("antr", prompt, api_key, stream=True):
|
||||
response += chunk
|
||||
try:
|
||||
await msg.edit(formatted_response + response)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@ultroid_cmd(pattern="gpt( (.*)|$)")
|
||||
async def openai_ai(event):
|
||||
"""Use OpenAI GPT"""
|
||||
prompt = event.pattern_match.group(1).strip()
|
||||
if not prompt:
|
||||
return await event.eor("❌ Please provide a prompt!")
|
||||
|
||||
api_key = udB.get_key("OPENAI_API_KEY")
|
||||
if not api_key:
|
||||
return await event.eor("⚠️ Please set GPT API key using `setdb OPENAI_API_KEY your_api_key`")
|
||||
|
||||
msg = await event.eor("🤔 Thinking...")
|
||||
model = get_model("gpt")
|
||||
|
||||
header = (
|
||||
"🌟 **OpenAI GPT**\n"
|
||||
f"**Model:** `{model}`\n"
|
||||
"➖➖➖➖➖➖➖➖➖➖\n\n"
|
||||
f"**🔍 Prompt:**\n{prompt}\n\n"
|
||||
"**💡 Response:**\n"
|
||||
)
|
||||
|
||||
if event.client.me.bot:
|
||||
await msg.edit(header)
|
||||
response = ""
|
||||
async for chunk in get_ai_response("gpt", prompt, api_key, stream=True):
|
||||
response += chunk
|
||||
try:
|
||||
await msg.edit(header + response)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
response =""
|
||||
async for chunk in get_ai_response("gpt", prompt, api_key, stream=True):
|
||||
response += chunk
|
||||
try:
|
||||
await msg.edit(header + response)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@ultroid_cmd(pattern="deepseek( (.*)|$)")
|
||||
async def deepseek_ai(event):
|
||||
"""Use DeepSeek AI"""
|
||||
prompt = event.pattern_match.group(1).strip()
|
||||
if not prompt:
|
||||
return await event.eor("❌ Please provide a prompt!")
|
||||
|
||||
api_key = udB.get_key("DEEPSEEK_API_KEY")
|
||||
if not api_key:
|
||||
return await event.eor("⚠️ Please set DeepSeek API key using `setdb DEEPSEEK_API_KEY your_api_key`")
|
||||
|
||||
msg = await event.eor("🤔 Thinking...")
|
||||
model = get_model("deepseek")
|
||||
|
||||
formatted_response = (
|
||||
"🤖 **DeepSeek AI**\n"
|
||||
f"**Model:** `{model}`\n"
|
||||
"➖➖➖➖➖➖➖➖➖➖\n\n"
|
||||
f"**🔍 Prompt:**\n{prompt}\n\n"
|
||||
f"**💡 Response:**\n"
|
||||
)
|
||||
|
||||
if event.client.me.bot:
|
||||
await msg.edit(formatted_response)
|
||||
response = ""
|
||||
async for chunk in get_ai_response("deepseek", prompt, api_key, stream=True):
|
||||
response += chunk
|
||||
try:
|
||||
await msg.edit(formatted_response + response)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
response = ""
|
||||
async for chunk in get_ai_response("deepseek", prompt, api_key, stream=True):
|
||||
response += chunk
|
||||
|
||||
try:
|
||||
await msg.edit(formatted_response + response)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid ~ UserBot
|
||||
# Copyright (C) 2024 TeamUltroid
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
@@ -32,9 +32,6 @@
|
||||
|
||||
• `{i}webshot <url>`
|
||||
Get a screenshot of the webpage.
|
||||
|
||||
• `{i}shorturl <url> <id-optional>`
|
||||
shorten any url...
|
||||
"""
|
||||
import glob
|
||||
import io
|
||||
@@ -464,26 +461,3 @@ async def webss(event):
|
||||
os.remove(pic)
|
||||
await xx.delete()
|
||||
|
||||
|
||||
@ultroid_cmd(pattern="shorturl")
|
||||
async def magic(event):
|
||||
try:
|
||||
match = event.text.split(maxsplit=1)[1].strip()
|
||||
except IndexError:
|
||||
return await event.eor("`Provide url to turn into tiny...`")
|
||||
data = {
|
||||
"url": match.split()[0],
|
||||
"id": match[1] if len(match) > 1 else secrets.token_urlsafe(6),
|
||||
}
|
||||
data = await async_searcher(
|
||||
"https://tiny.ultroid.tech/api/new",
|
||||
data=data,
|
||||
post=True,
|
||||
re_json=True,
|
||||
)
|
||||
response = data.get("response", {})
|
||||
if not response.get("status"):
|
||||
return await event.eor(f'**ERROR :** `{response["message"]}`')
|
||||
await event.eor(
|
||||
f"• **Ultroid Tiny**\n• Given Url : {url}\n• Shorten Url : {data['response']['tinyUrl']}"
|
||||
)
|
||||
|
||||
203
plugins/twitter.py
Normal file
203
plugins/twitter.py
Normal file
@@ -0,0 +1,203 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
||||
|
||||
"""
|
||||
✘ Commands Available -
|
||||
|
||||
• `{i}tw <tweet text>`
|
||||
Tweet the text.
|
||||
|
||||
• `{i}twr <tweet id/link>`
|
||||
Get tweet details with reply/quote/comment count.
|
||||
|
||||
• `{i}twuser <username>`
|
||||
Get user details of the Twitter account.
|
||||
|
||||
• `{i}twl <tweet link>`
|
||||
Upload the tweet media to telegram.
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
from twikit import Client
|
||||
from . import LOGS, eor, get_string, udB, ultroid_cmd
|
||||
|
||||
# Store client globally
|
||||
twitter_client = None
|
||||
|
||||
# Get path to cookies file
|
||||
COOKIES_FILE = "resources/auth/twitter_cookies.json"
|
||||
|
||||
async def get_client():
|
||||
global twitter_client
|
||||
if twitter_client:
|
||||
return twitter_client
|
||||
|
||||
if not all(udB.get_key(key) for key in ["TWITTER_USERNAME", "TWITTER_EMAIL", "TWITTER_PASSWORD"]):
|
||||
raise Exception("Set TWITTER_USERNAME, TWITTER_EMAIL and TWITTER_PASSWORD in vars first!")
|
||||
|
||||
# Create auth directory if it doesn't exist
|
||||
os.makedirs(os.path.dirname(COOKIES_FILE), exist_ok=True)
|
||||
|
||||
client = Client()
|
||||
await client.login(
|
||||
auth_info_1=udB.get_key("TWITTER_USERNAME"),
|
||||
auth_info_2=udB.get_key("TWITTER_EMAIL"),
|
||||
password=udB.get_key("TWITTER_PASSWORD"),
|
||||
cookies_file=COOKIES_FILE
|
||||
)
|
||||
twitter_client = client
|
||||
return client
|
||||
|
||||
|
||||
|
||||
@ultroid_cmd(pattern="tw( (.*)|$)")
|
||||
async def tweet_cmd(event):
|
||||
"""Post a tweet"""
|
||||
text = event.pattern_match.group(1).strip()
|
||||
if not text:
|
||||
return await event.eor("🚫 `Give some text to tweet!`")
|
||||
|
||||
msg = await event.eor("🕊 `Tweeting...`")
|
||||
try:
|
||||
client = await get_client()
|
||||
tweet = await client.create_tweet(text=text)
|
||||
await msg.edit(f"✨ **Successfully Posted!**\n\n🔗 https://x.com/{tweet.user.screen_name}/status/{tweet.id}")
|
||||
except Exception as e:
|
||||
await msg.edit(f"❌ **Error:**\n`{str(e)}`")
|
||||
|
||||
|
||||
@ultroid_cmd(pattern="twdetail( (.*)|$)")
|
||||
async def twitter_details(event):
|
||||
"""Get tweet details"""
|
||||
match = event.pattern_match.group(1).strip()
|
||||
if not match:
|
||||
return await event.eor("🚫 `Give tweet ID/link to get details!`")
|
||||
|
||||
msg = await event.eor("🔍 `Getting tweet details...`")
|
||||
try:
|
||||
client = await get_client()
|
||||
if "twitter.com" in match or "x.com" in match:
|
||||
tweet_id = match.split("/")[-1].split("?")[0]
|
||||
else:
|
||||
tweet_id = match
|
||||
|
||||
tweet = await client.get_tweet_by_id(tweet_id)
|
||||
text = "🐦 **Tweet Details**\n\n"
|
||||
text += f"📝 **Content:** `{tweet.text}`\n\n"
|
||||
if hasattr(tweet, "metrics"):
|
||||
text += f"❤️ **Likes:** `{tweet.metrics.likes}`\n"
|
||||
text += f"🔄 **Retweets:** `{tweet.metrics.retweets}`\n"
|
||||
text += f"💬 **Replies:** `{tweet.metrics.replies}`\n"
|
||||
text += f"👁 **Views:** `{tweet.metrics.views}`\n"
|
||||
|
||||
await msg.edit(text)
|
||||
except Exception as e:
|
||||
await msg.edit(f"❌ **Error:**\n`{str(e)}`")
|
||||
|
||||
|
||||
@ultroid_cmd(pattern="twuser( (.*)|$)")
|
||||
async def twitter_user(event):
|
||||
"""Get user details"""
|
||||
match = event.pattern_match.group(1).strip()
|
||||
if not match:
|
||||
return await event.eor("🚫 `Give username to get details!`")
|
||||
|
||||
msg = await event.eor("🔍 `Getting user details...`")
|
||||
try:
|
||||
client = await get_client()
|
||||
user = await client.get_user_by_screen_name(match)
|
||||
text = "👤 **Twitter User Details**\n\n"
|
||||
text += f"📛 **Name:** `{user.name}`\n"
|
||||
text += f"🔖 **Username:** `@{user.screen_name}`\n"
|
||||
text += f"📝 **Bio:** `{user.description}`\n\n"
|
||||
text += f"👥 **Followers:** `{user.followers_count}`\n"
|
||||
text += f"👣 **Following:** `{user.following_count}`\n"
|
||||
text += f"🐦 **Total Tweets:** `{user.statuses_count}`\n"
|
||||
text += f"📍 **Location:** `{user.location or 'Not Set'}`\n"
|
||||
text += f"✅ **Verified:** `{user.verified}`\n"
|
||||
|
||||
if user.profile_image_url:
|
||||
image_url = user.profile_image_url.replace("_normal.", ".")
|
||||
await event.client.send_file(
|
||||
event.chat_id,
|
||||
file=image_url,
|
||||
caption=text,
|
||||
force_document=False
|
||||
)
|
||||
await msg.delete()
|
||||
else:
|
||||
await msg.edit(text)
|
||||
|
||||
except Exception as e:
|
||||
await msg.edit(f"❌ **Error:**\n`{str(e)}`")
|
||||
|
||||
|
||||
@ultroid_cmd(pattern="twl( (.*)|$)")
|
||||
async def twitter_media(event):
|
||||
"""Download tweet media"""
|
||||
match = event.pattern_match.group(1).strip()
|
||||
if not match:
|
||||
return await event.eor("🚫 `Give tweet link to download media!`")
|
||||
|
||||
msg = await event.eor("📥 `Downloading media...`")
|
||||
try:
|
||||
client = await get_client()
|
||||
if "twitter.com" in match or "x.com" in match:
|
||||
tweet_id = match.split("/")[-1].split("?")[0]
|
||||
else:
|
||||
tweet_id = match
|
||||
|
||||
tweet = await client.get_tweet_by_id(tweet_id)
|
||||
|
||||
if not hasattr(tweet, "media"):
|
||||
return await msg.edit("😕 `No media found in tweet!`")
|
||||
|
||||
# Prepare caption with tweet text
|
||||
caption = f"🐦 **Tweet by @{tweet.user.screen_name}**\n\n"
|
||||
caption += f"{tweet.text}\n\n"
|
||||
if hasattr(tweet, "metrics"):
|
||||
caption += f"❤️ `{tweet.metrics.likes}` 🔄 `{tweet.metrics.retweets}` 💬 `{tweet.metrics.replies}`"
|
||||
|
||||
media_count = 0
|
||||
for media in tweet.media:
|
||||
if media.type == "photo":
|
||||
await event.client.send_file(
|
||||
event.chat_id,
|
||||
media.url,
|
||||
caption=caption if media_count == 0 else None # Only add caption to first media
|
||||
)
|
||||
media_count += 1
|
||||
elif media.type == "video":
|
||||
if hasattr(media, "video_info") and isinstance(media.video_info, dict):
|
||||
variants = media.video_info.get("variants", [])
|
||||
mp4_variants = [
|
||||
v for v in variants
|
||||
if v.get("content_type") == "video/mp4" and "bitrate" in v
|
||||
]
|
||||
if mp4_variants:
|
||||
best_video = max(mp4_variants, key=lambda x: x["bitrate"])
|
||||
video_caption = caption if media_count == 0 else "" # Only add tweet text to first media
|
||||
if video_caption:
|
||||
video_caption += f"\n🎥 Video Quality: {best_video['bitrate']/1000:.0f}kbps"
|
||||
else:
|
||||
video_caption = f"🎥 Video Quality: {best_video['bitrate']/1000:.0f}kbps"
|
||||
|
||||
await event.client.send_file(
|
||||
event.chat_id,
|
||||
best_video["url"],
|
||||
caption=video_caption
|
||||
)
|
||||
media_count += 1
|
||||
|
||||
if media_count > 0:
|
||||
await msg.edit(f"✅ Successfully downloaded {media_count} media items!")
|
||||
await msg.delete()
|
||||
else:
|
||||
await msg.edit("😕 `No media could be downloaded!`")
|
||||
except Exception as e:
|
||||
await msg.edit(f"❌ **Error:**\n`{str(e)}`")
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
import os
|
||||
|
||||
from . import eor, get_string, udB, ultroid_cmd
|
||||
from . import eor, get_string, udB, ultroid_cmd, HNDLR
|
||||
|
||||
|
||||
@ultroid_cmd(pattern="get($| (.*))", fullsudo=True)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ultroid - UserBot
|
||||
# Copyright (C) 2021-2023 TeamUltroid
|
||||
# Copyright (C) 2021-2025 TeamUltroid
|
||||
#
|
||||
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
||||
# PLease read the GNU Affero General Public License in
|
||||
|
||||
Reference in New Issue
Block a user