|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
""" |
|
β 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 |
|
|
|
|
|
twitter_client = None |
|
|
|
|
|
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!") |
|
|
|
|
|
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() |
|
from urllib.parse import urlparse |
|
parsed_url = urlparse(match) |
|
if parsed_url.hostname in ["twitter.com", "x.com"]: |
|
tweet_id = parsed_url.path.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!`") |
|
|
|
|
|
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 |
|
) |
|
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 "" |
|
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)}`") |
|
|