You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift(Vapor)下Telegram API发送文档失败及大文件发送咨询

问题描述

在Linux服务器上使用Swift结合Vapor框架开发Telegram Bot时,执行以下代码尝试通过URL发送文档:

代码片段

let handler16 = TGMessageHandler(filters: .regexp(pattern: "^11$")) {update, bot in
    if let id = update.message?.chat.id {
        let chatId: TGChatId = .chat(id)
    //    let file = File(data: "hello", filename: "МЭСК.docx")
        let params: TGSendDocumentParams = .init(chatId: chatId, document: .url("http://www.ncbi.nlm.nih.gov/geo/download/?acc=GSE46130&format=file"))
        try bot.sendDocument(params: params)
    }
}

错误信息

Type: server Description: Response marked as not Ok, it seems something wrong with request
Code: 400
Bad Request: failed to get HTTP URL contentReason:

现咨询如何正确保存并发送自有大文档,已知Telegram服务器上的文件可通过FileInfo.fileId("file_id")发送且无限制,但不清楚自有大文件的处理方式。


解决方案

一、URL发送失败的原因

你使用的NCBI链接大概率存在以下问题,导致Telegram服务器无法正常获取内容:

  • 链接带有反爬机制或需要身份验证,Telegram的请求被拦截
  • 链接返回的内容不是标准可识别的文档格式
  • 链接跳转逻辑复杂,Telegram无法正确解析

二、自有大文件的正确处理方式

针对自有大文件(通常指超过Telegram直接上传限制的文件,一般为50MB以上,以官方API规则为准),可按以下方式处理:

1. 本地文件直接上传(中等大小文件适用)

如果文件在Telegram直接上传限制内(50MB以内),可直接读取服务器本地文件构造File对象发送:

let handler16 = TGMessageHandler(filters: .regexp(pattern: "^11$")) {update, bot in
    guard let id = update.message?.chat.id else { return }
    let chatId: TGChatId = .chat(id)
    
    // 读取服务器本地的目标文件
    guard let fileURL = URL(fileURLWithPath: "/path/to/your/large/document.docx"),
          let fileData = try? Data(contentsOf: fileURL) else {
        // 处理文件读取失败的逻辑
        return
    }
    let file = File(data: fileData, filename: "custom_document_name.docx")
    let params = TGSendDocumentParams(chatId: chatId, document: .file(file))
    
    try bot.sendDocument(params: params)
}

2. 分片上传(超大文件适用)

如果文件超过直接上传限制,需使用Telegram的分片上传API(uploadFile接口),步骤如下:

  • 将大文件分割为若干5MB以内的分片(建议每个分片5MB)
  • 依次上传每个分片,获取对应上传凭证
  • 所有分片上传完成后,调用sendDocument组合分片信息完成发送

3. 上传一次复用file_id(最高效方案)

无论文件大小,可先将自有文件上传到Telegram服务器一次,获取对应的file_id,之后即可通过FileInfo.fileId无限制复用发送:

// 首次上传获取file_id(可在Bot初始化或单独脚本中执行)
let testChatId: TGChatId = .chat(your_test_chat_id)
let fileURL = URL(fileURLWithPath: "/path/to/your/large/file")!
let fileData = try Data(contentsOf: fileURL)
let file = File(data: fileData, filename: "large_file.docx")
let uploadParams = TGSendDocumentParams(chatId: testChatId, document: .file(file))
let uploadResponse = try bot.sendDocument(params: uploadParams)
let savedFileId = uploadResponse.result?.document?.fileId ?? "" // 将此file_id持久化存储

// 后续发送直接使用file_id
let handler16 = TGMessageHandler(filters: .regexp(pattern: "^11$")) {update, bot in
    guard let id = update.message?.chat.id else { return }
    let chatId: TGChatId = .chat(id)
    let params = TGSendDocumentParams(chatId: chatId, document: .fileId(savedFileId))
    try bot.sendDocument(params: params)
}

注意事项

  • 确保Linux服务器上的目标文件有可读权限,避免读取失败
  • 分片上传需严格遵循Telegram API的分片规则,否则会上传失败
  • 持久化存储file_id时,建议存入数据库或配置文件,避免重复上传

内容的提问来源于stack exchange,提问作者Pablo Juan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 20:31:14