← 返回 TimeAmber
logo NodeSeekbeta

【开源】别让小鸡吃灰 - TG机器人,下载Youtube、X等网站视频转存到115\阿里云盘等网盘

不知道为啥Github账号404了 直接上传到网盘了 有需要自取
https://gofile.io/d/KAKat9

最近X总是封号,一封号点赞的小视频就找不到了,正好618买了115网盘的8年会员,于是想用telegram的机器人把Youtube、X、tiktok视频下载到VPS上并转存到网盘里,翻了一圈没有能满足我需求的,于是花了点时间手撸了一个,实现很简单,理论上yt-dlp支持的网站这个脚本都支持
求鸡腿 xhj006

预览图:
215e7637e15b5c83d945ee103621bf52.png

项目地址:https://github.com/Srainc/TBot-DSSC
项目说明:

TBot-DSSC

简介:
通过给Telegram机器发送URL,让服务器下载对应的视频并同步到网盘中
该脚本通过Telegram机器人接收、创建、反馈任务,通过yt-dlp下载视频,通过CloudDrive2添加网盘,通过Rclone对本地数据与网盘进行数据同步

环境需求:
Python >= 3.9
Rclone
CloudDrive2
ffmpeg

环境部署:
Python组件安装

pip install python-telegram-bot tqdm yt-dlp

ffmprg安装

apt install ffmpeg

Rclone安装

curl https://rclone.org/install.sh | sudo bash

CloudDrive2安装

curl -fsSL "https://raw.githubusercontent.com/lonelylose/clouddrive2/main/cd2.sh" | bash -s install

使用说明:
1、使用CloudDrive2添加对应网盘
2、使用Rclone添加CloudDrive2对应的WebDav服务
3、申请Telegram机器人
4、修改Python脚本中的API_TOKEN、DOWNLOAD_DIR、ALLOWED_USER_ID、MOUNT_PATH、RCLONE_NAME字段为对应的值
5、启动脚本

其他信息:
1、API_TOKEN字段需要通过官方机器人https://t.me/BotFather申请API后获得
2、ALLOWED_USER_ID字段可以通过https://t.me/userinfobot获得
3、可以使用nohup命令或者screen工具进行Python脚本的持久化运行
4、在debian11下正常运行,其它系统请自测
5、CloudDrive2、Rclone的使用方法请自行互联网搜索

免责声明:
1、使用该脚本则默认同意该声明
2、该脚本为个人测试用途,数据无价,请谨慎使用,使用该脚本导致的一切后果开发者不承担责任

1.. 678910
  • 保存为 xxx.py

    import os
    import shlex
    import subprocess
    import logging
    from tqdm import tqdm
    from telegram import Update
    from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, CallbackContext
    from telegram.ext.filters import TEXT
    from urllib.parse import urlparse
    from datetime import datetime
    
    # 替换为你的 Telegram 机器人 API Token 
    API_TOKEN = '1234567890:beTK1P4NtjnVnLs-gtLHgCQJXyoI0gWgRWg'
    # 下载目录
    DOWNLOAD_DIR = '/Down'
    # 允许使用的用户 ID 
    ALLOWED_USER_ID = 1234567890  # 替换为你想允许的用户 ID 
    # 网盘挂载路径
    MOUNT_PATH = '/115/Server'
    # Rclone 配置的项目名称 rclone config 可以查看
    RCLONE_NAME = '115'
    
    # 确保下载目录存在
    os.makedirs(DOWNLOAD_DIR, exist_ok=True)
    
    # 配置日志记录
    LOGGING_ENABLED = os.getenv('LOGGING_ENABLED', 'true').lower() == 'true'
    if LOGGING_ENABLED:
        logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    else:
        logging.basicConfig(level=logging.CRITICAL)  # 只记录严重错误
    
    logger = logging.getLogger(__name__)
    
    # /start 命令的处理函数
    async def start(update: Update, context: CallbackContext):
        if update.message.from_user.id != ALLOWED_USER_ID:
            await update.message.reply_text('您无权使用此机器人。')
            return
        await update.message.reply_text('你好!向我发送视频 URL,我将为您下载该视频。')
    
    # 处理收到的 URL
    async def handle_message(update: Update, context: CallbackContext):
        if update.message.from_user.id != ALLOWED_USER_ID:
            await update.message.reply_text('您无权使用此机器人。')
            return
    
        url = update.message.text
        chat_id = update.message.chat_id
    
        # 解析 URL 中的域名
        domain = urlparse(url).netloc
        domain_dir = os.path.join(DOWNLOAD_DIR, domain)
    
        # 确保域名对应的目录存在
        os.makedirs(domain_dir, exist_ok=True)
        current_date = datetime.now().strftime('%Y-%m-%d')
    
        download_command = f'yt-dlp -o {shlex.quote(domain_dir + "/%(title).30s_" + current_date + ".%(ext)s")} {shlex.quote(url)}'
    
        # 发送下载开始消息
        await update.message.reply_text(f'开始下载:{url}')
    
        try:
            # 运行 yt-dlp 命令并捕获输出
            process = subprocess.Popen(shlex.split(download_command), stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, encoding='utf-8')
    
            progress_message = await update.message.reply_text('下载进度:0%')
            last_progress = 0
    
            while True:
                output = process.stdout.readline()
                if output == '' and process.poll() is not None:
                    break
                if output:
                    logger.info(output.strip())
                    # 解析进度信息
                    if '[download]' in output and '%' in output:
                        progress = output.split('%')[0].split()[-1].strip()
                        try:
                            progress = float(progress)
                            if progress >= last_progress + 10:
                                last_progress = progress
                                await progress_message.edit_text(f'下载进度:{progress}%')
                        except ValueError:
                            pass
    
            # 捕获下载过程中的错误信息
            stderr_output = process.stderr.read()
            if process.returncode == 0:
                await update.message.reply_text('下载完成!')
                logger.info(f'Download complete for {url}')
                 # 同步文件到115:/115/Server
                sync_command = f'rclone move {shlex.quote(DOWNLOAD_DIR)} {RCLONE_NAME}:{shlex.quote(MOUNT_PATH)}'
                sync_process = subprocess.run(shlex.split(sync_command), capture_output=True, text=True)
                
                if sync_process.returncode == 0:
                    await update.message.reply_text('文件同步完成!')
                    logger.info('File sync complete')
                else:
                    await update.message.reply_text(f'文件同步错误:{sync_process.stderr.strip()}')
                    logger.error(f'File sync error: {sync_process.stderr.strip()}')
    
            else:
                await update.message.reply_text(f'Error: {stderr_output.strip()}')
                logger.error(f'Error: {stderr_output.strip()}')
        except Exception as e:
            await update.message.reply_text(f'Error: {str(e)}')
            logger.error(f'Exception occurred: {str(e)}')
    
    def main():
        application = ApplicationBuilder().token(API_TOKEN).build()
        application.add_handler(CommandHandler("start", start))
        application.add_handler(MessageHandler(TEXT, handle_message))  # 更正后的过滤器
    
        # 运行机器人
        application.run_polling()
    
    if __name__ == '__main__':
        main()
    
  • 支持

    无欲无求,清心寡欲!收想收的小鸡鸡,玩好玩的小鸡鸡!

  • 点个star xhj003

  • bd

  • 不错👍

  • 绑定

  • bd

  • 前排支持 xhj003

  • bd

  • 支持

  • 给大佬点赞👍

  • 帮顶

  • 鸡脚给你

    正在播放《安和桥》 ━━━━━━●─────── 2:40
    ⇆ ㅤㅤㅤ◁ ㅤㅤ❚❚ ㅤㅤ▷ ㅤㅤㅤ↻ ​​​

  • 好贴帮顶

  • 这个支持下载不允许转发不允许下载的视频么?

  • 不错不错

  • bd

  • 支持

  • star

  • MARK

  • 强!

  • 你说得对但是我选择打包成docker放容器云,小鸡继续吃灰

    论坛私聊 | 探针 | EDU与8连后缀Tron地址出售:地摊

  • Nice pussy

  • 好办法支持

  • 大佬点赞

  • 建议docker一键

    ✉️站内PM | ✈️有白嫖通知一下 | ☠️陪跑大王☠️ | ☃️TG翻译机器人 | ❤️日志随记 | ❤️DMIT好用的VPS

  • @byte #14 不支持哦 大伙要是需求比较强烈可以研究一下 不过TG下载自己服务器上的内容好像有大小限制

  • 点赞

  • 策略上如果网盘支持rclone,就没必要用cd2

    图床|✅博客+1|⛄️针+1|⚡频道+1|⭐️Patreon订阅|⛵Github|✴️NNR提速

  • 支持xhj003

  • @BlueSkyXN #29 rclone原生不支持国内的一些网盘 另外用改版的rclone或者alist速度也会有问题

  • 帮顶

  • 帮顶 感谢分享

  • 能下载tg的视频吗

  • 正在播放《体面》 ━━━━━━●─────── 00:24 / 04:23
    ⇆ ㅤㅤㅤ◁ ㅤㅤ❚❚ ㅤㅤ▷ ㅤㅤㅤ↻ ​​​

  • 绑定

  • xhj006

  • 很好 xhj003

  • TG私信我 ▎2024新年快乐

  • 点赞

  • xhj003

  • xhj002 这个看起来不错,插个眼,以后能用上

  • 支持大佬

  • 这不是一般的强,是超强!

  • 大佬牛逼

  • 已经点亮了

  • 🚫
  • @byte #48 这项目之前研究过 下载存储在TG上的视频 需要高级API 申请不能说麻烦 但也不简单 另外有下载大小限制 除非另外开个项目把这两个分开

  • 好东西鸡腿送上

  • 提个建议大佬,支持转发tg视频,支持转存到onedrive

  • @brains #0 教程能不能再详细点,老实说我用不来

    TG私信我 ▎2024新年快乐

  • @brains #50 API 申请我到没注意,我拿一个新的号来登录的,似乎也没有很麻烦?

    另外说的下载大小限制是什么呢?我看我用这个下载的最大的 TG 视频是 3.8GB

  • 能保存pikpak吗

  • bd

  • bd

  • 有点意思

  • ? 项目好像没了


    ...好像是连号都没了

  • @neek #60 不知道为啥会显示404。。。

  • @brains #0 cd2可以基于alist吗,如果能融合下115bot这个项目就完美了'只需要一个机器人了

    ✈️TG | ❤️ 以针会友 | ☺️ll.sd—流量商店

  • 这不得点个star

  • 佬,网盘失踪了

  • 老哥,这个机器人能不能支持下 下载阿里的视频转存到115呀

  • 谢谢分享,收藏先

  • @bacon159 #69 直接用CloudDrive2或者alist将阿里云盘的资源秒传到115

  • @brains #71 就是因为无法秒传 才需要vps手动搬的,,,能秒传就不需要这个机器人了

  • @bacon159 #72 不应该啊 确定CloudDrive2无法秒传么

  • @brains #73 对 有些国漫资源秒传都是需要有人搬运的 可能过了一天都没人搬运这样 只能自己搬运

  • @bacon159 #74 那阿里云盘没开第三方应用权益包的话 挂载CloudDrive2想下到本地也会限速吧 只能开了vip下载到本地再上传到115?

  • @brains #75 限速400k每秒这样 下载了再上传到115如果在vps是没有感知的 肯定比等别人一天后才搬运要快哈哈

  • @bacon159 #76 那用chatgpt写个搬运脚本啊 两个网盘都挂载到CloudDrive2上 然后从阿里云盘直接用脚本复制到115

  • 牛批

  • 好东西

  • 感谢分享,等一个docker

  • 这玩意不错,谢谢楼主了 xhj003

  • 马克

    ✈️TG | ✉️站内PM
    目前站内成功交易次数:11次 持续更新中 | 好听

  • BD

  • 谢谢分享

  • 可以直接把tg视频转发给他,让他下载吗

    TG:@galili1

  • bd

  • 好东西

    Tg @nu11ppbot

  • 强!

    真诚永远是最好的必杀技
    联系我在TG~

  • 支持

  • 链接好像失效了

  • 保存为 xxx.py

    import os
    import shlex
    import subprocess
    import logging
    from tqdm import tqdm
    from telegram import Update
    from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, CallbackContext
    from telegram.ext.filters import TEXT
    from urllib.parse import urlparse
    from datetime import datetime
    
    # 替换为你的 Telegram 机器人 API Token 
    API_TOKEN = '1234567890:beTK1P4NtjnVnLs-gtLHgCQJXyoI0gWgRWg'
    # 下载目录
    DOWNLOAD_DIR = '/Down'
    # 允许使用的用户 ID 
    ALLOWED_USER_ID = 1234567890  # 替换为你想允许的用户 ID 
    # 网盘挂载路径
    MOUNT_PATH = '/115/Server'
    # Rclone 配置的项目名称 rclone config 可以查看
    RCLONE_NAME = '115'
    
    # 确保下载目录存在
    os.makedirs(DOWNLOAD_DIR, exist_ok=True)
    
    # 配置日志记录
    LOGGING_ENABLED = os.getenv('LOGGING_ENABLED', 'true').lower() == 'true'
    if LOGGING_ENABLED:
        logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    else:
        logging.basicConfig(level=logging.CRITICAL)  # 只记录严重错误
    
    logger = logging.getLogger(__name__)
    
    # /start 命令的处理函数
    async def start(update: Update, context: CallbackContext):
        if update.message.from_user.id != ALLOWED_USER_ID:
            await update.message.reply_text('您无权使用此机器人。')
            return
        await update.message.reply_text('你好!向我发送视频 URL,我将为您下载该视频。')
    
    # 处理收到的 URL
    async def handle_message(update: Update, context: CallbackContext):
        if update.message.from_user.id != ALLOWED_USER_ID:
            await update.message.reply_text('您无权使用此机器人。')
            return
    
        url = update.message.text
        chat_id = update.message.chat_id
    
        # 解析 URL 中的域名
        domain = urlparse(url).netloc
        domain_dir = os.path.join(DOWNLOAD_DIR, domain)
    
        # 确保域名对应的目录存在
        os.makedirs(domain_dir, exist_ok=True)
        current_date = datetime.now().strftime('%Y-%m-%d')
    
        download_command = f'yt-dlp -o {shlex.quote(domain_dir + "/%(title).30s_" + current_date + ".%(ext)s")} {shlex.quote(url)}'
    
        # 发送下载开始消息
        await update.message.reply_text(f'开始下载:{url}')
    
        try:
            # 运行 yt-dlp 命令并捕获输出
            process = subprocess.Popen(shlex.split(download_command), stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, encoding='utf-8')
    
            progress_message = await update.message.reply_text('下载进度:0%')
            last_progress = 0
    
            while True:
                output = process.stdout.readline()
                if output == '' and process.poll() is not None:
                    break
                if output:
                    logger.info(output.strip())
                    # 解析进度信息
                    if '[download]' in output and '%' in output:
                        progress = output.split('%')[0].split()[-1].strip()
                        try:
                            progress = float(progress)
                            if progress >= last_progress + 10:
                                last_progress = progress
                                await progress_message.edit_text(f'下载进度:{progress}%')
                        except ValueError:
                            pass
    
            # 捕获下载过程中的错误信息
            stderr_output = process.stderr.read()
            if process.returncode == 0:
                await update.message.reply_text('下载完成!')
                logger.info(f'Download complete for {url}')
                 # 同步文件到115:/115/Server
                sync_command = f'rclone move {shlex.quote(DOWNLOAD_DIR)} {RCLONE_NAME}:{shlex.quote(MOUNT_PATH)}'
                sync_process = subprocess.run(shlex.split(sync_command), capture_output=True, text=True)
                
                if sync_process.returncode == 0:
                    await update.message.reply_text('文件同步完成!')
                    logger.info('File sync complete')
                else:
                    await update.message.reply_text(f'文件同步错误:{sync_process.stderr.strip()}')
                    logger.error(f'File sync error: {sync_process.stderr.strip()}')
    
            else:
                await update.message.reply_text(f'Error: {stderr_output.strip()}')
                logger.error(f'Error: {stderr_output.strip()}')
        except Exception as e:
            await update.message.reply_text(f'Error: {str(e)}')
            logger.error(f'Exception occurred: {str(e)}')
    
    def main():
        application = ApplicationBuilder().token(API_TOKEN).build()
        application.add_handler(CommandHandler("start", start))
        application.add_handler(MessageHandler(TEXT, handle_message))  # 更正后的过滤器
    
        # 运行机器人
        application.run_polling()
    
    if __name__ == '__main__':
        main()
    
  • @poliste #90 直接把代码发到帖子里了 看置顶

  • bd

1.. 678910
内容
预览
对照
AC娘
洋葱头
小黄鸡