Skip to content

Commit

Permalink
support instagram
Browse files Browse the repository at this point in the history
  • Loading branch information
BennyThink committed Apr 16, 2023
1 parent 07cbf8f commit b101ff2
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 47 deletions.
45 changes: 27 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,42 @@

YouTube Download Bot🚀

This Telegram bot allows you to download videos from YouTube and other supported platforms.
This Telegram bot allows you to download videos from YouTube and other supported platforms, including Instagram!

-----
**READ [FAQ](FAQ.md) FIRST IF YOU ENCOUNTER ANY ISSUES.**

-----
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)
<details> <summary>Deploy to heroku</summary>

<a href="https://heroku.com/deploy"><img src="https://www.herokucdn.com/deploy/button.svg" alt="Deploy to Heroku"></a>

If you are having trouble deploying, you can fork the project to your personal account and deploy it from there.

**Starting November 28, 2022, free Heroku Dynos, free Heroku Postgres, and free Heroku Data for Redis® plans will no
longer be available.**
[Heroku Announcement](https://devcenter.heroku.com/articles/free-dyno-hours)
</details>

# Usage

[https://t.me/benny_ytdlbot](https://t.me/benny_ytdlbot)

Send link directly to the bot. Any
Websites [supported by youtube-dl](https://ytdl-org.github.io/youtube-dl/supportedsites.html) will also work.
Websites [supported by youtube-dl](https://ytdl-org.github.io/youtube-dl/supportedsites.html) will work to.

# Limitations of my bot

Due to limitations on servers and bandwidth, there are some restrictions on this service.
Due to limitations on servers and bandwidth, there are some restrictions on this free service.

* Each user is limited to 5 free downloads per 24-hour period
* there is a maximum of three subscriptions allowed for YouTube channels.

If you require more downloads, you can purchase additional tokens. Additionally, you have the option of deploying your
own bot.
If you need more downloads, you can purchase additional tokens. Additionally, you have the option of deploying your
own bot. See below instructions.

# Features

![](assets/1.jpeg)

1. fast download and upload.
2. ads free
3. support progress bar
Expand All @@ -50,13 +51,28 @@ own bot.
9. supports celery worker distribution - faster than before.
10. subscriptions to YouTube Channels
11. cache mechanism - download once for the same video.
12. support instagram posts

# Screenshots

## Normal download

![](assets/1.jpeg)

## Instagram download

![](assets/instagram.png)

## celery

![](assets/2.jpeg)

# How to deploy?

This bot can be deployed on any platform that supports Python.

Need help with deployment or exclusive features? I offer paid service - contact me at @BennyThink

## Run natively on your machine

To deploy this bot, follow these steps:
Expand Down Expand Up @@ -162,16 +178,7 @@ Type "help", "copyright", "credits" or "license" for more information.

### 3.2.3 Setup instagram cookies

Required if you want to support instagram.

You can use this extension
[Get cookies.txt](https://chrome.google.com/webstore/detail/get-cookiestxt/bgaddhkoddajcdgocldbbfleckgcbcid)
to get instagram cookies

```shell
vim data/instagram.com_cookies.txt
# paste your cookies
```
You don't need to do this anymore! This bot support instagram posts out of the box, including photos, videos and reels.

## 3.3 Tidy docker-compose.yml

Expand Down Expand Up @@ -265,6 +272,8 @@ https://dmesg.app/m3u8/prog_index.m3u8
https://twitter.com/nitori_sayaka/status/1526199729864200192
https://twitter.com/BennyThinks/status/1475836588542341124

## test instagram

# Donation

* [Buy me a coffee](https://www.buymeacoffee.com/bennythink)
Expand Down
Binary file added assets/instagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions ytdlbot/constant.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class BotText:
3. You have the option to buy more tokens. Type /buy for more information.
4. The source code for this bot will always remain open and can be found here: https://github.com/tgbot-collection/ytdlbot
5. Need help with deployment or exclusive features? I offer paid service - contact me at @BennyThink
"""

about = "YouTube Downloader by @BennyThink.\n\nOpen source on GitHub: https://github.com/tgbot-collection/ytdlbot"
Expand Down
26 changes: 22 additions & 4 deletions ytdlbot/downloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import ffmpeg
import ffpb
import filetype
import requests
import yt_dlp as ytdl
from tqdm import tqdm

Expand Down Expand Up @@ -153,7 +154,7 @@ def can_convert_mp4(video_path, uid):
return True


def ytdl_download(url, tempdir, bm, **kwargs) -> dict:
def ytdl_download(url, tempdir: "str", bm, **kwargs) -> dict:
payment = Payment()
chat_id = bm.chat.id
hijack = kwargs.get("hijack")
Expand All @@ -180,7 +181,8 @@ def ytdl_download(url, tempdir, bm, **kwargs) -> dict:
None,
]
adjust_formats(chat_id, url, formats, hijack)
add_instagram_cookies(url, ydl_opts)
if download_instagram(url, tempdir):
return {"status": True, "error": "", "filepath": list(pathlib.Path(tempdir).glob("*"))}

address = ["::", "0.0.0.0"] if IPv6 else [None]
for format_ in formats:
Expand Down Expand Up @@ -252,9 +254,20 @@ def convert_audio_format(resp: "dict", bm):
resp["filepath"][index] = new_path


def add_instagram_cookies(url: "str", opt: "dict"):
def download_instagram(url: "str", tempdir: "str"):
if url.startswith("https://www.instagram.com"):
opt["cookiefile"] = pathlib.Path(__file__).parent.joinpath("instagram.com_cookies.txt").as_posix()
api = f"https://ssmstore.store/rami/index.php?url={url}"
res = requests.get(api).json()
if isinstance(res, dict):
downloadable = {i["url"]: i["ext"] for i in res["url"]}
else:
downloadable = {i["url"]: i["ext"] for item in res for i in item["url"]}

for link, ext in downloadable.items():
save_path = pathlib.Path(tempdir, f"{id(link)}.{ext}")
with open(save_path, "wb") as f:
f.write(requests.get(link, stream=True).content)
return True


def split_large_video(response: "dict"):
Expand All @@ -270,3 +283,8 @@ def split_large_video(response: "dict"):

if split and original_video:
response["filepath"] = [i.as_posix() for i in pathlib.Path(original_video).parent.glob("*")]


if __name__ == "__main__":
a = download_instagram("https://www.instagram.com/p/CrEAz-AI99Y/", "tmp")
print(a)
83 changes: 58 additions & 25 deletions ytdlbot/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from hashlib import md5
from urllib.parse import quote_plus

import filetype
import psutil
import pyrogram.errors
import requests
Expand All @@ -42,7 +43,6 @@
ENABLE_VIP,
OWNER,
RATE_LIMIT,
TG_MAX_SIZE,
WORKERS,
)
from constant import BotText
Expand Down Expand Up @@ -127,7 +127,7 @@ def forward_video(client, bot_msg, url):

try:
res_msg: "Message" = upload_processor(client, bot_msg, url, cached_fid)
obj = res_msg.document or res_msg.video or res_msg.audio or res_msg.animation
obj = res_msg.document or res_msg.video or res_msg.audio or res_msg.animation or res_msg.photo

caption, _ = gen_cap(bot_msg, url, obj)
res_msg.edit_text(caption, reply_markup=gen_video_markup())
Expand Down Expand Up @@ -265,27 +265,19 @@ def ytdl_normal_download(bot_msg, client, url):
logging.info("Download complete.")
if result["status"]:
client.send_chat_action(chat_id, "upload_document")
video_paths = result["filepath"]
video_paths: "list" = result["filepath"]
bot_msg.edit_text("Download complete. Sending now...")
for video_path in video_paths:
# normally there's only one video in that path...
st_size = os.stat(video_path).st_size
if st_size > TG_MAX_SIZE:
bot_msg.edit_text(f"Your video({sizeof_fmt(st_size)}) is too large for Telegram.")
# client.send_chat_action(chat_id, 'upload_document')
# client.send_message(chat_id, upload_transfer_sh(bot_msg, video_paths))
continue
try:
upload_processor(client, bot_msg, url, video_path)
except pyrogram.errors.Flood as e:
logging.critical("FloodWait from Telegram: %s", e)
client.send_message(
chat_id,
f"I'm being rate limited by Telegram. Your video will come after {e.x} seconds. Please wait patiently.",
)
flood_owner_message(client, e)
time.sleep(e.x)
upload_processor(client, bot_msg, url, video_path)
try:
upload_processor(client, bot_msg, url, video_paths)
except pyrogram.errors.Flood as e:
logging.critical("FloodWait from Telegram: %s", e)
client.send_message(
chat_id,
f"I'm being rate limited by Telegram. Your video will come after {e.x} seconds. Please wait patiently.",
)
flood_owner_message(client, e)
time.sleep(e.x)
upload_processor(client, bot_msg, url, video_paths)

bot_msg.edit_text("Download success!✅")
else:
Expand All @@ -296,12 +288,43 @@ def ytdl_normal_download(bot_msg, client, url):
temp_dir.cleanup()


def upload_processor(client, bot_msg, url, vp_or_fid: "typing.Any[str, pathlib.Path]"):
def generate_input_media(file_paths: "list", cap: "str") -> list:
input_media = []
for path in file_paths:
mime = filetype.guess_mime(path)
if "video" in mime:
input_media.append(pyrogram.types.InputMediaVideo(media=path))
elif "image" in mime:
input_media.append(pyrogram.types.InputMediaPhoto(media=path))
elif "audio" in mime:
input_media.append(pyrogram.types.InputMediaAudio(media=path))
else:
input_media.append(pyrogram.types.InputMediaDocument(media=path))

input_media[0].caption = cap
return input_media


def upload_processor(client, bot_msg, url, vp_or_fid: "typing.Any[str, list]"):
# raise pyrogram.errors.exceptions.FloodWait(13)
# if is str, it's a file id; else it's a list of paths
payment = Payment()
chat_id = bot_msg.chat.id
markup = gen_video_markup()
cap, meta = gen_cap(bot_msg, url, vp_or_fid)
if isinstance(vp_or_fid, list) and len(vp_or_fid) > 1:
# just generate the first for simplicity, send as media group(2-20)
cap, meta = gen_cap(bot_msg, url, vp_or_fid[0])
res_msg = client.send_media_group(chat_id, generate_input_media(vp_or_fid, cap))
# TODO no cache for now
return res_msg[0]
elif isinstance(vp_or_fid, list) and len(vp_or_fid) == 1:
# normal download, just contains one file in video_paths
vp_or_fid = vp_or_fid[0]
cap, meta = gen_cap(bot_msg, url, vp_or_fid)
else:
# just a file id as string
cap, meta = gen_cap(bot_msg, url, vp_or_fid)

settings = payment.get_user_settings(str(chat_id))
if ARCHIVE_ID and isinstance(vp_or_fid, pathlib.Path):
chat_id = ARCHIVE_ID
Expand Down Expand Up @@ -364,9 +387,19 @@ def upload_processor(client, bot_msg, url, vp_or_fid: "typing.Any[str, pathlib.P
reply_markup=markup,
**meta,
)
except FileNotFoundError:
# this is likely a photo
logging.info("Retry to send as photo")
res_msg = client.send_photo(
chat_id,
vp_or_fid,
caption=cap,
progress=upload_hook,
progress_args=(bot_msg,),
)

unique = get_unique_clink(url, bot_msg.chat.id)
obj = res_msg.document or res_msg.video or res_msg.audio or res_msg.animation
obj = res_msg.document or res_msg.video or res_msg.audio or res_msg.animation or res_msg.photo
redis.add_send_cache(unique, getattr(obj, "file_id", None))
redis.update_metrics("video_success")
if ARCHIVE_ID and isinstance(vp_or_fid, pathlib.Path):
Expand Down

0 comments on commit b101ff2

Please sign in to comment.