Skip to content

Add Instagram Downloader Plugin#496

Closed
paman7647 wants to merge 1 commit intoTeamUltroid:mainfrom
paman7647:patch-1
Closed

Add Instagram Downloader Plugin#496
paman7647 wants to merge 1 commit intoTeamUltroid:mainfrom
paman7647:patch-1

Conversation

@paman7647
Copy link

This plugin allows users to download media from Instagram, including reels, videos, photos, and carousels. It provides a command handler for the 'ig' command to initiate downloads.

This plugin allows users to download media from Instagram, including reels, videos, photos, and carousels. It provides a command handler for the 'ig' command to initiate downloads.
Copilot AI review requested due to automatic review settings March 1, 2026 16:49
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an Instagram media downloader command to the Ultroid plugins set, enabling users to fetch and upload reels/videos/photos/carousels directly into chats.

Changes:

  • Introduces a new .ig <instagram link> command handler.
  • Uses yt-dlp to extract/download Instagram media and uploads results via fast_uploader.
  • Adds a custom progress hook to report download progress in-chat.
Comments suppressed due to low confidence (1)

plugins/utils.py:113

  • Avoid bare except: here; it will also swallow KeyboardInterrupt/SystemExit and makes debugging operational issues harder. Catch Exception and consider logging the failure (at least at debug/error level) so rename/upload issues are diagnosable.
        try:
            os.rename(media_path, final_name)
        except:
            final_name = media_path

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +145 to +146
if "instagram.com" not in url:
return await event.eor("**❌ Invalid Instagram link.**")
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Instagram URL validation if "instagram.com" not in url is vulnerable to false positives (e.g., https://instagram.com.evil.tld/...) and can reject/accept malformed inputs unpredictably. Prefer urllib.parse.urlparse(url) and validate hostname (e.g., instagram.com / www.instagram.com) similar to how plugins/twitter.py validates domains.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +3
# Ultroid - UserBot
# Instagram Downloader Plugin
# This file is part of < https://github.com/TeamUltroid/Ultroid/ >
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file implements the Instagram downloader, but it’s named plugins/utils.py. The startup exclude list already references an instagram plugin (see pyUltroid/__main__.py), so keeping this in utils.py makes it harder to manage/disable consistently and is confusing for maintenance. Consider renaming/moving this plugin to plugins/instagram.py (or update the exclusion mechanism accordingly).

Copilot uses AI. Check for mistakes.
Comment on lines +71 to +74
"nocheckcertificate": True,
"outtmpl": "%(id)s.%(ext)s",
"progress_hooks": [lambda d: asyncio.create_task(ig_progress(d, time.time(), msg))],
}
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

progress_hooks uses asyncio.create_task(...) but this file never imports asyncio, so it will raise NameError the first time the hook runs. Add the missing import (and keep it consistent with other plugins).

Copilot uses AI. Check for mistakes.
Comment on lines +72 to +74
"outtmpl": "%(id)s.%(ext)s",
"progress_hooks": [lambda d: asyncio.create_task(ig_progress(d, time.time(), msg))],
}
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_download_ig runs inside run_async (thread pool). yt-dlp progress hooks are therefore executed in a worker thread, where asyncio.create_task() will fail with "no running event loop". Use a thread-safe bridge (e.g., asyncio.run_coroutine_threadsafe(..., event.client.loop) / capture the main loop) instead of create_task inside the hook.

Copilot uses AI. Check for mistakes.
Comment on lines +72 to +74
"outtmpl": "%(id)s.%(ext)s",
"progress_hooks": [lambda d: asyncio.create_task(ig_progress(d, time.time(), msg))],
}
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The progress hook currently passes time.time() as start_time on every callback, which resets the timer and makes the 10-second throttling ineffective (it may try to edit on almost every hook call). Capture a single start_time once before starting the download and reuse it for all hook invocations.

Copilot uses AI. Check for mistakes.
Comment on lines +90 to +113
title = media.get("title") or "Instagram_Media"

# sanitizing title
if len(title) > 30:
title = title[:27] + "..."

# find file downloaded by yt-dlp
media_path = None
for f in glob.glob(f"{media_id}*"):
if not f.endswith(".jpg"):
media_path = f
break

if not media_path:
continue

# rename file
ext = "." + media_path.split(".")[-1]
final_name = f"{title}{ext}"

try:
os.rename(media_path, final_name)
except:
final_name = media_path
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

title is taken from remote metadata and is only truncated, not sanitized for filesystem safety. Characters like /, \, : or newlines can make os.rename fail or produce unintended paths. Use the project's filename sanitizer (e.g., check_filename) or explicitly strip/replace path separators and control characters before building final_name.

Copilot uses AI. Check for mistakes.
@paman7647 paman7647 closed this Mar 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants