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:
Devesh Pal
2025-02-21 23:05:48 +05:30
committed by GitHub
parent dace7972f3
commit 0afa1ade15
153 changed files with 754 additions and 178 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
View 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)}`")

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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