### Content/Zh/Getting Started/Installation --- title: "安装" weight: 10 --- # 安装 ## 一键脚本 {{< tabs "scripts" >}} {{< tab "Windows" >}} `tdl` 将被安装到 `$Env:SystemDrive\tdl`(将被添加到 `PATH` 中),该脚本还可用于升级 `tdl`。 #### 安装最新版本 {{< command >}} iwr -useb https://docs.iyear.me/tdl/install.ps1 | iex {{< /command >}} #### 通过 `ghproxy.com` 镜像安装 {{< command >}} $Script=iwr -useb https://docs.iyear.me/tdl/install.ps1; $Block=[ScriptBlock]::Create($Script); Invoke-Command -ScriptBlock $Block -ArgumentList "", "$True" {{< /command >}} #### 安装特定版本 {{< command >}} $Env:TDLVersion = "VERSION" $Script=iwr -useb https://docs.iyear.me/tdl/install.ps1; $Block=[ScriptBlock]::Create($Script); Invoke-Command -ScriptBlock $Block -ArgumentList "$Env:TDLVersion" {{< /command >}} {{< /tab >}} {{< tab "macOS 和 Linux" >}} `tdl` 将被安装到 `/usr/local/bin/tdl`,该脚本还可用于升级 `tdl`。 #### 安装最新版本 {{< command >}} curl -sSL https://docs.iyear.me/tdl/install.sh | sudo bash {{< /command >}} #### 通过 `ghproxy.com` 镜像安装 {{< command >}} curl -sSL https://docs.iyear.me/tdl/install.sh | sudo bash -s -- --proxy {{< /command >}} #### 安装特定版本 {{< command >}} curl -sSL https://docs.iyear.me/tdl/install.sh | sudo bash -s -- --version VERSION {{< /command >}} {{< /tab >}} {{< /tabs >}} ## 包管理器 {{< tabs "package managers" >}} {{}} {{< command >}} brew install telegram-downloader {{< /command >}} {{< /tab >}} {{}} {{< command >}} scoop bucket add extras scoop install telegram-downloader {{< /command >}} {{< /tab >}} {{}} {{< command >}} pkg install tdl {{< /command >}} {{< /tab >}} {{}} {{< command >}} yay -S tdl {{< /command >}} {{< /tab >}} {{}} #### nix-env {{< command >}} nix-env -iA nixos.tdl {{< /command >}} #### NixOS-Configuration ``` environment.systemPackages = [ pkgs.tdl ]; ``` #### nix-shell {{< command >}} nix-shell -p tdl {{< /command >}} {{< /tab >}} {{< /tabs >}} [](https://repology.org/project/telegram-downloader/versions) ## Docker 可用镜像: - [`iyear/tdl`](https://hub.docker.com/r/iyear/tdl) - [`ghcr.io/iyear/tdl`](https://ghcr.io/iyear/tdl) 可用标签: - `latest`(默认):最新的稳定版本 - `X.Y.Z`:`tdl`的特定版本 {{< tabs "docker" >}} {{< tab "Docker" >}} 以一次性命令运行 `tdl`: {{< command >}} docker run --rm -it iyear/tdl {{< /command >}} 进一步,挂载配置目录以保持持久化: {{< command >}} docker run --rm -it \ -v $HOME/.tdl:/root/.tdl \ iyear/tdl {{< /command >}} 为了方便获取下载的文件,可以挂载下载目录和其他需要的目录: {{< command >}} docker run --rm -it \ -v $HOME/.tdl:/root/.tdl \ -v $HOME/Downloads:/downloads \ iyear/tdl {{< /command >}} 在容器内运行 `tdl`: {{< command >}} docker run --rm -it --entrypoint sh iyear/tdl {{< /command >}} {{< details title="预览输出" open=false >}} ```1 / # tdl version Version: 0.17.7 Commit: ace2402 Date: 2024-11-01T14:40:56+08:00 go1.21.13 linux/amd64 / # ``` {{< /details >}} 如果希望使用 `localhost` 地址的代理,使用 `host` 网络运行: {{< command >}} docker run --rm -it --network host iyear/tdl {{< /command >}} {{< /tab >}} {{< tab "Docker Compose" >}} 使用 Docker Compose 运行 `tdl`,避免每次输入 `docker run` 选项。 {{< details title="docker-compose.yml" open=false >}} {{< hint info >}} 示例配置使用 Docker Compose v2 语法。 {{< /hint >}} ```yaml services: tdl: image: iyear/tdl # 或指定特定版本的 X.Y.Z 版本标签 volumes: - $HOME/.tdl:/root/.tdl # 保持配置持久化 - $HOME/Downloads:/downloads # 可选 # - /path/to/your/need:/path/in/container stdin_open: true tty: true # 如果需要使用 localhost 地址的代理,使用 host 网络 network_mode: host ``` {{< /details >}} 使用 Docker Compose 运行 `tdl`: {{< command >}} docker compose run --rm tdl {{< /command >}} 在容器内运行 `tdl`: {{< command >}} docker compose run --rm --entrypoint sh tdl {{< /command >}} {{< details title="预览输出" open=false >}} ```1 / # tdl version Version: 0.17.7 Commit: ace2402 Date: 2024-11-01T14:40:56+08:00 go1.21.13 linux/amd64 / # ``` {{< /details >}} {{< /tab >}} {{< /tabs >}} ## 预编译二进制 1. 下载指定操作系统和架构的压缩包: {{< tabs "prebuilt" >}} {{< tab "Windows" >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Windows_64bit.zip" >}}x86_64/amd64{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Windows_32bit.zip" >}}x86{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Windows_arm64.zip" >}}arm64{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Windows_armv5.zip" >}}armv5{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Windows_armv6.zip" >}}armv6{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Windows_armv7.zip" >}}armv7{{< /button >}} {{< /tab >}} {{< tab "macOS" >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_MacOS_64bit.tar.gz" >}}Intel{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_MacOS_arm64.tar.gz" >}}M1/M2{{< /button >}} {{< /tab >}} {{< tab "Linux" >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Linux_64bit.tar.gz" >}}x86_64/amd64{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Linux_32bit.tar.gz" >}}x86{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Linux_arm64.tar.gz" >}}arm64{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Linux_armv5.tar.gz" >}}armv5{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Linux_armv6.tar.gz" >}}armv6{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Linux_armv7.tar.gz" >}}armv7{{< /button >}} {{< /tab >}} {{< /tabs >}} 2. 解压缩压缩包 3. 将可执行文件移动到所需目录 4. 将此目录添加到 PATH 环境变量 5. 确保您对文件具有执行权限 ## 源代码 要从源代码构建 `tdl` 的扩展版本,您必须: 1. 安装 [Git](https://git-scm.com/) 2. 安装 Go 的 1.25 版本或更高版本 3. 根据 Go 文档中的描述更新您的 `PATH` 环境变量 {{< hint info >}} 安装目录由 `GOPATH` 和 `GOBIN` 环境变量控制。如果设置了 `GOBIN`,则二进制文件将安装到该目录。如果设置了 `GOPATH`,则二进制文件将安装到 `GOPATH` 列表中第一个目录的 `bin` 子目录。否则,二进制文件将安装到默认的 `GOPATH` 的 `bin` 子目录(`$HOME/go` 或 `%USERPROFILE%\go`)。 {{< /hint >}} 然后构建: {{< command >}} go install github.com/iyear/tdl@latest tdl version {{< /command >}} --- ### Content/Zh/Getting Started/Quick Start --- title: "快速开始" weight: 20 --- # 快速开始 ## 登录 我们不在这里指定命名空间,它将使用 `default` 命名空间。如果你想使用其他命名空间,可以使用 `-n` 标志指定命名空间。 ### **使用桌面客户端登录** {{< hint warning >}} 请确保从[官方网站](https://desktop.telegram.org/)下载客户端(不要从 Microsoft Store 或 App Store 下载) {{< /hint >}} 使用默认路径: {{< command >}} tdl login {{< /command >}} 如果您设置了本地密码: {{< command >}} tdl login -p YOUR_PASSCODE {{< /command >}} 或者指定自定义客户端路径: {{< command >}} tdl login -d /path/to/TelegramDesktop {{< /command >}} ### **使用二维码登录** {{< command >}} tdl login -T qr {{< /command >}} ### **使用手机号码和验证码登录** {{< command >}} tdl login -T code {{< /command >}} ## 下载 我们从 Telegram 官方频道下载文件: {{< command >}} tdl dl -u https://t.me/telegram/193 {{< /command >}} --- ### Content/Zh/Getting Started/Shell Completion --- title: "自动补全" weight: 30 --- # 自动补全 运行对应的命令以在所有会话中启用 Shell 自动补全: {{< tabs "shell" >}} {{< tab "bash" >}} {{< command >}} echo "source <(tdl completion bash)" >> ~/.bashrc {{< /command >}} {{< /tab >}} {{< tab "zsh" >}} {{< command >}} echo "source <(tdl completion zsh)" >> ~/.zshrc {{< /command >}} {{< /tab >}} {{< tab "fish" >}} {{< command >}} echo "tdl completion fish | source" >> ~/.config/fish/config.fish {{< /command >}} {{< /tab >}} {{< tab "PowerShell" >}} {{< command >}} Add-Content -Path $PROFILE -Value "tdl completion powershell | Out-String | Invoke-Expression" {{< /command >}} {{< /tab >}} {{< /tabs >}} --- ### Content/Zh/Guide/Tools/Export Members --- title: "导出成员" weight: 20 --- # 导出成员 导出聊天成员/订阅者、管理员、机器人等。 {{< hint info >}} 部分类型用户(被禁用户/被踢出用户/……)导出需要聊天管理员权限。 {{< /hint >}} {{< include "snippets/chat.md" >}} ## 默认 将所有用户导出为 `tdl-users.json` {{< command >}} tdl chat users -c CHAT {{< /command >}} ## 自定义路径 指定文件路径进行导出 {{< command >}} tdl chat users -c CHAT -o /path/to/export.json {{< /command >}} ## 原始数据 导出 Telegram MTProto 原始用户结构,用于调试。 {{< command >}} tdl chat users -c CHAT --raw {{< /command >}} --- ### Content/Zh/Guide/Tools/Export Messages --- title: "导出消息" weight: 30 --- # 导出消息 以 JSON 格式导出聊天、频道、群组等中的媒体消息。 {{< include "snippets/chat.md" >}} {{< hint info >}} 空的 CHAT 表示“收藏夹” {{< /hint >}} ## 所有消息 将包含媒体的所有消息导出到 `tdl-export.json` {{< command >}} tdl chat export -c CHAT {{< /command >}} ## 从主题/回复中导出 从特定主题导出媒体消息: {{< hint info >}} 获取主题 ID 的方式: 1. 消息链接:`https://t.me/c/1492447836/251011/269724`(`251011` 是主题 ID) 2. `tdl chat ls` 命令 {{< /hint >}} {{< command >}} tdl chat export -c CHAT --topic TOPIC_ID {{< /command >}} 从特定频道帖子的回复中导出媒体消息: {{< command >}} tdl chat export -c CHAT --reply POST_ID {{< /command >}} ## 自定义路径 指定输出文件路径进行导出。默认:`tdl-export.json`。 {{< command >}} tdl chat export -c CHAT -o /path/to/output.json {{< /command >}} ## 自定义类型 ### 时间范围 根据特定的时间戳范围进行导出。默认:`1970-01-01` - `当前` {{< command >}} tdl chat export -c CHAT -T time -i 1665700000,1665761624 {{< /command >}} `time` 也是 `-T` 选项的默认值,因此您可以省略它 {{< command >}} tdl chat export -c CHAT -i 1665700000,1665761624 {{< /command >}} ### ID 范围 根据特定的消息 ID 范围进行导出。默认:`0` - `最新` {{< command >}} tdl chat export -c CHAT -T id -i 100,500 {{< /command >}} ### 最新 导出最后 100 条媒体文件: {{< command >}} tdl chat export -c CHAT -T last -i 100 {{< /command >}} ## 过滤 请参考[过滤器指南](/zh/reference/expr)以获取有关过滤器的基本知识。 列出所有可用的过滤字段: {{< command >}} tdl chat export -c CHAT -f - {{< /command >}} 导出最后的 10 个媒体文件,其中 `大小 > 5MiB` 且 `查看次数 > 200`: {{< command >}} tdl chat export -c CHAT -T last -i 10 -f "Views>200 && Media.Name endsWith '.zip' && Media.Size > 5*1024*1024" {{< /command >}} ## 包含内容 附带消息内容: {{< command >}} tdl chat export -c CHAT --with-content {{< /command >}} ## 原始数据 导出 Telegram MTProto 原始消息结构,用于调试。 {{< command >}} tdl chat export -c CHAT --raw {{< /command >}} ## 非媒体消息 导出包括非媒体消息的所有消息,用于调试/备份。 {{< command >}} tdl chat export -c CHAT --all {{< /command >}} --- ### Content/Zh/Guide/Tools/List Chats --- title: "列出聊天" weight: 10 --- # 列出聊天 ## 列出所有聊天 {{< command >}} tdl chat ls {{< /command >}} ## JSON 格式 {{< command >}} tdl chat ls -o json {{< /command >}} ## 过滤器 请参考 [过滤器指南](/zh/reference/expr) 以获取有关过滤器的基本知识。 列出所有可用的过滤字段: {{< command >}} tdl chat ls -f - {{< /command >}} 列出名字包含 "Telegram" 的频道: {{< command >}} tdl chat ls -f "Type contains 'channel' && VisibleName contains 'Telegram'" {{< /command >}} 列出具有主题的群组: {{< command >}} tdl chat ls -f "len(Topics)>0" {{< /command >}} --- ### Content/Zh/Guide/Download --- title: "下载" weight: 30 --- # 下载 ## 从链接下载: {{< hint info >}} 点击官方客户端的 "复制链接" 按钮获取消息链接。 {{< /hint >}} {{< include "snippets/link.md" >}} {{< command >}} tdl dl -u https://t.me/tdl/1 -u https://t.me/tdl/2 {{< /command >}} ## 从 JSON 下载: 有两种导出 JSON 文件的方式: {{< tabs "json" >}} {{< tab "tdl" >}} 请参考 [导出消息](/zh/guide/tools/export-messages) {{< /tab >}} {{< tab "桌面客户端" >}} 1. 选择要导出的对话,点击右上角的三个点,然后点击 `导出聊天历史`。 2. 取消选中所有选项(您现在不需要下载它们),将 `大小限制` 设置为最小值。 3. 设置格式为 `JSON` 并选择您需要的时间段。 4. 导出它!`result.json` 就是您需要的文件。 {{< /tab >}} {{< /tabs >}} {{< command >}} tdl dl -f result1.json -f result2.json {{< /command >}} ## 合并下载: {{< command >}} tdl dl \ -u https://t.me/tdl/1 -u https://t.me/tdl/2 \ -f result1.json -f result2.json {{< /command >}} ## 自定义目录: 将文件下载到自定义目录 {{< command >}} tdl dl -u https://t.me/tdl/1 -d /path/to/dir {{< /command >}} ## 自定义参数: 使用每个任务8个线程,4个并发任务下载: {{< command >}} tdl dl -u https://t.me/tdl/1 -t 8 -l 4 {{< /command >}} ## 反序下载: 按反序下载文件(从最新到最旧) {{< hint warning >}} 不同的顺序将影响“恢复下载”功能 {{< /hint >}} {{< command >}} tdl dl -f result.json --desc {{< /command >}} ## MIME 探测: 如果文件扩展名与 MIME 类型不匹配,tdl将使用正确的扩展名重命名文件。 {{< hint warning >}} 副作用:例如 `.apk` 文件将被重命名为 `.zip`。 {{< /hint >}} {{< command >}} tdl dl -u https://t.me/tdl/1 --rewrite-ext {{< /command >}} ## 相册/组合消息探测 自动检测消息是否为相册/组合消息,并下载相应的所有文件。 {{< command >}} tdl dl -u https://t.me/tdl/1 --group {{< /command >}} ## 自动跳过 在下载时跳过相同的文件(即名称和大小相同)。 {{< command >}} tdl dl -u https://t.me/tdl/1 --skip-same {{< /command >}} ## "Takeout" 会话 通过 ["Takeout" 会话](https://arabic-telethon.readthedocs.io/en/stable/extra/examples/telegram-client.html#exporting-messages) 下载文件: > 如果下载大量媒体,更倾向于使用 "Takeout" 会话,它允许您以较低的速率限制从您的帐户中导出数据。 {{< command >}} tdl dl -u https://t.me/tdl/1 --takeout {{< /command >}} ## 过滤器 使用扩展名过滤器下载文件: {{< hint warning >}} 扩展名仅与文件名匹配,而不是 MIME 类型。因此,这可能不会按预期工作。 白名单和黑名单不能同时使用。 {{< /hint >}} 白名单:只下载扩展名为 `.jpg` `.png` 的文件 {{< command >}} tdl dl -u https://t.me/tdl/1 -i jpg,png {{< /command >}} 黑名单:下载除了扩展名为 `.mp4` `.flv` 的所有文件 {{< command >}} tdl dl -u https://t.me/tdl/1 -e mp4,flv {{< /command >}} ## 文件名模板 使用自定义文件名模板下载: 请参考 [模板指南](/zh/guide/template) 了解更多。 {{< command >}} tdl dl -u https://t.me/tdl/1 \ --template "{{ .DialogID }}_{{ .MessageID }}_{{ .DownloadDate }}_{{ .FileName }}" {{< /command >}} ## 恢复/重新开始下载 在不需要交互的情况下恢复下载: {{< command >}} tdl dl -u https://t.me/tdl/1 --continue {{< /command >}} 在不需要交互的情况下重新开始下载: {{< command >}} tdl dl -u https://t.me/tdl/1 --restart {{< /command >}} ## HTTP 文件服务器 将文件暴露为 HTTP 服务器,而不使用内置下载它们 {{< hint info >}} 当您想要使用下载管理器(如 `aria2`/`wget`/`axel`/`IDM`)下载文件时,适合使用此选项。 {{< /hint >}} {{< command >}} tdl dl -u https://t.me/tdl/1 --serve {{< /command >}} 使用自定义端口: {{< command >}} tdl dl -u https://t.me/tdl/1 --serve --port 8081 {{< /command >}} --- ### Content/Zh/Guide/Extensions --- title: "扩展 🆕" weight: 70 --- # 扩展 {{< hint warning >}} 扩展是 tdl 的一项新功能,仍处于实验阶段,CLI 可能会在未来版本中发生变化。 如果你遇到任何问题或有任何建议,请在 GitHub 上[创建 Issue](https://github.com/iyear/tdl/issues/new/choose)。 {{< /hint >}} ## 概览 tdl 扩展是与 tdl 核心无缝集成的独立工具。它们提供了一种扩展 tdl 核心的方法,但不需要将每个新功能添加到核心代码中。 tdl 扩展具有以下特点: - 它们可以添加和删除,而不会影响 tdl 核心。 - 它们与 tdl 集成,并会显示在 tdl 命令和其他地方。 tdl 扩展位于 `~/.tdl/extensions`,由 `tdl extension` 子命令控制。 使用以下命令快速体验 tdl 扩展: {{< command >}} tdl extension install iyear/tdl-whoami {{< /command >}} {{< command >}} tdl whoami {{< /command >}} 你可以看到 `tdl-whoami` 扩展的输出。详情请参阅 [tdl-whoami](https://github.com/iyear/tdl-whoami)。 ``` You are XXXXX. ID: XXXXXXXX ``` ## 查找扩展 你可以通过浏览[带有 `tdl-extension` 主题的代码库](https://github.com/topics/tdl-extension)来查找扩展。 ## 安装扩展 要安装扩展,请使用 `extension install` 子命令。 扩展有两种类型: - `GitHub` : 托管在 GitHub 代码库上的扩展。 {{< command >}} tdl extension install / {{< /command >}} 要从私有代码库安装扩展,必须设置 `GITHUB_TOKEN` 环境变量为 [GitHub 个人访问令牌](https://github.com/settings/personal-access-tokens/new)(具有 `Contents` 读取权限)。 {{< command >}} export GITHUB_TOKEN=YOUR_TOKEN tdl extension install / {{< /command >}} - `Local` : 存储在本地计算机上的扩展。 {{< command >}} tdl extension install /path/to/extension {{< /command >}} 强制安装已经存在的扩展,请使用 `--force` 选项: {{< command >}} tdl extension install --force EXTENSION {{< /command >}} 一次安装多个扩展,请使用以下命令: {{< command >}} tdl extension install / /path/to/extension2 ... {{< /command >}} 仅打印信息而不实际安装扩展,请使用 `--dry-run` 选项: {{< command >}} tdl extension install --dry-run EXTENSION {{< /command >}} 如果你已经安装了同名的扩展,安装将失败。例如,如果你已经安装了 `foo/tdl-whoami`,则必须在安装 `bar/tdl-whoami` 之前卸载它。 ## 运行扩展 安装扩展后,可以像运行本地 tdl 命令一样运行扩展,使用 `tdl EXTENSION-NAME`。`EXTENSION-NAME` 是包含扩展的代码库的名称,去掉 `tdl-` 前缀。 例如,如果你从 `iyear/tdl-whoami` 代码库安装了扩展,可以使用以下命令运行扩展。 {{< command >}} tdl whoami {{< /command >}} 运行扩展时,全局配置仍然可用。例如,以下命令在运行 `tdl-whoami` 扩展时指定命名空间和代理。 {{< command >}} tdl -n foo --proxy socks5://localhost:1080 whoami {{< /command >}} 扩展自身的选项也可以使用。例如,以下命令在运行 `tdl-whoami` 扩展时启用详细模式。 {{< hint info >}} 请记住在扩展子命令之前写全局选项,在扩展子命令之后写扩展选项: {{< command >}} tdl <全局选项> <扩展名> <扩展选项> {{< /command >}} {{< /hint >}} {{< command >}} tdl -n foo whoami -v {{< /command >}} 通常可以在包含扩展的代码库的 README 中找到有关如何使用扩展的具体信息。 ## 查看已安装的扩展 要查看所有已安装的扩展,请使用 `extension list` 子命令。此命令将列出所有已安装的扩展及其作者和版本。 {{< command >}} tdl extension list {{< /command >}} ## 更新扩展 要更新扩展,请使用 `extension upgrade` 子命令。将 `EXTENSION` 参数替换为扩展的名称。 {{< command >}} tdl extension upgrade EXTENSION1 EXTENSION2 ... {{< /command >}} 更新所有已安装的扩展,请设置 `EXTENSION` 参数为空。 {{< command >}} tdl extension upgrade {{< /command >}} 从 GitHub 私有代码库升级扩展,必须设置 `GITHUB_TOKEN` 环境变量为 [GitHub 个人访问令牌](https://github.com/settings/personal-access-tokens/new)(具有 `Contents` 读取权限)。 {{< command >}} export GITHUB_TOKEN=YOUR_TOKEN tdl extension upgrade EXTENSION {{< /command >}} 仅打印信息而不实际升级扩展,请使用 `--dry-run` 选项: {{< command >}} tdl extension upgrade --dry-run EXTENSION {{< /command >}} ## 卸载扩展 要卸载扩展,请使用 `extension remove` 子命令。将 `EXTENSION` 参数替换为扩展的名称。 {{< command >}} tdl extension remove EXTENSION1 EXTENSION2 ... {{< /command >}} 仅打印信息而不实际卸载扩展,请使用 `--dry-run` 选项: {{< command >}} tdl extension remove --dry-run EXTENSION {{< /command >}} ## 开发扩展 请参阅 [tdl-extension-template](https://github.com/iyear/tdl-extension-template) 代码库,了解如何为 tdl 创建、构建和发布扩展。 --- ### Content/Zh/Guide/Forward --- title: "转发" weight: 35 --- # 转发 具有自动回退和消息路由的转发功能 一行命令将消息从 `https://t.me/telegram/193` 转发到 `收藏夹`: {{< command >}} tdl forward --from https://t.me/telegram/193 {{< /command >}} ## 自定义来源 {{< include "snippets/link.md" >}} 您可以从链接和[导出的JSON文件](/zh/guide/download/#从-json-下载)转发消息: {{< command >}} tdl forward \ --from https://t.me/telegram/193 \ --from https://t.me/telegram/195 \ --from tdl-export.json \ --from tdl-export2.json {{< /command >}} ## 自定义目标 {{< include "snippets/chat.md" >}} ### 特定聊天 转发到特定的聊天: {{< command >}} tdl forward --from tdl-export.json --to CHAT {{< /command >}} ### 消息路由 通过基于 [expr](/zh/reference/expr) 的路由将消息转发至不同的聊天 列出所有可用的字段: {{< command >}} tdl forward --from tdl-export.json --to - {{< /command >}} 如果消息包含 `foo`,则转发到 `CHAT1`,否则转发到 `收藏夹`: {{< hint info >}} 表达式必须返回一个**字符串**或者**结构体**作为目标 CHAT,空字符串表示转发到 `收藏夹`。 {{< /hint >}} {{< command >}} tdl forward --from tdl-export.json \ --to 'Message.Message contains "foo" ? "CHAT1" : ""' {{< /command >}} 转发含有 `foo` 的消息到 `CHAT1`,否则转发到 `CHAT2` 中 ID 为 4 的消息/主题: {{< command >}} tdl forward --from tdl-export.json \ --to 'Message.Message contains "foo" ? "CHAT1" : { Peer: "CHAT2", Thread: 4 }' {{< /command >}} 如果表达式较复杂,你可以传递文件名: {{< details "router.txt" >}} 你可以像写 `switch` 一样编写表达式: ```javascript Message.Message contains "foo" ? "CHAT1" : From.ID == 123456 ? "CHAT2" : Message.Views > 30 ? { Peer: "CHAT3", Thread: 101 } : "" ``` {{< /details >}} {{< command >}} tdl forward --from tdl-export.json --to router.txt {{< /command >}} ## 模式 消息转发采取自动降级策略 可用模式: - `direct`(默认) - `clone` ### Direct 优先使用官方的转发API。 如果聊天或消息不允许使用官方转发API,将自动降级为 `clone` 模式。 {{< command >}} tdl forward --from tdl-export.json --mode direct {{< /command >}} ### Clone 通过复制方式转发消息,将不包含转发来源的标头。 将自动忽略一些无法复制的消息内容,例如投票、发票等 {{< command >}} tdl forward --from tdl-export.json --mode clone {{< /command >}} ## 编辑 使用[表达式引擎](/reference/expr)编辑转发前的消息。 {{< hint info >}} - 你必须传递合并照片的第一条消息才能编辑标题。 - 你可以传递任何合并文档的消息以编辑相应的评论。 {{< /hint >}} 你可以在表达式中引用原始消息的相关字段。 列出所有可用字段: {{< command >}} tdl forward --from tdl-export.json --edit - {{< /command >}} 在原始消息后附加 `测试转发消息`: {{< command >}} tdl forward --from tdl-export.json --edit 'Message.Message + " 测试转发消息"' {{< /command >}} 以[HTML](https://core.telegram.org/bots/api#html-style)格式编写带有样式的消息: {{< command >}} tdl forward --from tdl-export.json --edit \ 'Message.Message + `粗体 链接`' {{< /command >}} 如果表达式较复杂,可以传递文件名: {{< details "edit.txt" >}} ```javascript repeat(Message.Message, 2) + ` 谷歌 必应 粗体 斜体 代码 剧透

package main

import "fmt"

func main() {
    fmt.Println("hello world")
}
` + From.VisibleName ``` {{< /details >}} {{< command >}} tdl forward --from tdl-export.json --edit edit.txt {{< /command >}} ## 试运行 只打印进度而不实际发送消息,可以用于调试消息路由的效果。 {{< command >}} tdl forward --from tdl-export.json --dry-run {{< /command >}} ## 静默发送 发送消息而不通知其他成员。 {{< command >}} tdl forward --from tdl-export.json --silent {{< /command >}} ## 取消分组检测 默认情况下,tdl 将自动探测到分组消息并将它们转发为合并的消息。 你可以通过 `--single` 禁用此行为,将其作为单个消息转发。 {{< command >}} tdl forward --from tdl-export.json --single {{< /command >}} ## 反序 对每个来源的消息进行反序转发。 {{< command >}} tdl forward --from tdl-export.json --desc {{< /command >}} --- ### Content/Zh/Guide/Global Config --- title: "全局设置" weight: 10 --- # 全局配置 全局配置是可以在每个命令中设置的选项。 {{< hint info >}} **每次都设置全局配置!** 全局配置**不代表**配置会被持久化或者只需要在全局设置一次,它们只会在当前命令中生效。 你需要在每一个命令中设置它们。 {{< /hint >}} ## `-n/--ns` 每个命名空间代表一个 Telegram 帐号。默认值:`default`。 例如你想新增一个其他账户,为所有命令都添加 `-n YOUR_ACCOUNT_NAME` 选项即可: {{< command >}} tdl -n iyear {{< /command >}} ## `--proxy` 设置代理。默认值:`""`。 格式:`protocol://username:password@host:port` {{< command >}} tdl --proxy socks5://localhost:1080 tdl --proxy http://localhost:8080 tdl --proxy https://localhost:8081 {{< /command >}} ## `--storage` 设置存储。默认值:`type=bolt,path=~/.tdl/data` 格式: `type=驱动,opt1=val1,opt2=val2,...` 可用的驱动: | 驱动名 | 选项 | 描述 | |:----------:|:------------------------------:|---------------------------------------------| | `bolt`(默认) | `path=/path/to/data-directory` | 将数据存储在单独的数据库文件中,因此您可以在多个进程中使用(但必须是不同的命名空间)。 | | `file` | `path=/path/to/data.json` | 将数据存储在单个 JSON 文件中,通常用于调试。 | | `legacy` | `path=/path/to/data.kv` | **已弃用。** 将数据存储在单个数据库文件中,因此你**不能**在多个进程中使用它。 | | - | - | 等待更多驱动... | {{< command >}} tdl --storage type=bolt,path=/path/to/data-dir {{< /command >}} ## `--ntp` 设置 NTP 服务器。如果为空,将使用系统时间。默认值:`""`。 {{< command >}} tdl --ntp pool.ntp.org {{< /command >}} ## `--reconnect-timeout` 设置 Telegram 连接的重连超时。默认值:`2m`。 {{< hint info >}} 如果您的网络不稳定,请将超时设置为更长时间或0(无限)。 {{< /hint >}} {{< command >}} tdl --reconnect-timeout 1m30s {{< /command >}} ## `--debug` 启用调试级别日志。默认值:`false`。 {{< command >}} tdl --debug {{< /command >}} ## `--pool` 设置 Telegram 客户端的连接池大小。默认值:`8`。 {{< hint info >}} 如果你想要更快的速度,请将连接池设置的更大或者0(无限)。 {{< /hint >}} {{< command >}} tdl --pool 2 {{< /command >}} ## `--delay` 设置每个任务之间的延迟。默认值:`0s`。 {{< hint info >}} 如果你想避免因为短时间内产生大量请求被限流,请设置更长的延迟时间。 {{< /hint >}} {{< command >}} tdl --delay 5s {{< /command >}} ## `--disable-progress-ps` 禁用进度条CPU/内存使用统计信息,这可能会在某些终端中导致显示问题。默认值:`false`。 {{< command >}} tdl --disable-progress-ps {{< /command >}} --- ### Content/Zh/Guide/Login --- type: "docs" title: "登录" weight: 20 bookHref: "/zh/getting-started/quick-start/#login" --- # Login --- ### Content/Zh/Guide/Migration --- title: "迁移" weight: 50 --- # 迁移 备份或恢复您的数据 ## 备份 将您的数据备份到文件中。默认值:`.backup.tdl`。 {{< command >}} tdl backup {{< /command >}} 或者指定输出文件: {{< command >}} tdl backup -d /path/to/custom.tdl {{< /command >}} ## 恢复 从备份文件中恢复您的数据。 {{< command >}} tdl recover -f /path/to/custom.backup.tdl {{< /command >}} ## 迁移 将数据迁移到另一个存储中 查看[存储](/zh/guide/global-config/#--storage)以获取存储选项的详细信息。 迁移当前存储到文件类型存储: {{< command >}} tdl migrate --to type=file,path=/path/to/data.json {{< /command >}} 迁移自定义存储到文件类型存储: {{< command >}} tdl migrate --storage type=bolt,path=/path/to/data-directory --to type=file,path=/path/to/data.json {{< /command >}} --- ### Content/Zh/Guide/Template --- title: "模板指南" bookHidden: true bookToC: false --- # 模板指南 本指南将介绍可用于 tdl 模板中的变量和函数。 模板语法基于[Go text/template](https://golang.org/pkg/text/template/)。 ## 下载 ### 变量 (Beta) | 变量 | 描述 | |:--------------:|:---------------------:| | `DialogID` | Telegram 对话ID | | `MessageID` | Telegram 消息ID | | `MessageDate` | Telegram 消息日期(时间戳) | | `FileName` | Telegram 文件名 | | `FileCaption` | Telegram 文件说明,也就是文本消息 | | `FileSize` | 可读的文件大小,例如 `1GB` | | `DownloadDate` | 下载日期(时间戳) | ### 函数 (Beta) | 函数 | 描述 | 用法 | 示例 | |:------------:|:------------------------------------------------------------------------------------------:|:------------------------------------------------------------:|:-------------------------------------------------------------------------------------:| | `repeat` | 重复 `STRING` `N` 次 | `repeat STRING N` | `{{ repeat "test" 3 }}` | | `replace` | 对 `STRING` 执行 `PAIRS` 替换 | `replace STRING PAIRS...` | `{{ replace "Test" "t" "T" "e" "E" }}` | | `upper` | 将 `STRING` 转换为大写 | `upper STRING` | `{{ upper "Test" }}` | | `lower` | 将 `STRING` 转换为小写 | `lower STRING` | `{{ lower "Test" }}` | | `snakecase` | 将 `STRING` 转换为 snake_case | `snakecase STRING` | `{{ snakecase "Test" }}` | | `camelcase` | 将 `STRING` 转换为 camelCase | `camelcase STRING` | `{{ camelcase "Test" }}` | | `kebabcase` | 将 `STRING` 转换为 kebab-case | `kebabcase STRING` | `{{ kebabcase "Test" }}` | | `rand` | 在范围 `MIN` 到 `MAX` 生成随机数 | `rand MIN MAX` | `{{ rand 1 10 }}` | | `now` | 获取当前时间戳 | `now` | `{{ now }}` | | `formatDate` | [格式化](https://zhuanlan.zhihu.com/p/145009400) `TIMESTAMP` 时间戳
(默认格式: `20060102150405`) | `formatDate TIMESTAMP`
`formatDate TIMESTAMP "format"` | `{{ formatDate 1600000000 }}`
`{{ formatDate 1600000000 "2006-01-02-15-04-05"}}` | | `filenamify` | 尽可能将 `STRING` 转换为合法文件名,可选 `MaxLength` 限制字符串长度避免文件系统限制 | `filenamify STRING MaxLength` | `{{ filenamify .FileName 32 }}` | ### 示例: ```gotemplate {{ .DialogID }}_{{ .MessageID }}_{{ replace .FileCaption `/` `_` `\` `_` `:` `_` }} {{ .FileName }}_{{ formatDate .DownloadDate }}_{{ .FileSize }} {{ .FileName }}_{{ formatDate .DownloadDate "2006-01-02-15-04-05"}}_{{ .FileSize }} {{ lower (replace .FileName ` ` `_`) }} {{ formatDate (now) }} ``` ### 默认: ```gotemplate {{ .DialogID }}_{{ .MessageID }}_{{ filenamify .FileName }} ``` --- ### Content/Zh/Guide/Upload --- title: "上传" weight: 40 --- # 上传 ## 上传文件 上传指定的文件和目录到 `保存的消息`: {{< command >}} tdl up -p /path/to/file -p /path/to/dir {{< /command >}} ## 自定义目标 上传到自定义聊天。 {{< include "snippets/chat.md" >}} ## 指定聊天 上传到指定的聊天: {{< command >}} tdl up -p /path/to/file -c CHAT {{< /command >}} 上传到论坛型聊天的指定主题: {{< command >}} tdl up -p /path/to/file -c CHAT --topic TOPIC_ID {{< /command >}} ## 消息路由 通过基于[表达式](/reference/expr)的消息路由,将文件上传到不同的聊天: {{< hint warning >}} `--to` 标志与 `-c/--chat` 和 `--topic` 标志冲突,只能使用其中一个。 {{< /hint >}} 列出所有可用字段: {{< command >}} tdl up -p /path/to/file --to - {{< /command >}} 如果 MIME 包含 `video` 则上传到 `CHAT1`,否则上传到 `收藏夹`: {{< hint info >}} 必须返回一个字符串或结构体作为目标聊天,空字符串表示上传到 `收藏夹`。 {{< /hint >}} {{< command >}} tdl up -p /path/to/file \ --to 'MIME contains "video" ? "CHAT1" : ""' {{< /command >}} 如果 MIME 包含 `video` 则上传到 `CHAT1`,否则回复 `CHAT2` 的消息/主题 `4`: {{< command >}} tdl up -p /path/to/file \ --to 'MIME contains "video" ? "CHAT1" : { Peer: "CHAT2", Thread: 4 }' {{< /command >}} 如果表达式较复杂,可以传递文件名: {{< details "router.txt" >}} 像使用 `switch` 一样编写表达式: ```javascript MIME contains "video" ? "CHAT1" : FileExt contains ".mp3" ? "CHAT2" : FileName contains "chat3" > 30 ? {Peer: "CHAT3", Thread: 101} : "" ``` {{< /details >}} {{< command >}} tdl up -p /path/to/file --to router.txt {{< /command >}} ## 自定义参数 使用每个任务8个线程、4个并发任务上传: {{< command >}} tdl up -p /path/to/file -t 8 -l 4 {{< /command >}} ## 自定义标题 使用[表达式引擎](/reference/expr)编写自定义标题。 列出所有可用字段: {{< command >}} tdl up -p /path/to/file --caption - {{< /command >}} 自定义简单的标题: {{< command >}} tdl up -p ./path/to/file --caption 'FileName + " - uploaded by tdl"' {{< /command >}} 以[HTML](https://core.telegram.org/bots/api#html-style)格式编写带有样式的消息: {{< command >}} tdl up -p /path/to/file --caption \ 'FileName + `Bold Link`' {{< /command >}} 如果表达式较复杂,可以传递文件名: {{< details "caption.txt" >}} ```javascript repeat(FileName, 2) + ` Google Bing bold italic code spoiler

package main

import "fmt"

func main() {
    fmt.Println("hello world")
}
` + MIME ``` {{< /details >}} {{< command >}} tdl up -p /path/to/file --caption caption.txt {{< /command >}} ## 过滤器 使用扩展名过滤器上传文件: {{< hint warning >}} 扩展名仅与文件名匹配,而不是 MIME 类型。因此,这可能不会按预期工作。 白名单和黑名单不能同时使用。 {{< /hint >}} 白名单:只上传扩展名为 `.jpg` `.png` 的文件 {{< command >}} tdl up -p /path/to/file -p /path/to/dir -i jpg,png {{< /command >}} 黑名单:上传除了扩展名为 `.mp4` `.flv` 的所有文件 {{< command >}} tdl up -p /path/to/file -p /path/to/dir -e mp4 -e flv {{< /command >}} ## 自动删除 删除已上传成功的文件: {{< command >}} tdl up -p /path/to/file --rm {{< /command >}} ## 照片 将图像作为照片而不是文件上传: {{< command >}} tdl up -p /path/to/file --photo {{< /command >}} --- ### Content/Zh/More/Env --- title: "环境变量" weight: 20 --- # 环境变量 {{< hint info >}} 所有环境变量的值优先级低于命令行选项。 {{< /hint >}} 通过设置环境变量,避免在每次重复输入相同的命令行选项。 | 环境变量 | 对应选项 | |:-------------------------:|:-----------------------:| | `TDL_NS` | `-n/--ns` | | `TDL_PROXY` | `--proxy` | | `TDL_STORAGE` | `--storage` | | `TDL_DEBUG` | `--debug` | | `TDL_SIZE` | `-s/--size` | | `TDL_THREADS` | `-t/--threads` | | `TDL_LIMIT` | `-l/--limit` | | `TDL_POOL` | `--pool` | | `TDL_NTP` | `--ntp` | | `TDL_RECONNECT_TIMEOUT` | `--reconnect-timeout` | | `TDL_DISABLE_PROGRESS_PS` | `--disable-progress-ps` | | `TDL_TEMPLATE` | dl `--template` | {{< hint warning >}} - `TDL_STORAGE` 环境变量的格式与命令行选项不同:`{"type": "bolt", "path": "/path/to/data-dir"}` (JSON 对象)。 {{< /hint >}} --- ### Content/Zh/More/Troubleshooting --- title: "疑难解答" weight: 40 --- # 疑难解答 ## 最佳实践 如何减小封号的风险? - 使用官方客户端会话登录。 - 尽可能使用默认的下载和上传选项。不要设置过大的 `threads` 和 `size`。 - 不要同时在多台设备上使用相同的帐户登录。 - 不要同时下载或上传太多文件。 - 成为 Telegram 大会员。😅 ## 常见问题 #### Q: 输入命令后为什么没有响应?日志中为什么出现 `msg_id too high`? **A:** 检查是否需要使用代理(使用 `--proxy` 选项);检查您系统的本地时间是否正确(使用 `--ntp` 选项或校准系统时间) 如果仍然无法解决问题,请使用 `--debug` 标志重新运行。然后创建一个新的 ISSUE 并将日志粘贴到问题中。 #### Q: 使用 tdl 后,桌面客户端停止工作怎么办? **A:** 如果您的桌面客户端无法接收消息、加载聊天或发送消息,可能遇到了会话冲突。 您可以尝试使用 `tdl login` 重新登录,并**选择 YES 以退出桌面客户端登录**,这将删除客户端会话文件以分离会话。 #### Q: 如何将会话迁移到另一台设备? **A:** 您可以使用 `tdl backup` 和 `tdl recover` 命令导出和导入会话。详细信息请参见 [迁移](/zh/guide/migration)。 #### Q: 这算滥用吗? **A:** 不是。下载和上传速度受服务器端限制。由于官方客户端的速度通常不会达到帐户限制,因此开发了此工具,以尽可能高的速度下载文件。 #### Q: 这会导致封禁吗? **A:** 我不确定。所有操作都不涉及向其他人主动发送消息等高风险行为。 --- ### Content/Zh/Reference/Expr --- title: "表达式指南" bookHidden: true --- # 表达式指南 表达式由 [expr](https://github.com/antonmedv/expr) 引擎提供支持,它是一个简单、轻量但功能强大的表达式引擎。 表达式引擎文档:https://expr.medv.io/docs/Language-Definition 它功能强大,但对于新用户来说可能有些难以理解。如果您对表达式引擎有任何疑问,请随时提出 ISSUE。 --- ### Content/Zh/Snippets/Chat --- --- {{< details title="CHAT 示例" open=false >}} #### 可用值: - `@iyear` (用户名) - `iyear` (无前缀 `@` 的用户名) - `123456789`(ID) - `https://t.me/iyear` (公开链接) - `+1 123456789`(电话号码) #### 如何在 Telegram 桌面端获取聊天 ID: - `设置` → `高级` → `实验性设置` → `在资料中显示对话 ID` {{< /details >}} --- ### Content/Zh/Snippets/Link --- --- {{< details title="消息链接示例" open=false >}} - `https://t.me/telegram/193` - `https://t.me/c/1697797156/151` - `https://t.me/iFreeKnow/45662/55005` - `https://t.me/c/1492447836/251015/251021` - `https://t.me/opencfdchannel/4434?comment=360409` - `https://t.me/myhostloc/1485524?thread=1485523` - `...`(如果发现新的链接格式,请提交新的 Issue) {{< /details >}} --- ### Content/Zh/ Index --- title: 介绍 --- # tdl {{< image src="img/logo.png" align="right" height="310" width="310">}} 📥 Telegram Downloader, but more than a downloader ## 特性 - 单文件启动 - 低资源占用 - 吃满你的带宽 - 比官方客户端更快 - 支持从受保护的会话中下载文件 - 具有自动回退和消息路由的转发功能 - 支持上传文件至 Telegram - 导出历史消息/成员/订阅者数据至 JSON 文件 ## 预览 预览中的速度已经达到了代理的限制,同时**速度取决于你是否是付费用户** {{< image src="img/preview.gif" >}} ## 赞助者 ## 贡献者 contributors --- ### Content/En/Getting Started/Installation --- title: "Installation" weight: 10 --- # Installation ## One-Line Scripts {{< tabs "scripts" >}} {{< tab "Windows" >}} `tdl` will be installed to `$Env:SystemDrive\tdl`(will be added to `PATH`), and script also can be used to upgrade `tdl` . #### Install latest version {{< command >}} iwr -useb https://docs.iyear.me/tdl/install.ps1 | iex {{< /command >}} #### Install with `ghproxy.com` {{< command >}} $Script=iwr -useb https://docs.iyear.me/tdl/install.ps1; $Block=[ScriptBlock]::Create($Script); Invoke-Command -ScriptBlock $Block -ArgumentList "", "$True" {{< /command >}} #### Install specific version {{< command >}} $Env:TDLVersion = "VERSION" $Script=iwr -useb https://docs.iyear.me/tdl/install.ps1; $Block=[ScriptBlock]::Create($Script); Invoke-Command -ScriptBlock $Block -ArgumentList "$Env:TDLVersion" {{< /command >}} {{< /tab >}} {{< tab "macOS & Linux" >}} `tdl` will be installed to `/usr/local/bin/tdl`, and script also can be used to upgrade `tdl`. #### Install latest version {{< command >}} curl -sSL https://docs.iyear.me/tdl/install.sh | sudo bash {{< /command >}} #### Install with `ghproxy.com` {{< command >}} curl -sSL https://docs.iyear.me/tdl/install.sh | sudo bash -s -- --proxy {{< /command >}} #### Install specific version {{< command >}} curl -sSL https://docs.iyear.me/tdl/install.sh | sudo bash -s -- --version VERSION {{< /command >}} {{< /tab >}} {{< /tabs >}} ## Package Managers {{< tabs "package managers" >}} {{}} {{< command >}} brew install telegram-downloader {{< /command >}} {{< /tab >}} {{}} {{< command >}} scoop bucket add extras scoop install telegram-downloader {{< /command >}} {{< /tab >}} {{}} {{< command >}} pkg install tdl {{< /command >}} {{< /tab >}} {{}} {{< command >}} yay -S tdl {{< /command >}} {{< /tab >}} {{}} #### nix-env {{< command >}} nix-env -iA nixos.tdl {{< /command >}} #### NixOS-Configuration ``` environment.systemPackages = [ pkgs.tdl ]; ``` #### nix-shell {{< command >}} nix-shell -p tdl {{< /command >}} {{< /tab >}} {{< /tabs >}} [](https://repology.org/project/telegram-downloader/versions) ## Docker Available images: - [`iyear/tdl`](https://hub.docker.com/r/iyear/tdl) - [`ghcr.io/iyear/tdl`](https://ghcr.io/iyear/tdl) Available tags: - `latest`(default): The latest stable release - `X.Y.Z`: A specific version of `tdl` {{< tabs "docker" >}} {{< tab "Docker" >}} To run `tdl` in one-off command: {{< command >}} docker run --rm -it iyear/tdl {{< /command >}} Further, to keep config persistent, you can mount the config directory: {{< command >}} docker run --rm -it \ -v $HOME/.tdl:/root/.tdl \ iyear/tdl {{< /command >}} To get download files, you can mount the download and other directories as needed: {{< command >}} docker run --rm -it \ -v $HOME/.tdl:/root/.tdl \ -v $HOME/Downloads:/downloads \ iyear/tdl {{< /command >}} To run `tdl` inside the container shell: {{< command >}} docker run --rm -it --entrypoint sh iyear/tdl {{< /command >}} {{< details title="Preview output" open=false >}} ```1 / # tdl version Version: 0.17.7 Commit: ace2402 Date: 2024-11-01T14:40:56+08:00 go1.21.13 linux/amd64 / # ``` {{< /details >}} To use proxy with `localhost` address, run it with `host` network: {{< command >}} docker run --rm -it --network host iyear/tdl {{< /command >}} {{< /tab >}} {{< tab "Docker Compose" >}} Run `tdl` with Docker Compose to avoid typing `docker run` flags each time. {{< details title="docker-compose.yml" open=false >}} {{< hint info >}} Example configuration uses Docker Compose v2 syntax. {{< /hint >}} ```yaml services: tdl: image: iyear/tdl # or specify X.Y.Z tag for a specific version volumes: - $HOME/.tdl:/root/.tdl # keep config persistent - $HOME/Downloads:/downloads # optional # - /path/to/your/need:/path/in/container stdin_open: true tty: true # use host network if you need to use proxy with localhost address network_mode: host ``` {{< /details >}} Run `tdl` with Docker Compose: {{< command >}} docker compose run --rm tdl {{< /command >}} To run `tdl` inside the container shell: {{< command >}} docker compose run --rm --entrypoint sh tdl {{< /command >}} {{< details title="Preview output" open=false >}} ```1 / # tdl version Version: 0.17.7 Commit: ace2402 Date: 2024-11-01T14:40:56+08:00 go1.21.13 linux/amd64 / # ``` {{< /details >}} {{< /tab >}} {{< /tabs >}} ## Prebuilt Binaries 1. Download the archive for the desired operating system, and architecture: {{< tabs "prebuilt" >}} {{< tab "Windows" >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Windows_64bit.zip" >}}x86_64/amd64{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Windows_32bit.zip" >}}x86{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Windows_arm64.zip" >}}arm64{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Windows_armv5.zip" >}}armv5{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Windows_armv6.zip" >}}armv6{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Windows_armv7.zip" >}}armv7{{< /button >}} {{< /tab >}} {{< tab "macOS" >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_MacOS_64bit.tar.gz" >}}Intel{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_MacOS_arm64.tar.gz" >}}M1/M2{{< /button >}} {{< /tab >}} {{< tab "Linux" >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Linux_64bit.tar.gz" >}}x86_64/amd64{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Linux_32bit.tar.gz" >}}x86{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Linux_arm64.tar.gz" >}}arm64{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Linux_armv5.tar.gz" >}}armv5{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Linux_armv6.tar.gz" >}}armv6{{< /button >}} {{< button href="https://github.com/iyear/tdl/releases/latest/download/tdl_Linux_armv7.tar.gz" >}}armv7{{< /button >}} {{< /tab >}} {{< /tabs >}} 2. Extract the archive 3. Move the executable to the desired directory 4. Add this directory to the PATH environment variable 5. Verify that you have execute permission on the file ## Source To build the extended edition of `tdl` from source you must: 1. Install [Git](https://git-scm.com/) 2. Install [Go](https://go.dev/) version 1.25 or later 3. Update your `PATH` environment variable as described in the Go documentation {{< hint info >}} The installation directory is controlled by the `GOPATH` and `GOBIN` environment variables. If `GOBIN` is set, binaries are installed to that directory. If `GOPATH` is set, binaries are installed to the `bin` subdirectory of the first directory in the `GOPATH` list. Otherwise, binaries are installed to the `bin` subdirectory of the default `GOPATH` (`$HOME/go` or `%USERPROFILE%\go`). {{< /hint >}} Then build: {{< command >}} go install github.com/iyear/tdl@latest tdl version {{< /command >}} --- ### Content/En/Getting Started/Quick Start --- title: "Quick Start" weight: 20 --- # Quick Start ## Login We don't specify the namespace here, so it will use the `default` namespace. You can specify the namespace with `-n` flag if you want to use another namespace. ### **Login with desktop clients** {{< hint warning >}} Please ensure that clients are downloaded from [official website](https://desktop.telegram.org/) (NOT from Microsoft Store or App Store) {{< /hint >}} Automatically find the client path: {{< command >}} tdl login {{< /command >}} Or if you set a local passcode: {{< command >}} tdl login -p YOUR_PASSCODE {{< /command >}} Or specify custom client path: {{< command >}} tdl login -d /path/to/TelegramDesktop {{< /command >}} ### **Login with QR code** {{< command >}} tdl login -T qr {{< /command >}} ### **Login with phone & code** {{< command >}} tdl login -T code {{< /command >}} ## Download We download media from Telegram official channel: {{< command >}} tdl dl -u https://t.me/telegram/193 {{< /command >}} --- ### Content/En/Getting Started/Shell Completion --- title: "Shell Completion" weight: 30 --- # Shell Completion Run corresponding command to enable shell completion in all sessions: {{< tabs "shell" >}} {{< tab "bash" >}} {{< command >}} echo "source <(tdl completion bash)" >> ~/.bashrc {{< /command >}} {{< /tab >}} {{< tab "zsh" >}} {{< command >}} echo "source <(tdl completion zsh)" >> ~/.zshrc {{< /command >}} {{< /tab >}} {{< tab "fish" >}} {{< command >}} echo "tdl completion fish | source" >> ~/.config/fish/config.fish {{< /command >}} {{< /tab >}} {{< tab "PowerShell" >}} {{< command >}} Add-Content -Path $PROFILE -Value "tdl completion powershell | Out-String | Invoke-Expression" {{< /command >}} {{< /tab >}} {{< /tabs >}} --- ### Content/En/Guide/Tools/Export Members --- title: "Export Members" weight: 20 --- # Export Members Export chat members/subscribers, admins, bots, etc. {{< hint info >}} Chat administrator permission is required for some types of members(kicked, banned, etc.). {{< /hint >}} {{< include "snippets/chat.md" >}} ## All Export all users to `tdl-users.json` {{< command >}} tdl chat users -c CHAT {{< /command >}} ## Custom Destination Export with specified file path {{< command >}} tdl chat users -c CHAT -o /path/to/export.json {{< /command >}} ## Raw Export Telegram MTProto raw user structure, which is useful for debugging. {{< command >}} tdl chat users -c CHAT --raw {{< /command >}} --- ### Content/En/Guide/Tools/Export Messages --- title: "Export Messages" weight: 30 --- # Export Messages Export media messages from chats, channels, groups, etc. in JSON format. {{< include "snippets/chat.md" >}} {{< hint info >}} Empty CHAT means 'Saved Messages' {{< /hint >}} ## All Export all messages containing media to `tdl-export.json` {{< command >}} tdl chat export -c CHAT {{< /command >}} ## From Topic/Replies Export media messages from specific topic: {{< hint info >}} Get Topic ID: 1. Message Link: `https://t.me/c/1492447836/251011/269724` (`251011` is topic id) 2. `tdl chat ls` command {{< /hint >}} {{< command >}} tdl chat export -c CHAT --topic TOPIC_ID {{< /command >}} Export media messages from specific channel post replies: {{< command >}} tdl chat export -c CHAT --reply POST_ID {{< /command >}} ## Custom Destination Export with specific output file path. Default: `tdl-export.json`. {{< command >}} tdl chat export -c CHAT -o /path/to/output.json {{< /command >}} ## Custom Type ### Time Range Export with specific timestamp range. Default: `1970-01-01` - `NOW` {{< command >}} tdl chat export -c CHAT -T time -i 1665700000,1665761624 {{< /command >}} `time` is also the default value of `-T` option, so you can omit it {{< command >}} tdl chat export -c CHAT -i 1665700000,1665761624 {{< /command >}} ### ID Range Export with specific message id range. Default: `0` - `latest` {{< command >}} tdl chat export -c CHAT -T id -i 100,500 {{< /command >}} ### Last Export last 100 media messages: {{< command >}} tdl chat export -c CHAT -T last -i 100 {{< /command >}} ## Filter Please refer to [Filter Guide](/reference/expr) for basic knowledge about filter. List all available filter fields: {{< command >}} tdl chat export -c CHAT -f - {{< /command >}} Export last 10 zip files that `size > 5MiB` and `views > 200`: {{< command >}} tdl chat export -c CHAT -T last -i 10 -f "Views>200 && Media.Name endsWith '.zip' && Media.Size > 5*1024*1024" {{< /command >}} ## With Content Export with message content: {{< command >}} tdl chat export -c CHAT --with-content {{< /command >}} ## Raw Export Telegram MTProto raw message structure, which is useful for debugging. {{< command >}} tdl chat export -c CHAT --raw {{< /command >}} ## Non-Media Export all messages including non-media messages, which is useful for debugging/backup. {{< command >}} tdl chat export -c CHAT --all {{< /command >}} --- ### Content/En/Guide/Tools/List Chats --- title: "List Chats" weight: 10 --- # List Chats ## List all chats {{< command >}} tdl chat ls {{< /command >}} ## JSON Output {{< command >}} tdl chat ls -o json {{< /command >}} ## Filter Please refer to [Filter Guide](/reference/expr) for basic knowledge about filter. List all available filter fields: {{< command >}} tdl chat ls -f - {{< /command >}} List channels that VisibleName contains "Telegram": {{< command >}} tdl chat ls -f "Type contains 'channel' && VisibleName contains 'Telegram'" {{< /command >}} List groups that have topics: {{< command >}} tdl chat ls -f "len(Topics)>0" {{< /command >}} --- ### Content/En/Guide/Download --- title: "Download" weight: 30 --- # Download ## From Links: {{< hint info >}} Get message links from "Copy Link" button in official clients. {{< /hint >}} {{< include "snippets/link.md" >}} {{< command >}} tdl dl -u https://t.me/tdl/1 -u https://t.me/tdl/2 {{< /command >}} ## From JSON: There are two ways to export the JSON you need: {{< tabs "json" >}} {{< tab "tdl" >}} This is especially for protected chats and more powerful than the desktop client. Please refer to [Export Messages](/guide/tools/export-messages) {{< /tab >}} {{< tab "Desktop Client" >}} 1. Choose the dialog you want to export, and click the three dots in the upper right corner, then click `Export Chat History`. 2. Uncheck all boxes(you don't need to download them now) and set `Size Limit` to minimum 3. Set Format to `JSON` and select the time period you need. 4. Export it! And `result.json` is what you need. {{< /tab >}} {{< /tabs >}} {{< command >}} tdl dl -f result1.json -f result2.json {{< /command >}} ## Combine Sources: {{< command >}} tdl dl \ -u https://t.me/tdl/1 -u https://t.me/tdl/2 \ -f result1.json -f result2.json {{< /command >}} ## Custom Destination: Download files to custom directory {{< command >}} tdl dl -u https://t.me/tdl/1 -d /path/to/dir {{< /command >}} ## Custom Parameters: Download with 8 threads per task, 4 concurrent tasks: {{< command >}} tdl dl -u https://t.me/tdl/1 -t 8 -l 4 {{< /command >}} ## Descending Order: Download files in descending order(from newest to oldest) {{< hint warning >}} Different order will affect resuming download {{< /hint >}} {{< command >}} tdl dl -f result.json --desc {{< /command >}} ## MIME Detection: If the file extension is not matched with the MIME type, tdl will rename the file with the correct extension. {{< hint warning >}} Side effect: like `.apk` file, it will be renamed to `.zip`. {{< /hint >}} {{< command >}} tdl dl -u https://t.me/tdl/1 --rewrite-ext {{< /command >}} ## Album/Grouped Detection Automatically detect if the message is an album/grouped message and download all of them. {{< command >}} tdl dl -u https://t.me/tdl/1 --group {{< /command >}} ## Auto Skip Skip the same files(name and size) when downloading. {{< command >}} tdl dl -u https://t.me/tdl/1 --skip-same {{< /command >}} ## Takeout Session Download files with [takeout session](https://arabic-telethon.readthedocs.io/en/stable/extra/examples/telegram-client.html#exporting-messages): > If you plan to download a lot of media, you may prefer to do this within a takeout session. Takeout sessions let you > export data from your account with lower flood wait limits. {{< command >}} tdl dl -u https://t.me/tdl/1 --takeout {{< /command >}} ## Filters Download files with extension filters: {{< hint warning >}} The extension is only matched with the file name, not the MIME type. So it may not work as expected. Whitelist and blacklist can not be used at the same time. {{< /hint >}} Whitelist: Only download files with `.jpg` `.png` extension {{< command >}} tdl dl -u https://t.me/tdl/1 -i jpg,png {{< /command >}} Blacklist: Download all files except `.mp4` `.flv` extension {{< command >}} tdl dl -u https://t.me/tdl/1 -e mp4,flv {{< /command >}} ## Name Template Download with custom file name template: Please refer to [Template Guide](/guide/template) for more details. {{< command >}} tdl dl -u https://t.me/tdl/1 \ --template "{{ .DialogID }}_{{ .MessageID }}_{{ .DownloadDate }}_{{ .FileName }}" {{< /command >}} ## Resume/Restart Resume without UI interaction: {{< command >}} tdl dl -u https://t.me/tdl/1 --continue {{< /command >}} Restart without UI interaction: {{< command >}} tdl dl -u https://t.me/tdl/1 --restart {{< /command >}} ## Serve Expose the files as an HTTP server instead of downloading them with built-in downloader {{< hint info >}} This is useful when you want to download files with a download manager like `aria2`/`wget`/`axel`/`IDM`... {{< /hint >}} {{< command >}} tdl dl -u https://t.me/tdl/1 --serve {{< /command >}} With custom port: {{< command >}} tdl dl -u https://t.me/tdl/1 --serve --port 8081 {{< /command >}} --- ### Content/En/Guide/Extensions --- title: "Extensions 🆕" weight: 70 --- # Extensions {{< hint warning >}} Extensions are a new feature in tdl. They are still in the experimental stage, and the CLI may change in future versions. If you encounter any problems or have any suggestions, please [open an issue](https://github.com/iyear/tdl/issues/new/choose) on GitHub. {{< /hint >}} ## Overview tdl extensions are add-on tools that integrate seamlessly with tdl. They provide a way to extend the core feature set of tdl, but without requiring every new feature to be added to the core. tdl extensions have the following features: - They can be added and removed without impacting the core tdl tool. - They integrate with tdl, and will show up in tdl help and other places. tdl extensions live in `~/.tdl/extensions`, which is controlled by `tdl extension` commands. To get started with extensions, you can use the following commands: {{< command >}} tdl extension install iyear/tdl-whoami {{< /command >}} {{< command >}} tdl whoami {{< /command >}} You can see the output of the `tdl-whoami` extension. Refer to the [tdl-whoami](https://github.com/iyear/tdl-whoami) for details. ``` You are XXXXX. ID: XXXXXXXX ``` ## Finding extensions You can find extensions by browsing [repositories with the `tdl-extension` topic](https://github.com/topics/tdl-extension). ## Installing extensions To install an extension, use the `extension install` subcommand. There are two types of extensions: - `GitHub` : Extensions hosted on GitHub repositories. {{< command >}} tdl extension install / {{< /command >}} To install an extension from a private repository, you must set up a [GitHub personal access token](https://github.com/settings/personal-access-tokens/new)(with `Contents` read permission) in your environment with the `GITHUB_TOKEN` variable. {{< command >}} export GITHUB_TOKEN=YOUR_TOKEN tdl extension install / {{< /command >}} - `Local` : Extensions stored on your local machine. {{< command >}} tdl extension install /path/to/extension {{< /command >}} To install an extension even if it exists, use the `--force` flag: {{< command >}} tdl extension install --force EXTENSION {{< /command >}} To install multiple extensions at once, use the following command: {{< command >}} tdl extension install / /path/to/extension2 ... {{< /command >}} To only print information without actually installing the extension, use the `--dry-run` flag: {{< command >}} tdl extension install --dry-run EXTENSION {{< /command >}} If you already have an extension by the same name installed, the command will fail. For example, if you have installed `foo/tdl-whoami`, you must uninstall it before installing `bar/tdl-whoami`. ## Running extensions When you have installed an extension, you run the extension as you would run a native tdl command, using `tdl EXTENSION-NAME`. The `EXTENSION-NAME` is the name of the repository that contains the extension, minus the `tdl-` prefix. For example, if you installed the extension from the `iyear/tdl-whoami` repository, you would run the extension with the following command. {{< command >}} tdl whoami {{< /command >}} Global config flags are still available when running an extension. For example, you can run the following command to specify namespace and proxy when running the `tdl-whoami` extension. {{< command >}} tdl -n foo --proxy socks5://localhost:1080 whoami {{< /command >}} Flags specific to an extension can also be used. For example, you can run the following command to enable verbose mode when running the `tdl-whoami` extension. {{< hint info >}} Remember to write global flags before extension subcommands and write extension flags after extension subcommands: {{< command >}} tdl {{< /command >}} {{< /hint >}} {{< command >}} tdl -n foo whoami -v {{< /command >}} You can usually find specific information about how to use an extension in the README of the repository that contains the extension. ## Viewing installed extensions To view all installed extensions, use the `extension list` subcommand. This command will list all installed extensions, along with their authors and versions. {{< command >}} tdl extension list {{< /command >}} ## Updating extensions To update an extension, use the `extension upgrade` subcommand. Replace the `EXTENSION` parameters with the name of extensions. {{< command >}} tdl extension upgrade EXTENSION1 EXTENSION2 ... {{< /command >}} To update all installed extensions, keep the `EXTENSION` parameter empty. {{< command >}} tdl extension upgrade {{< /command >}} To upgrade an extension from a GitHub private repository, you must set up a [GitHub personal access token](https://github.com/settings/personal-access-tokens/new)(with `Contents` read permission) in your environment with the `GITHUB_TOKEN` variable. {{< command >}} export GITHUB_TOKEN=YOUR_TOKEN tdl extension upgrade EXTENSION {{< /command >}} To only print information without actually upgrading the extension, use the `--dry-run` flag: {{< command >}} tdl extension upgrade --dry-run EXTENSION {{< /command >}} ## Uninstalling extensions To uninstall an extension, use the `extension remove` subcommand. Replace the `EXTENSION` parameters with the name of extensions. {{< command >}} tdl extension remove EXTENSION1 EXTENSION2 ... {{< /command >}} To only print information without actually uninstalling the extension, use the `--dry-run` flag: {{< command >}} tdl extension remove --dry-run EXTENSION {{< /command >}} ## Developing extensions Please refer to the [tdl-extension-template](https://github.com/iyear/tdl-extension-template) repository for instructions on how to create, build, and publish extensions for tdl. --- ### Content/En/Guide/Forward --- title: "Forward" weight: 35 --- # Forward Forward messages with automatic fallback and message routing One-liner to forward messages from `https://t.me/telegram/193` to `Saved Messages`: {{< command >}} tdl forward --from https://t.me/telegram/193 {{< /command >}} ## Custom Source {{< include "snippets/link.md" >}} You can forward messages from links and [exported JSON files](/guide/download#from-json): {{< command >}} tdl forward \ --from https://t.me/telegram/193 \ --from https://t.me/telegram/195 \ --from tdl-export.json \ --from tdl-export2.json {{< /command >}} ## Custom Destination {{< include "snippets/chat.md" >}} ### Specific Chat Forward to specific one chat: {{< command >}} tdl forward --from tdl-export.json --to CHAT {{< /command >}} ### Message Routing Forward to different chats by message router which is based on [expression](/reference/expr). List all available fields: {{< command >}} tdl forward --from tdl-export.json --to - {{< /command >}} Forward to `CHAT1` if message contains `foo`, otherwise forward to `Saved Messages`: {{< hint info >}} You must return a **string** or **struct** as the target CHAT, and empty string means forward to `Saved Messages`. {{< /hint >}} {{< command >}} tdl forward --from tdl-export.json \ --to 'Message.Message contains "foo" ? "CHAT1" : ""' {{< /command >}} Forward to `CHAT1` if message contains `foo`, otherwise forward to reply to message/topic `4` in `CHAT2`: {{< command >}} tdl forward --from tdl-export.json \ --to 'Message.Message contains "foo" ? "CHAT1" : { Peer: "CHAT2", Thread: 4 }' {{< /command >}} Pass a file name if the expression is complex: {{< details "router.txt" >}} Write your expression like `switch`: ```javascript Message.Message contains "foo" ? "CHAT1" : From.ID == 123456 ? "CHAT2" : Message.Views > 30 ? { Peer: "CHAT3", Thread: 101 } : "" ``` {{< /details >}} {{< command >}} tdl forward --from tdl-export.json --to router.txt {{< /command >}} ## Mode Forward messages with automatic fallback strategy. Available modes: - `direct` (default) - `clone` ### Direct Prefer to use official forward API. If the chat or message is not allowed to use official forward API, it will be automatically downgraded to `clone` mode. {{< command >}} tdl forward --from tdl-export.json --mode direct {{< /command >}} ### Clone Forward messages by copying them, which doesn't have forwarded header. Some message content can't be copied, such as poll, invoice, etc. They will be ignored. {{< command >}} tdl forward --from tdl-export.json --mode clone {{< /command >}} ## Edit Edit the message before forwarding based on [expression](/reference/expr). {{< hint info >}} - You must pass the first message of grouped photos to edit the caption. - You can pass any message of grouped documents to edit the corresponding comment. {{< /hint >}} You can reference relevant fields from the original message in the expression. List all available fields: {{< command >}} tdl forward --from tdl-export.json --edit - {{< /command >}} Append `Test Forwarded Message` to the original message: {{< command >}} tdl forward --from tdl-export.json --edit 'Message.Message + " Test Forwarded Message"' {{< /command >}} Write styled message with [HTML](https://core.telegram.org/bots/api#html-style): {{< command >}} tdl forward --from tdl-export.json --edit \ 'Message.Message + `Bold Link`' {{< /command >}} Pass a file name if the expression is complex: {{< details "edit.txt" >}} ```javascript repeat(Message.Message, 2) + ` Google Bing bold italic code spoiler

package main

import "fmt"

func main() {
    fmt.Println("hello world")
}
` + From.VisibleName ``` {{< /details >}} {{< command >}} tdl forward --from tdl-export.json --edit edit.txt {{< /command >}} ## Dry Run Print the progress without actually sending messages, which is useful for message routing debugging. {{< command >}} tdl forward --from tdl-export.json --dry-run {{< /command >}} ## Silent Send messages without notification. {{< command >}} tdl forward --from tdl-export.json --silent {{< /command >}} ## No Grouped Detection By default, tdl will detect grouped messages and forward them as an album. You can disable this behavior by `--single` to forward it as a single message. {{< command >}} tdl forward --from tdl-export.json --single {{< /command >}} ## Descending Order Forward messages in descending order for each source. {{< command >}} tdl forward --from tdl-export.json --desc {{< /command >}} --- ### Content/En/Guide/Global Config --- title: "Global Config" weight: 10 --- # Global Config Global config is some CLI flags that can be set in every command. {{< hint info >}} **Set Global Config EVERYTIME!** Global config **does not mean** that the configuration will be persisted or only need to be set once in global settings, they will only take effect in the current command. You need to set them in each command. {{< /hint >}} ## `-n/--ns` Each namespace represents a Telegram account. Default: `default`. If you want to add another account, just add `-n YOUR_ACCOUNT_NAME` option to every command: {{< command >}} tdl -n iyear {{< /command >}} ## `--proxy` Set the proxy. Default: `""`. Format: `protocol://username:password@host:port` {{< command >}} tdl --proxy socks5://localhost:1080 tdl --proxy http://localhost:8080 tdl --proxy https://localhost:8081 {{< /command >}} ## `--storage` Set the storage. Default: `type=bolt,path=~/.tdl/data` Format: `type=DRIVER,opt1=val1,opt2=val2,...` Available drivers: | Driver | Options | Description | |:----------------:|:------------------------------:|---------------------------------------------------------------------------------------------------------------| | `bolt` (Default) | `path=/path/to/data-directory` | Store data in separate database files. So you can use it in multiple processes(must be different namespaces). | | `file` | `path=/path/to/data.json` | Store data in a single JSON file, which is useful for debugging. | | `legacy` | `path=/path/to/data.kv` | **Deprecated.** Store data in a single database file. So you **can't** use it in multiple processes. | | - | - | Wait for more drivers... | {{< command >}} tdl --storage type=bolt,path=/path/to/data-dir {{< /command >}} ## `--ntp` Set ntp server host. If it's empty, system time will be used. Default: `""`. {{< command >}} tdl --ntp pool.ntp.org {{< /command >}} ## `--reconnect-timeout` Set Telegram client reconnect timeout. Default: `2m`. {{< hint info >}} Set higher timeout or 0(INF) if your network is poor. {{< /hint >}} {{< command >}} tdl --reconnect-timeout 1m30s {{< /command >}} ## `--debug` Enable debug level log. Default: `false`. {{< command >}} tdl --debug {{< /command >}} ## `--pool` Set the DC pool size of Telegram client. Default: `8`. {{< hint info >}} Set higher timeout or 0(INF) if you want faster speed. {{< /hint >}} {{< command >}} tdl --pool 2 {{< /command >}} ## `--delay` set the delay between each task. Default: `0s`. {{< hint info >}} Set higher delay time if you want to avoid Telegram's flood control. {{< /hint >}} {{< command >}} tdl --delay 5s {{< /command >}} ## `--disable-progress-ps` Disable progress CPU/memory usage stats, which may cause display issues in some terminals. Default: `false`. {{< command >}} tdl --disable-progress-ps {{< /command >}} --- ### Content/En/Guide/Login --- type: "docs" title: "Login" weight: 20 bookHref: "/getting-started/quick-start/#login" --- # Login --- ### Content/En/Guide/Migration --- title: "Migration" weight: 50 --- # Migration Backup or recover your data ## Backup Backup all namespace data to a file. Default: `.backup.tdl`. {{< command >}} tdl backup {{< /command >}} Or specify the output file: {{< command >}} tdl backup -d /path/to/custom.tdl {{< /command >}} ## Recover Recover your data from a tdl backup file. Existing namespace data will be overwritten. {{< command >}} tdl recover -f /path/to/custom.backup.tdl {{< /command >}} ## Migrate Migrate your data to another storage See [Storage Flag](/guide/global-config/#--storage) for storage option details. Migrate current storage to file storage: {{< command >}} tdl migrate --to type=file,path=/path/to/data.json {{< /command >}} Migrate custom source storage to file storage: {{< command >}} tdl migrate --storage type=bolt,path=/path/to/data-directory --to type=file,path=/path/to/data.json {{< /command >}} --- ### Content/En/Guide/Template --- title: "Template Guide" bookHidden: true bookToC: false --- # Template Guide This guide is intended to introduce variables and functions that are available in the tdl template. Template syntax is based on [Go's text/template](https://golang.org/pkg/text/template/) package. ## Download ### Variables (beta) | Var | Desc | |:--------------:|:----------------------------------------:| | `DialogID` | Telegram dialog id | | `MessageID` | Telegram message id | | `MessageDate` | Telegram message date(timestamp) | | `FileName` | Telegram file name | | `FileCaption` | Telegram file caption, aka. text message | | `FileSize` | Human-readable file size, like `1GB` | | `DownloadDate` | Download date(timestamp) | ### Functions (beta) | Func | Desc | Usage | Example | |:------------:|:------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------:|:-------------------------------------------------------------------------------------:| | `repeat` | Repeat `STRING` `N` times | `repeat STRING N` | `{{ repeat "test" 3 }}` | | `replace` | Perform replacement on `STRING` with `PAIRS` | `replace STRING PAIRS...` | `{{ replace "Test" "t" "T" "e" "E" }}` | | `upper` | Convert `STRING` to uppercase | `upper STRING` | `{{ upper "Test" }}` | | `lower` | Convert `STRING` to lowercase | `lower STRING` | `{{ lower "Test" }}` | | `snakecase` | Convert `STRING` to snake_case | `snakecase STRING` | `{{ snakecase "Test" }}` | | `camelcase` | Convert `STRING` to camelCase | `camelcase STRING` | `{{ camelcase "Test" }}` | | `kebabcase` | Convert `STRING` to kebab-case | `kebabcase STRING` | `{{ kebabcase "Test" }}` | | `rand` | Generate random number in range `MIN` to `MAX` | `rand MIN MAX` | `{{ rand 1 10 }}` | | `now` | Get current timestamp | `now` | `{{ now }}` | | `formatDate` | Format `TIMESTAMP` with [format](https://golang.cafe/blog/golang-time-format-example.html)
Default: `20060102150405` | `formatDate TIMESTAMP`
`formatDate TIMESTAMP "format"` | `{{ formatDate 1600000000 }}`
`{{ formatDate 1600000000 "2006-01-02-15-04-05"}}` | | `filenamify` | Convert `STRING` to a valid filename with the best effort. Optional `MaxLength` can be used to limit string length | `filenamify STRING MaxLength` | `{{ filenamify .FileName 32 }}` | ### Examples: ```gotemplate {{ .DialogID }}_{{ .MessageID }}_{{ replace .FileCaption `/` `_` `\` `_` `:` `_` }} {{ .FileName }}_{{ formatDate .DownloadDate }}_{{ .FileSize }} {{ .FileName }}_{{ formatDate .DownloadDate "2006-01-02-15-04-05"}}_{{ .FileSize }} {{ lower (replace .FileName ` ` `_`) }} {{ formatDate (now) }} ``` ### Default: ```gotemplate {{ .DialogID }}_{{ .MessageID }}_{{ filenamify .FileName }} ``` --- ### Content/En/Guide/Upload --- title: "Upload" weight: 40 --- # Upload ## Upload Files Upload specified files and directories to `Saved Messages`: {{< command >}} tdl up -p /path/to/file -p /path/to/dir {{< /command >}} ## Custom Destination Upload to custom chat. {{< include "snippets/chat.md" >}} ### Specific Chat Upload to specific one chat: {{< command >}} tdl up -p /path/to/file -c CHAT {{< /command >}} Upload to specific topic in a forum chat: {{< command >}} tdl up -p /path/to/file -c CHAT --topic TOPIC_ID {{< /command >}} ### Message Routing Upload to different chats by message router which is based on [expression](/reference/expr). {{< hint warning >}} The `--to` flag is conflicted with the `-c/--chat` and `--topic` flags. You can only use one of them. {{< /hint >}} List all available fields: {{< command >}} tdl up -p /path/to/file --to - {{< /command >}} Upload to `CHAT1` if MIME contains `video`, otherwise upload to `Saved Messages`: {{< hint info >}} You must return a **string** or **struct** as the target CHAT, and empty string means upload to `Saved Messages`. {{< /hint >}} {{< command >}} tdl up -p /path/to/file \ --to 'MIME contains "video" ? "CHAT1" : ""' {{< /command >}} Upload to `CHAT1` if MIME contains `video`, otherwise upload to reply to message/topic `4` in `CHAT2`: {{< command >}} tdl up -p /path/to/file \ --to 'MIME contains "video" ? "CHAT1" : { Peer: "CHAT2", Thread: 4 }' {{< /command >}} Pass a file name if the expression is complex: {{< details "router.txt" >}} Write your expression like `switch`: ```javascript MIME contains "video" ? "CHAT1" : FileExt contains ".mp3" ? "CHAT2" : FileName contains "chat3" > 30 ? {Peer: "CHAT3", Thread: 101} : "" ``` {{< /details >}} {{< command >}} tdl up -p /path/to/file --to router.txt {{< /command >}} ## Custom Parameters Upload with 8 threads per task, 4 concurrent tasks: {{< command >}} tdl up -p /path/to/file -t 8 -l 4 {{< /command >}} ## Custom Caption Custom caption is based on [expression](/reference/expr). List all available fields: {{< command >}} tdl up -p /path/to/file --caption - {{< /command >}} Custom simple caption: {{< command >}} tdl up -p /path/to/file --caption 'FileName + " - uploaded by tdl"' {{< /command >}} Write styled message with [HTML](https://core.telegram.org/bots/api#html-style): {{< command >}} tdl up -p /path/to/file --caption \ 'FileName + `Bold Link`' {{< /command >}} Pass a file name if the expression is complex: {{< details "caption.txt" >}} ```javascript repeat(FileName, 2) + ` Google Bing bold italic code spoiler

package main

import "fmt"

func main() {
    fmt.Println("hello world")
}
` + MIME ``` {{< /details >}} {{< command >}} tdl up -p /path/to/file --caption caption.txt {{< /command >}} ## Filters Upload files with extension filters: {{< hint warning >}} The extension is only matched with the file name, not the MIME type. So it may not work as expected. Whitelist and blacklist can not be used at the same time. {{< /hint >}} Whitelist: Only upload files with `.jpg` `.png` extension {{< command >}} tdl up -p /path/to/file -p /path/to/dir -i jpg,png {{< /command >}} Blacklist: Upload all files except `.mp4` `.flv` extension {{< command >}} tdl up -p /path/to/file -p /path/to/dir -e mp4 -e flv {{< /command >}} ## Delete Local Delete the uploaded file after uploading successfully: {{< command >}} tdl up -p /path/to/file --rm {{< /command >}} ## Photo Upload images as photos instead of documents: {{< command >}} tdl up -p /path/to/file --photo {{< /command >}} --- ### Content/En/More/Data --- title: "Data" weight: 30 --- # Data Your account information will be stored in the `~/.tdl` directory. Log files will be stored in the `~/.tdl/log` directory. --- ### Content/En/More/Env --- title: "Env" weight: 20 --- # Env {{< hint info >}} The values of all environment variables have a lower priority than flags. {{< /hint >}} Avoid typing the same flag values repeatedly every time by setting environment variables. | NAME | FLAG | |:-------------------------:|:-----------------------:| | `TDL_NS` | `-n/--ns` | | `TDL_PROXY` | `--proxy` | | `TDL_STORAGE` | `--storage` | | `TDL_DEBUG` | `--debug` | | `TDL_SIZE` | `-s/--size` | | `TDL_THREADS` | `-t/--threads` | | `TDL_LIMIT` | `-l/--limit` | | `TDL_POOL` | `--pool` | | `TDL_NTP` | `--ntp` | | `TDL_RECONNECT_TIMEOUT` | `--reconnect-timeout` | | `TDL_DISABLE_PROGRESS_PS` | `--disable-progress-ps` | | `TDL_TEMPLATE` | dl `--template` | {{< hint warning >}} - `TDL_STORAGE` format in env is different from that in flags: `{"type": "bolt", "path": "/path/to/data-dir"}` (JSON object). {{< /hint >}} --- ### Content/En/More/Troubleshooting --- title: "Troubleshooting" weight: 40 --- # Troubleshooting ## Best Practices How to minimize the risk of blocking? - Login with the official client session. - Use the default download and upload options as possible. Do not set too large `threads` and `size`. - Do not use the same account to login on multiple devices at the same time. - Don't download or upload too many files at once. - Become a Telegram premium user. 😅 ## FAQ #### Q: Why no response after entering the command? And why there is `msg_id too high` in the log? **A:** Check if you need to use a proxy (use `proxy` flag); Check if your system's local time is correct (use `ntp` flag or calibrate system time) If that doesn't work, run again with `--debug` flag. Then file a new issue and paste your log in the issue. #### Q: Desktop client stop working after using tdl? **A:** If your desktop client can't receive messages, load chats, or send messages, you may encounter session conflicts. You can try re-login with `tdl login` and **select YES for logout**, which will delete the session files to separate sessions. #### Q: How to migrate session to another device? **A:** You can use the `tdl backup` and `tdl recover` commands to export and import sessions. See [Migration](/guide/migration) for more details. #### Q: Is this a form of abuse? **A:** No. The download and upload speed is limited by the server side. Since the speed of official clients usually does not reach the account limit, this tool was developed to download files at the highest possible speed. #### Q: Will this result in a ban? **A:** I am not sure. All operations do not involve dangerous actions such as actively sending messages to other people. But it's safer to use a long-term account. --- ### Content/En/Reference/Expr --- title: "Expr Guide" bookHidden: true --- # Expr Guide Expr is powered by [expr](https://github.com/antonmedv/expr), which is a simple, lightweight, yet powerful expression engine. Expression engine docs: https://expr.medv.io/docs/Language-Definition It's powerful but may be a little hard to new users. So feel free to file an issue if you have any questions about the expression engine. ---