Skip to content

Docker 环境下私聊文件发送失败:download_file/base64 可落盘,但 upload_private_file 返回 rich media transfer failed #755

@under-the-ocean

Description

@under-the-ocean

问题描述

在 Docker 部署的 llbot + PMHQ 环境中,OneBot v11 的文件发送相关接口无法成功发送私聊文件。

现象:

  • download_file 可以把文件下载到 llbot 容器内 /app/llbot/data/temp/...
  • upload_private_file 能识别 base64 输入并落盘到 /app/llbot/data/temp/...
  • 但最终发送到 QQ 时失败,报错 rich media transfer failed
  • 直接传 llbot 容器路径给 upload_private_file 时,也可能返回 未知文件类型或路径不存在

已尝试过的方案

我看到其他 issue 中提到过通过修改 Docker volume 映射解决文件路径问题,因此已经按该思路调整过 Docker 映射,使 llbotpmhq 共享关键目录,但问题仍然存在。

当前 compose 关键配置如下:

services:
  pmhq:
    image: docker.1ms.run/linyuchen/pmhq:7.3.2
    privileged: true
    environment:
      - ENABLE_HEADLESS=false
    networks:
      - app_network
    volumes:
      - qq_volume:/root/.config/QQ
      - ./llbot_config:/app/llbot/data:rw
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:13000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  llbot:
    image: linyuchen/llbot:7.12.10
    ports:
      - "3080:3080"
    extra_hosts:
      - "host.docker.internal:host-gateway"
    environment:
      - PMHQ_HOST=pmhq
      - WEBUI_PORT=3080
    networks:
      - app_network
    volumes:
      - qq_volume:/root/.config/QQ
      - ./llbot_config:/app/llbot/data:rw
    depends_on:
      - pmhq
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "sh", "-c", "ps | grep '[n]ode'"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

volumes:
  qq_volume:

networks:
  app_network:
    driver: bridge

也就是说,pmhqllbot 已经共享:

/root/.config/QQ
/app/llbot/data

但仍然无法发送文件。

环境信息

  • llbot 镜像:linyuchen/llbot:7.12.10
  • PMHQ 镜像:docker.1ms.run/linyuchen/pmhq:7.3.2
  • OneBot 版本接口返回:
{
  "app_name": "LLOneBot",
  "protocol_version": "v11",
  "app_version": "7.12.10"
}

复现步骤

1. 使用 base64 发送小文本文件

调用:

{
  "action": "upload_private_file",
  "params": {
    "user_id": 3791129086,
    "file": "base64://SGVsbG8gZnJvbSBBc3RyQm90IGZpbGUgdGVzdC4K",
    "name": "astrbot_file_test.txt"
  }
}

返回失败,但可以看到 llbot 已经把 base64 内容落到本地临时文件:

filePath: /app/llbot/data/temp/fd5a1b91-d8d9-433e-b994-e1b36981271f
fileSize: 30

错误摘要:

rich media transfer failed

2. 使用 download_file 下载文件后再 upload_private_file

先调用:

{
  "action": "download_file",
  "params": {
    "url": "http://192.168.10.11:6185/api/file/send/xxx?download_token=xxx",
    "thread_count": 1
  }
}

返回成功:

{
  "file": "/app/llbot/data/temp/33bb8a19088a4ed77c3ca9f1e6d32e71"
}

然后调用:

{
  "action": "upload_private_file",
  "params": {
    "user_id": 3791129086,
    "file": "/app/llbot/data/temp/33bb8a19088a4ed77c3ca9f1e6d32e71",
    "name": "astrbot_plugin_napcat_llm_tools_v0.3.0.zip"
  }
}

返回失败:

rich media transfer failed

错误中显示 filePath 指向 llbot 本地临时文件,但最终 rich media 发送失败。

3. 直接发送 llbot 侧路径

尝试过以下路径:

/app/llbot/data/temp/webqq-uploads/7cca478a-ab3a-400e-b5a8-a1d3b037cc79.zip
/app/llbot/data/temp/webqq-uploads/7cca478a-ab3a-400e-b5a8-a1d3b037cc79
/app/llbot/data/temp/7cca478a-ab3a-400e-b5a8-a1d3b037cc79.zip
/app/llbot/data/temp/7cca478a-ab3a-400e-b5a8-a1d3b037cc79

返回类似:

未知文件类型或路径不存在

期望行为

在 Docker 环境下,upload_private_file 应该可以发送以下来源的文件:

  1. base64://... 解码后的临时文件
  2. download_file 下载到 /app/llbot/data/temp/... 的文件
  3. llbot 与 pmhq 共享卷中的文件路径

实际行为

文件可以落盘,但发送 QQ 私聊文件时失败:

rich media transfer failed

或者路径检查阶段失败:

未知文件类型或路径不存在

备注

这个问题和上层 Bot 框架无关。上层已经验证:

  • 图片发送正常
  • OCR 正常
  • download_file 能调用并返回 llbot 本地路径
  • base64 输入可被 llbot 解码到本地临时路径

失败集中在 llbot / PMHQ / QQNT 文件富媒体发送阶段。

请问在当前 Docker 架构下,upload_private_file 是否还有额外的路径要求、权限要求,或 PMHQ 侧需要额外挂载/配置?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions