项目
版本

Uppy 伴侣应用

伴侣是一个开源服务器应用程序,它消除了身份验证的复杂性,并减轻了从远程源(如 Instagram、Google Drive 等)下载文件的成本。伴侣是一个服务器到服务器的协调器,它从源流式传输文件到目标,且文件从未在伴侣中存储。伴侣可以作为独立(自托管)应用程序运行,Transloadit 托管,或插入选定应用程序作为 Express 中间件。Uppy 客户端向伴侣请求远程文件,伴侣会下载并同时上传到您的 Tus 服务器AWS 桶 或任何支持 PUT、POST 或 Multipart 上传 的服务器。

这意味着用户从 Google Drive 用手机上传 5GB 的视频时,不会消耗他们的数据计划,而你也不必担心实现 OAuth。

我应该何时使用它?

如果你想要让用户从 BoxDropboxFacebookGoogle DriveGoogle 相册InstagramOneDriveUnsplash从 URL 导入Zoom 下载文件 —— 你需要伴侣应用。

伴侣支持与 Uppy 相同的 上传器TusAWS S3常规 multipart 。但与手动设置插件不同,Uppy 会发送一个带有上传器的头部,伴侣将在服务器上使用相同的头部。这意味着如果你正在为本地上传使用 Tus ,你可以将远程上传发送到同一个 Tus 服务器(对于 AWS S3 桶也是一样)。

托管

使用 Transloadit 服务附带了一个托管版本的伴侣,因此你不必担心自己托管服务器。无论你是在免费还是付费的 Transloadit 计划 中,都可以使用伴侣。没有 Transloadit 计划,无法租用伴侣服务器。

注册(免费)计划

安装和使用

伴侣通过 npm 安装。根据你如何运行伴侣,安装过程略有不同。伴侣可以作为中间件集成到你的 Express 应用中,也可以作为一个独立服务器运行。大多数人可能希望将其作为一个独立服务器运行,而中间件可用于进一步自定义伴侣或将其集成到你自己的 HTTP 服务器代码中。

目前 Windows 不是支持的平台。它可能可以工作,我们很乐意接受这方面的改进,但我们无法提供支持。

独立模式

如果你想要将伴侣作为自己的 Node.js 进程运行,可以使用独立版本。它是一个配置好的 Express 服务器,具有会话、日志记录和最佳安全实践。通常,你首先想要全局安装它:

npm install -g @uppy/companion

独立伴侣始终提供 HTTP(非 HTTPS),并在生产环境中期望有一个反向代理进行 SSL 终止。有关更多信息,请参阅 COMPANION_PROTOCOL ( 服务器 )。

伴侣随附一个可执行文件(bin/companion),即独立服务器。与中间件版本不同,选项是通过环境变量设置的。

查看 选项 以了解 JS 和环境变量格式中的可用选项。

你至少需要这三个来开始:

export COMPANION_SECRET="shh!Issa Secret!"
export COMPANION_DOMAIN="YOUR SERVER DOMAIN"
export COMPANION_DATADIR="PATH/TO/DOWNLOAD/DIRECTORY"

然后运行:

companion

你还可以传递 JSON 配置文件的路径,如下所示:

companion --config /path/to/companion.json

你可能还想在 PM2 这样的进程管理器中运行伴侣,以确保在崩溃时重新启动,以及允许扩展到多个实例。

Express 中间件模式

首先,使用你喜欢的包管理器将其安装到你的 Node.js 项目中:

npm install @uppy/companion

要将伴侣插入现有服务器,调用其 .app 方法,将一个 选项 对象作为参数传递。这返回一个服务器实例,你可以将其挂载在 Express 应用的路由上。

import express from "express";
import bodyParser from "body-parser";
import session from "express-session";
import companion from "@uppy/companion";

const app = express();

// 伴侣需要body-parser和express-session中间件。
// 如果你的应用程序中使用这些,请这样添加。
//
// 如果你的应用程序中使用其他东西,你可以在与伴侣相同的子路径下
// 添加这些中间件,例如 app.use('/companion', companionApp)
app.use(bodyParser.json());
app.use(session({ secret: "some secrety secret" }));

const companionOptions = {
  providerOptions: {
    drive: {
      key: "GOOGLE_DRIVE_KEY",
      secret: "GOOGLE_DRIVE_SECRET",
    },
  },
  server: {
    host: "localhost:3020",
    protocol: "http",
    // 默认安装通常不需要路径。
    // 但是,如果你指定了`path`,你必须在下面的`app.use()`中指定相同路径,
    // 例如:app.use('/companion', companionApp)
    // path: '/companion',
  },
  filePath: "/path/to/folder/",
};

const { app: companionApp } = companion.app(companionOptions);
app.use(companionApp);

伴侣 Companion 使用 WebSocket 与客户端通信,向客户端发送进度、错误和成功信息。这是 Uppy 监听并更新其内部状态和 UI 的方式。

通过 companion.socket 函数添加伴侣 Companion 的 WebSocket 服务器:

const server = app.listen(PORT);

companion.socket(server);

如果 WebSocket 因某种原因失败,Uppy 和 Companion 将回退到 HTTP 轮询。

运行多个实例

我们建议在生产环境中至少运行两个实例,以防某个请求阻塞了 Node.js 事件循环(由于 bug 或流量激增),这样也不会阻塞或减慢所有其他请求(因为 Node.js 是单线程的)。

例如,Transloadit 的一位企业客户自托管了 Companion 来支持一项全球多所大学使用的教育服务,他们部署了 7 个 Companion 实例。而他们之前的解决方案运行在 35 个实例上。根据我们的经验,Companion 会在商品虚拟服务器(如 c5d.2xlarge )的网络接口卡饱和之前耗尽其他资源。

你的使用情况可能有所不同,所以我们建议添加可观测性。你可以让 Prometheus 爬取 /metrics 端点,并用 Grafana 绘制图表。

使用唯一端点

一种选择是运行多个具有各自独特端点的实例。这些端点可以是不同的端口、子域名或 IP。在这种设置下,你可以:

  1. 实现自己的逻辑,通过设置 companionUrl 选项将每个上传定向到特定的 Companion 端点。
  2. 设置 Companion 选项 COMPANION_SELF_ENDPOINT 。这个选项会使 Companion 响应包含 COMPANION_SELF_ENDPOINT 值的 i-am HTTP 头。当 Uppy 看到这个头时,它会将所有上传请求固定到该端点。

无论哪种情况,你通常还会配置一个单独的 Companion 实例(一个端点)来处理所有 OAuth 身份验证请求,这样你只需要指定一个 OAuth 回调 URL。参见 oauthDomainvalidHosts

使用负载均衡器

另一种选择是在多个 Companion 实例前设置负载均衡器。然后 Uppy 只看到一个单一的端点,并将所有请求发送到关联的负载均衡器,后者再将请求分发给 Companion 实例。Companion 实例通过 Redis 协调消息和事件,以便任何实例都可以处理客户端的请求。注意,这种设置不需要粘性会话。以下是这种设置的要求:

  • 实例需要连接到同一个 Redis 服务器。
  • 在两台服务器上将 COMPANION_SECRET 设置为相同的值。
  • 如果你使用 companionKeysParams 功能(Transloadit),则需要在每个实例上将 COMPANION_PREAUTH_SECRET 设置为相同。
  • 所有其他配置应相同,除非你在同一台机器上运行多个实例,那么每个实例的 COMPANION_PORT 应不同。

API

选项

默认配置

const options = {
  server: {
    protocol: "http",
    path: "",
  },
  providerOptions: {},
  s3: {
    endpoint: "https://{service}.{region}.amazonaws.com",
    conditions: [],
    useAccelerateEndpoint: false,
    getKey: (req, filename) => `${crypto.randomUUID()}-${filename}`,
    expires: 800, // 秒
  },
  allowLocalUrls: false,
  logClientVersion: true,
  periodicPingUrls: [],
  streamingUpload: false,
  clientSocketConnectTimeout: 60000,
  metrics: true,
};

filePath COMPANION_DATADIR

提供者文件将临时下载到的完整目录路径。

secret COMPANION_SECRET COMPANION_SECRET_FILE

Companion 用于生成授权令牌的密钥字符串。你应该生成一个长的随机字符串。例如:

const crypto = require("node:crypto");

const secret = crypto.randomBytes(64).toString("hex");

preAuthSecret COMPANION_PREAUTH_SECRET COMPANION_PREAUTH_SECRET_FILE

如果你使用 TransloaditcompanionKeysParams功能(使用你自己的自定义 OAuth 凭据的 Transloadit 托管的 Companion),将此变量设置为一个强大的随机生成的密钥。也参见 COMPANION_SECRET(但不要使用相同的密钥!)

oauthOrigin COMPANION_OAUTH_ORIGIN

此选项用于指定允许的 域(Origin),或是一个域数组(在 COMPANION_OAUTH_ORIGIN 中以逗号分隔的域)。任何来自未列出域的浏览器请求都将无法接收 OAuth2 令牌,并且 OAuth 请求将无法完成。将其设置为 '*' 以允许所有域(不推荐)。默认值:'*'

uploadUrls COMPANION_UPLOAD_URLS

一个允许列表(字符串数组)或正则表达式。Companion 只接受这些 URL 的上传。这确保你的 Companion 实例只被允许向你的受信任服务器上传,防止 SSRF 攻击。

COMPANION_PORT

独立服务器启动时使用的端口,默认为 3020。这是一个仅适用于独立模式的选项。

COMPANION_COOKIE_DOMAIN

允许您自定义为 Express 会话创建的 cookies 的域。这是一个仅适用于独立模式的选项。

COMPANION_HIDE_WELCOME

将其设置为 true 可禁用在 / 路径显示的欢迎消息。这是一个仅适用于独立模式的选项。

redisUrl COMPANION_REDIS_URL

运行中的 Redis 服务器的 URL。这可以用于使用多个实例水平扩展 Companion。参见 [如何扩展 Companion]。

COMPANION_REDIS_EXPRESS_SESSION_PREFIX

connect-redis 创建的 Redis 键设置自定义前缀。默认值为 sess:。会话用于存储认证状态以及通过 Companion 从浏览器加载缩略图。如果在同一 Redis 服务器上运行了多个不同应用,你可能希望更改此设置,因为很难知道 sess: 来自何处,可能会与其他应用冲突。**注意:**将来我们计划将默认值更改为 companion:,并可能删除此选项。这是一个仅适用于独立模式的选项。也请参阅 COMPANION_REDIS_PUBSUB_SCOPE

redisOptions

一个支持 redis 客户端选项 的对象。此选项可以替代 redisUrl 使用。

COMPANION_REDIS_PUBSUB_SCOPE

在 Redis 服务器上为 Companion 事件使用范围。设置此选项将使用提供的名称和冒号前缀所有事件。也请参阅 COMPANION_REDIS_EXPRESS_SESSION_PREFIX

server

基础服务器的配置选项。

键/环境变量 描述
protocol COMPANION_PROTOCOL httphttps 用于构建引用 Companion 实例本身的 URL,用于头和饼干。Companion 本身始终作为 HTTP 服务器运行,因此本地应使用 http。在生产环境中为您的域名启用 SSL/HTTPS(通过在 Companion 前面运行反向 https 代理,或使用托管服务的内置 HTTPS 功能)后,必须将其设置为 https
host COMPANION_DOMAIN 字符串 您服务器的公共主机名(例如 example.com)。
oauthDomain COMPANION_OAUTH_DOMAIN 字符串 如果您有多个具有不同(可能是动态)子域的 Companion 实例,可以设置一个单一固定子域和服务器(如 sub1.example.com),以处理您的 OAuth 身份验证。然后,这将在完成时将您重定向回正确的实例,并提供所需的凭据。这样,您只需为 OAuth 提供商配置一个回调 URL。
path COMPANION_PATH 字符串 Companion 应用程序所在的服务器路径。例如,如果 Companion 位于 example.com/companion,则路径为 /companion
implicitPath COMPANION_IMPLICIT_PATH 字符串 如果您的反向代理 URL 路径与 express 应用中的 Companion 路径不同,则需要设置此路径为 implicitPath。例如,如果 Companion 的 URL 是 example.com/mypath/companion。其中 /mypath 在您的 NGINX 服务器中定义,而 /companion 在您的 express 应用中设置。那么您需要将 implicitPath 选项设置为 /mypath,并将 path 选项设置为 /companion
validHosts COMPANION_DOMAINS 数组 如果设置了 oauthDomain,则需要设置一个有效的主机列表,以便 OAuth 处理器可以验证请求身份验证的 Uppy 实例的主机。这基本上是一个运行 Companion 实例的有效域列表。列表也可以包含正则表达式模式。例如 ['sub2.example.com', 'sub3.example.com', '(\\w+).example.com']

sendSelfEndpoint COMPANION_SELF_ENDPOINT

这实质上与 server.host + server.path 属性相同。设置此属性的主要原因是,当设置时,它会在每个响应请求的 i-am 头中添加该值。

providerOptions

一个用于启用提供商及其密钥和秘密的对象。例如:

{
  "drive": {
    "key": "***",
    "secret": "***"
  }
}

在使用独立版本时,您可以使用相应的环境变量或指向秘密文件(如 COMPANION_GOOGLE_SECRET_FILE)。

服务 环境变量
Box box COMPANION_BOX_KEY, COMPANION_BOX_SECRET, COMPANION_BOX_SECRET_FILE
Dropbox dropbox COMPANION_DROPBOX_KEY, COMPANION_DROPBOX_SECRET, COMPANION_DROPBOX_SECRET_FILE
Facebook facebook COMPANION_FACEBOOK_KEY, COMPANION_FACEBOOK_SECRET, COMPANION_FACEBOOK_SECRET_FILE
Google Drive drive COMPANION_GOOGLE_KEY, COMPANION_GOOGLE_SECRET, COMPANION_GOOGLE_SECRET_FILE
Google Photos googlephotos COMPANION_GOOGLE_KEY, COMPANION_GOOGLE_SECRET, COMPANION_GOOGLE_SECRET_FILE
Instagram instagram COMPANION_INSTAGRAM_KEY, COMPANION_INSTAGRAM_SECRET, COMPANION_INSTAGRAM_SECRET_FILE
OneDrive onedrive COMPANION_ONEDRIVE_KEY, COMPANION_ONEDRIVE_SECRET, COMPANION_ONEDRIVE_SECRET_FILE, COMPANION_ONEDRIVE_DOMAIN_VALIDATION(设置此变量为 true 可启用一个可用于验证您的应用的 OneDrive 路由)
Zoom zoom COMPANION_ZOOM_KEY, COMPANION_ZOOM_SECRET, COMPANION_ZOOM_SECRET_FILE, COMPANION_ZOOM_VERIFICATION_TOKEN

s3

Companion 配备了 AWS S3 的签名端点。Uppy 客户端可以使用这些端点对直接上传到 S3 的请求进行签名,而不必在浏览器中暴露秘密 S3 密钥。Companion 还支持直接从 Dropbox 和 Instagram 等提供商上传文件到 S3。

s3.key COMPANION_AWS_KEY

S3 访问密钥 ID。

s3.secret COMPANION_AWS_SECRET COMPANION_AWS_SECRET_FILE

S3 私有访问密钥。

s3.endpoint COMPANION_AWS_ENDPOINT

自定义 S3(兼容)服务的可选 URL。否则使用 AWS SDK 的默认值。

s3.bucket COMPANION_AWS_BUCKET

要存储上传文件的桶的名称。

它可以是返回桶名称的 string 函数,并接受以下参数:

  • http.IncomingMessage,HTTP 请求(对于远程上传将是 null
  • 用户为文件提供的元数据(对于本地上传将是 undefined

s3.forcePathStyle COMPANION_AWS_FORCE_PATH_STYLE

这增加了设置 S3 客户端的 forcePathStyle 选项的支持。在开发环境中与 Uppy/Companionlocalstack 一同使用时,这是必要的。默认值为:false

s3.region COMPANION_AWS_REGION

目标桶所在的数据中心区域。

COMPANION_AWS_PREFIX

所有上传键的可选前缀。这是一个仅适用于独立模式的选项。使用 express 中间件时,可以通过 getKey 选项实现相同功能。

s3.awsClientOptions

可以在 providerOptions.s3.awsClientOptions 对象中提供任何 AWS SDK 支持的 S3 选项除了 以下选项:

  • accessKeyId。相反,请使用 providerOptions.s3.key 属性。这是为了使 Companion 不同功能的配置名称保持一致。
  • secretAccessKey。相反,请使用 providerOptions.s3.secret 属性。这是为了使 Companion 不同功能的配置名称保持一致。

请注意,某些选项可能会因与 Companion 的假设冲突而导致错误行为。如果您发现特定选项不按预期工作,请在 Uppy 的存储库中 打开一个问题,以便我们可以在此记录。

s3.getKey(req, filename, metadata)

获取文件的键名。键是文件在存储桶中上传的路径。此选项应为一个接收三个参数的函数:

  • reqhttp.IncomingMessage,对于使用 @uppy/aws-s3 插件的常规 S3 上传的 HTTP 请求。此参数对于使用 @uppy/aws-s3@uppy/aws-s3-multipart 插件的分片上传不可用。对于远程上传,此参数为 null
  • filename,上传文件的原始名称;
  • metadata,用户为文件提供的元数据。

该函数应返回一个字符串 keyreq 参数可用于将文件上传到存储桶中与用户特定的文件夹,例如:

app.use(authenticationMiddleware);
app.use(
  uppy.app({
    providerOptions: {
      s3: {
        getKey: (req, filename, metadata) => `${req.user.id}/${filename}`,
        /* 认证选项 */
      },
    },
  })
);

默认实现返回 filename ,因此所有文件将被上传到存储桶的根目录并保留其原始文件名。

app.use(
  uppy.app({
    providerOptions: {
      s3: {
        getKey: (req, filename, metadata) => filename,
      },
    },
  })
);

在客户端签名时,此函数仅对分片上传调用。

COMPANION_AWS_USE_ACCELERATE_ENDPOINT

启用 S3 Transfer Acceleration。这是一个独立选项。

COMPANION_AWS_EXPIRES

设置预签名 URL 中的 X-Amz-Expires 查询参数(以秒为单位,默认:300)。这是一个独立选项。

COMPANION_AWS_ACL

为上传的对象设置 预定义的 ACL 。这是一个独立选项。

customProviders

此选项允许您添加自定义提供商,以及已经支持的提供商。更多信息,请参阅 添加自定义提供商

logClientVersion

一个布尔标志,告诉 Companion 是否在启动时记录其版本。

metrics COMPANION_HIDE_METRICS

一个布尔标志,告诉 Companion 是否提供一个带有 Prometheus 指标的 /metrics 端点(默认情况下,指标是启用的)。

streamingUpload COMPANION_STREAMING_UPLOAD

一个布尔标志,告诉 Companion 是否启用流式上传。如果启用,它将导致更快的上传,因为 Companion 将在下载的同时开始上传使用 stream.pipe 。如果 false ,文件将首先完全下载,然后上传。默认为 false ,但建议启用,尤其是当您预期上传大文件时。在未来版本中,默认值可能会更改为 true

maxFileSize COMPANION_MAX_FILE_SIZE

如果设置了此值,Companion 将限制要处理的最大文件大小。如果没有设置,它将处理任何大小限制的文件(这是默认值)。

periodicPingUrls COMPANION_PERIODIC_PING_URLS

如果设置了此值,Companion 将定期向指定的 URL 发送 POST 请求。这对于跟踪 Companion 实例作为心跳很有用。

periodicPingInterval COMPANION_PERIODIC_PING_INTERVAL

周期性 ping 请求的间隔(以毫秒为单位)。

periodicPingStaticPayload COMPANION_PERIODIC_PING_STATIC_JSON_PAYLOAD

一个可以 JSON.stringify 化的 JavaScript 对象,将作为周期性 ping 请求的 JSON 主体发送。

allowLocalUrls COMPANION_ALLOW_LOCAL_URLS

一个布尔标志,告诉 Companion 是否允许请求本地 URL(非互联网 IP)。

corsOrigins COMPANION_CLIENT_ORIGINS

允许的 CORS 源(默认为 true )。作为 corsorigin 选项传递。

COMPANION_CLIENT_ORIGINS_REGEX

类似于 COMPANION_CLIENT_ORIGINS ,但允许使用单个正则表达式。如果使用此选项,将忽略 COMPANION_CLIENT_ORIGINS 。这是一个独立选项。

chunkSize COMPANION_CHUNK_SIZE

控制 AWS S3 Multipart 和 Tus 上传的块大小。较小的值会导致更多的开销,但较大的值在网络连接不好的情况下会导致较慢的重试。传递给 tus-js-client 的 chunkSize,以及 AWS S3 MultipartpartSize

enableUrlEndpoint COMPANION_ENABLE_URL_ENDPOINT

将其设置为 false 以禁用 URL 功能 。默认:true

事件

companion.app() 返回的对象还有一个属性 companionEmitter ,它是一个 EventEmitter ,发出以下事件:

  • upload-start - 当上传开始时,发出一个包含属性 token 的对象,它是上传的唯一 ID。
  • token - 事件名称是 upload-start 中的令牌。事件具有以下属性:
    • action - 以下字符串之一:
      • success - 当上传成功时。
      • error - 当上传因错误而失败时。
    • payload - 错误或成功负载。

使用 EventEmitter 处理完成的文件上传的示例代码:

const companionApp = companion.app(options);
const { companionEmitter: emitter } = companionApp;

emitter.on("upload-start", ({ token }) => {
  console.log("上传开始", token);

  function onUploadEvent({ action, payload }) {
    if (action === "success") {
      emitter.off(token, onUploadEvent); // 避免监听器泄露
      console.log("上传完成", token, payload.url);
    } else if (action === "error") {
      emitter.off(token, onUploadEvent); // 避免监听器泄露
      console.error("上传失败", payload);
    }
  }
  emitter.on(token, onUploadEvent);
});

常见问题

有实时示例吗?

一个示例服务器正在运行于 https://companion.uppy.io

认证和令牌机制是如何工作的?

本节描述了 Companion 和提供者之间的认证工作原理。虽然这种行为对所有提供者(Dropbox、Instagram、Google Drive 等)都相同,但在此部分我们将以 Dropbox 代替任何提供者。

以下是用户通过 Companion 使用 Dropbox 进行认证和上传时发生的步骤:

  • 网站上的访问者点击 “连接到 Dropbox”。
  • Uppy 向 Companion 发送请求,后者向 Dropbox 发送 OAuth 请求(需要在 Companion 中添加 Dropbox 的 OAuth 凭据)。
  • Dropbox 会提示访问者登录,并询问是否允许网站访问您的文件。
  • 如果访问者同意,Companion 将从 Dropbox 收到一个令牌,我们可以用它临时下载文件。
  • Companion 使用密钥加密令牌并将其发送给 Uppy(客户端)。
  • 每当访问者在 Uppy 中点击文件夹时,都会向 Companion 请求新文件列表,并随请求发送加密的令牌。
  • Companion 解密令牌,请求 Dropbox 中的文件列表,并将其发送给 Uppy。
  • 当选择文件进行上传时,Companion 会按照此流程再次接收令牌,再次解密,然后从 Dropbox 下载文件。
  • 伴奏者收到字节后,将字节上传到最终目的地(根据配置:Apache、Tus 服务器、S3 存储桶等)。
  • Companion 向 Uppy 报告进度,就像本地上传一样。
  • 完成!

如何使用提供者重定向 URI?

在相应的开发平台上(例如 Google 开发者控制台)生成提供者的 API 密钥时,您需要提供一个 redirect URI 用于 OAuth 授权过程。一般来说,每个提供者的重定向 URI 格式如下:

http(s)://$YOUR_COMPANION_HOST_NAME/$PROVIDER_NAME/redirect

例如,如果您的 Companion 服务器托管在 https://my.companion.server.com 上,则 OneDrive 提供者的重定向 URI 将是:

https://my.companion.server.com/onedrive/redirect

请参阅 [支持的提供者] 查看所有提供者及其对应的名称列表。

如何在 Kubernetes 中使用 Companion?

我们有一个详细的指南,关于如何在 Kubernetes 中运行 Companion:Kubernetes

如何添加自定义提供者?

目前,Companion 支持 [此处列出的提供者] ,但您也可以选择添加自己的自定义提供者。您可以通过在调用 Uppy app 方法时传递 customProviders 选项来实现。自定义提供者应支持 OAuth 1 或 2 用于身份验证/授权。

import providerModule from "./path/to/provider/module";

const options = {
  customProviders: {
    myprovidername: {
      config: {
        authorize_url: "https://mywebsite.com/authorize",
        access_url: "https://mywebsite.com/token",
        oauth: 2,
        key: "***",
        secret: "***",
        scope: ["read", "write"],
      },
      module: providerModule,
    },
  },
};

uppy.app(options);

customProviders 选项应是一个包含每个自定义提供者的对象。每个自定义提供者反过来是一个包含两个键的对象:configmoduleconfig 选项将包含 OAuth API 设置,而 module 将指向提供者模块。

为了与 Companion 兼容,module 必须是一个具有以下方法的类。请注意,这些方法必须是 async 的,返回 Promise 或以 Error 拒绝:

  1. async list ({ token, directory, query }) - 返回一个包含用户文件列表的对象(例如特定目录中所有文件的列表)。请参阅 返回的列表数据结构示例token - 与请求一起发送的授权令牌(从 OAuth 过程中获取)

    • directory - 要从中检索数据的目录的 ID/名称。如果这不适用于您的提供者,可以忽略。
    • query - 服务器接收到的 expressjs 查询参数对象(以防您需要其中的数据)。
  2. async download ({ token, id, query }) - 从提供者下载特定文件。返回一个具有单一属性 { stream } 的对象 - 一个 stream.Readable,将从该流读取并上传到目的地。为了避免内存泄漏,请确保在拒绝此方法时释放您的流。

    • token - 与请求一起发送的授权令牌(从 OAuth 过程中获取)。
    • id - 正在下载的文件的 ID。
    • query - 服务器接收到的 expressjs 查询参数对象(以防您需要其中的数据)。
  3. async size ({ token, id, query }) - 作为 Number 返回需要下载的文件的字节大小。如果对象的大小未知,可以返回 null

    • token - 与请求一起发送的授权令牌(从 OAuth 过程中获取)。
    • id - 正在下载的文件的 ID。
    • query - 服务器接收到的 expressjs 查询参数对象(以防您需要其中的数据)。

该类还必须具有:

  • 一个唯一的 static authProvider 字符串属性 - 一个表示要使用的 grant(OAuth2 提供者)的小写值(例如,对于 Google,为 google)。如果您的提供者不使用 OAuth2,您可以省略此属性。
  • 一个静态属性 static version = 2,这是 Companion 提供者 API 的当前版本。

参考 示例代码,自定义提供者

列表数据

{
	// 用户名或访问的提供者账户的电子邮件
	"username": "johndoe",
	// 目录中的文件和文件夹列表。如果主要用作包含子项的集合,则视为文件夹
	"items": [
		{
			// 是否为文件夹的布尔值
			"isFolder": false,
			// 图标图像URL
			"icon": "https://random-api.url.com/fileicon.jpg",
			// 项目名称
			"name": "myfile.jpg",
			// 项目的MIME类型。仅在项目不是文件夹时相关
			"mimeType": "image/jpg",
			// 项目的ID(字符串)
			"id": "uniqueitemid",
			// 缩略图图像URL。仅在项目不是文件夹时相关
			"thumbnail": "https://random-api.url.com/filethumbnail.jpg",
			// 对于文件夹,这通常是将在list(...)方法中传递的值。对于文件,这是将在download(...)方法中传递的id。
			"requestPath": "file-or-folder-requestpath",
			// 项目最后修改的日期时间字符串(ISO 8601 格式)
			"modifiedDate": "2020-06-29T19:59:58Z",
			// 项目大小(以字节为单位)。仅在项目不是文件夹时相关
			"size": 278940,
			"custom": {
				// 可能包含更多自定义字段的对象,您可能需要将其发送到客户端。仅当有需求时添加此对象。
				"customData1": "the value",
				"customData2": "the value"
			}
			// 更多项目在这里
		}
	],
	// 如果“items”列表分页,这是获取下一页所需的请求路径
	"nextPagePath": "directory-name?cursor=cursor-to-next-page"
}

如何本地运行 Companion?

  1. 要为本地开发设置 Companion,请克隆 Uppy 存储库并安装,如下所示:

    git clone https://github.com/transloadit/uppy
    cd uppy
    yarn install
    
  2. 通过复制 .env.example.sh 文件到 .env.sh 并编辑为正确的值来配置环境变量。

    cp .env.example .env
    $EDITOR .env
    
  3. 要启动服务器,运行:

    yarn run start:companion
    

这将在 http://localhost:3020 上运行 Companion 实例。它使用 nodemon ,因此当文件更改时会自动重启。

在本文档中