Skip to content

Conversation

@karilaa-dev
Copy link
Owner

@karilaa-dev karilaa-dev commented Jan 17, 2026

PR Type

Enhancement


Description

  • Add handlers for unsupported content types in private chats

  • Improve error messaging for invalid links and uploads

  • Update locale strings with more user-friendly messages

  • Fix reaction emoji on errors in group chats


Diagram Walkthrough

flowchart LR
  A[User sends message] --> B{Content type?}
  B -->|Video| C[Reply: video_upload_hint]
  B -->|Photo| D[Reply: tiktok_links_only]
  B -->|Voice/Audio| D
  B -->|Text| E{Valid TikTok link?}
  E -->|No URL| F[Reply: send_link_prompt]
  E -->|Non-TikTok URL| G[Reply: non_tiktok_link]
  E -->|Valid| H[Process video]
  B -->|Other| D
Loading

File Walkthrough

Relevant files
Enhancement
1 files
get_video.py
Add handlers for unsupported content types                             
+72/-5   
Documentation
8 files
ar.json
Update Arabic error messages                                                         
+9/-5     
en.json
Update English error messages                                                       
+9/-5     
hi.json
Update Hindi error messages                                                           
+9/-5     
id.json
Update Indonesian error messages                                                 
+9/-5     
ru.json
Update Russian error messages                                                       
+9/-5     
so.json
Update Somali error messages                                                         
+9/-5     
uk.json
Update Ukrainian error messages                                                   
+9/-5     
vi.json
Update Vietnamese error messages                                                 
+9/-5     

Simplify configuration by removing most performance-related env vars
and hardcoding values optimized for maximum resource usage:

- ThreadPoolExecutor: 500 workers (vs default 32)
- aiohttp connections: unlimited (limit=0)
- curl_cffi pool: 10000 max_clients
- Image downloads: no concurrency limit (removed semaphore)

Keep only 3 user-configurable limits via env vars:
- MAX_USER_QUEUE_SIZE (default 0 = no limit)
- STREAMING_DURATION_THRESHOLD (default 300s)
- MAX_VIDEO_DURATION (default 0 = no limit)
…adata

TikTok's browser impersonation (impersonate=True) doesn't work through HTTP
proxies, causing extraction to fail with "Unable to extract webpage video data".

Changed approach:
- Use direct connection (no proxy) for video info extraction with impersonate
- Use proxy for media downloads to hide server IP

This fixes the issue where all proxy attempts would fail due to TikTok's
JavaScript challenge blocking non-browser requests through proxies.
Create the new YoutubeDL instance before closing the old one to ensure
we have a valid ydl even if initialization fails.
Return extraction error if video_data is None despite a non-error status
code, preventing downstream issues from invalid data.
Remove logic that stripped proxy from ydl_opts during extraction.
Datacenter IPs are typically blocked by TikTok, so extraction must
use the configured proxy to work on servers.
TikTok's WAF blocks newer Chrome versions (136+) when used with proxies
due to TLS fingerprint / User-Agent mismatches. This commit:

- Use fixed Chrome 120 impersonation target instead of auto-selecting newest
- Set matching User-Agent header for yt-dlp extraction and media downloads
- Add per-proxy session pool to avoid proxy contamination between requests
- Bake proxy into curl_cffi sessions at construction time
Extend message handling to respond with helpful guidance when users
send images, voice messages, audio files, or other unsupported content
in private chats. Group chats remain silent for these content types.

- Add F.photo handler for image uploads
- Add F.voice | F.audio handler for voice/audio messages
- Add catch-all handler for any other unsupported content
- Add tiktok_links_only locale key in all 8 languages
@zam-review
Copy link

zam-review bot commented Jan 17, 2026

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Code Duplication

The handlers handle_video_upload, handle_image_upload, and handle_voice_upload contain nearly identical code for checking chat type, retrieving user settings, and getting the language. This logic should be extracted into a helper function to reduce duplication and improve maintainability.

@video_router.message(F.video | F.video_note)
async def handle_video_upload(message: Message):
    """Inform users that we need links, not video uploads (private chats only)."""
    if message.chat.type != "private":
        return

    settings = await get_user_settings(message.chat.id)
    if settings:
        lang = settings[0]
    else:
        lang = await lang_func(message.chat.id, message.from_user.language_code, True)

    await message.reply(locale[lang]["video_upload_hint"])


@video_router.message(F.photo)
async def handle_image_upload(message: Message):
    """Inform users that we only support TikTok links, not images (private chats only)."""
    if message.chat.type != "private":
        return

    settings = await get_user_settings(message.chat.id)
    if settings:
        lang = settings[0]
    else:
        lang = await lang_func(message.chat.id, message.from_user.language_code, True)

    await message.reply(locale[lang]["tiktok_links_only"])


@video_router.message(F.voice | F.audio)
async def handle_voice_upload(message: Message):
    """Inform users that we only support TikTok links, not voice messages (private chats only)."""
    if message.chat.type != "private":
        return

    settings = await get_user_settings(message.chat.id)
    if settings:
        lang = settings[0]
    else:
        lang = await lang_func(message.chat.id, message.from_user.language_code, True)

    await message.reply(locale[lang]["tiktok_links_only"])
Catch-All Handler Risk

The handle_unsupported_content handler is registered with @video_router.message() without any filters. This catch-all handler may interfere with other message handlers or commands in the router. Consider adding more specific filters or ensuring this handler is registered at the appropriate priority level.

@video_router.message()
async def handle_unsupported_content(message: Message):
    """Catch-all for any unsupported content types (private chats only)."""
    if message.chat.type != "private":
        return

    settings = await get_user_settings(message.chat.id)
    if settings:
        lang = settings[0]
    else:
        lang = await lang_func(message.chat.id, message.from_user.language_code, True)

    await message.reply(locale[lang]["tiktok_links_only"])
Missing Error Handling

The new handlers (handle_video_upload, handle_image_upload, handle_voice_upload, and handle_unsupported_content) lack try-except blocks around database calls (get_user_settings) and message replies. If these operations fail, users won't receive any feedback. Consider adding error handling to provide a better user experience.

@video_router.message(F.video | F.video_note)
async def handle_video_upload(message: Message):
    """Inform users that we need links, not video uploads (private chats only)."""
    if message.chat.type != "private":
        return

    settings = await get_user_settings(message.chat.id)
    if settings:
        lang = settings[0]
    else:
        lang = await lang_func(message.chat.id, message.from_user.language_code, True)

    await message.reply(locale[lang]["video_upload_hint"])


@video_router.message(F.photo)
async def handle_image_upload(message: Message):
    """Inform users that we only support TikTok links, not images (private chats only)."""
    if message.chat.type != "private":
        return

    settings = await get_user_settings(message.chat.id)
    if settings:
        lang = settings[0]
    else:
        lang = await lang_func(message.chat.id, message.from_user.language_code, True)

    await message.reply(locale[lang]["tiktok_links_only"])


@video_router.message(F.voice | F.audio)
async def handle_voice_upload(message: Message):
    """Inform users that we only support TikTok links, not voice messages (private chats only)."""
    if message.chat.type != "private":
        return

    settings = await get_user_settings(message.chat.id)
    if settings:
        lang = settings[0]
    else:
        lang = await lang_func(message.chat.id, message.from_user.language_code, True)

    await message.reply(locale[lang]["tiktok_links_only"])

@karilaa-dev karilaa-dev merged commit 68c5124 into main Jan 17, 2026
1 check passed
@karilaa-dev karilaa-dev deleted the dev branch January 17, 2026 23:46
@zam-review
Copy link

zam-review bot commented Jan 17, 2026

Failed to generate code suggestions for PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants