协作中的 Webhook
您可以定义一个 URL,我们将在每次文档更改时调用它。这对于在您自己的应用程序中获取 Yjs 文档的 JSON 表示是非常有用的。
当文档保存到我们的数据库时,我们会调用您的 webhook URL。此操作具有 2-10 秒的防抖延迟。因此,我们不会淹没您的应用程序。目前,我们仅导出 Yjs 文档的 default 片段。
配置 Webhooks
要为文档和评论通知配置 webhooks,您可以按照以下步骤操作:
- 导航到您账户中的 协作设置。
- 找到 webhooks 部分并添加您希望的端点 URL。
添加 URL 后,webhook 会立即生效。您将开始接收指定事件的通知,无需任何延迟。
为您的 webhook 添加评论支持
如果您想为评论功能添加 webhook 支持,并且您的文档服务器是在 2024 年 3 月之前创建的,请按照 下面的说明 升级您的 webhook。
示例有效载荷
所有请求到您的 webhook URL 的请求将包含一个名为 X-Hocuspocus-Signature-256 的头,它使用您的密钥对整个消息进行签名。您可以在您的 Tiptap Collab 应用的 设置 中找到该密钥。
{
"appName": "", // 您的文档服务器名称
"name": "", // 文档名称(如果需要,经过 URI 编码)
"time": 0, // 当前时间的 ISO 字符串(Date.getTime())
"tiptapJson": {}, // 来自 Tiptap 的 JSON 输出(见 https://tiptap.dev/guide/output#option-1-json): TiptapTransformer.fromYdoc()
"ydocState"?: {}, // 可选,包含整个 yDoc 的 base64 编码。此项可在运行时配置中启用(见 https://tiptap.dev/docs/collaboration/operations/configure 中的 `webhook_include_ydoc_state`)
"clientsCount": 100,// 当前连接客户端数量
"type": "", // 有效载荷类型(如果文档已更改,则为 DOCUMENT);仅在您使用 webhooks v2 时可用
"trigger": "", // 触发事件的原因(通常是 "document.saved");仅在您使用 webhooks v2 时可用
"users": [] // 自上一个 webhook 以来更改内容的用户列表(JWT 的 "sub" 字段)
}重试
默认情况下,webhooks 不会重试,但您可以通过将 webhook_retries 设置为 1 来启用重试(见 配置运行时)。
重试计划如下:
- 第一次重试:初次尝试后 5 秒
- 第二次重试:上一次尝试后 15 秒
- 第三次重试:上一次尝试后 2 分钟
- 第四次重试:上一次尝试后 10 分钟
- 第五次重试:上一次尝试后 30 分钟
- 第六次重试:上一次尝试后 3 小时
所有重试都包含一个头 X-Hocuspocus-Retry,其中包含当前的重试计数。有效载荷中的 time 属性是初始尝试的时间戳。
启用评论 webhook
支持评论的 webhook 自动为所有在 2024 年 3 月之后创建账户的用户启用。
如果您的账户是在 2024 年 3 月之前创建的,并且您正在使用旧版本的 webhook 系统,则需要手动启用新的评论 webhook。操作方法如下:
- 如果您已经实现了之前的协作 webhook,请确保在处理传入 webhooks 时检查
type和trigger字段。 - 导航到您账户中的 协作设置。
- 找到 Webhook 部分并点击“更新”按钮。
此升级是为了适应多个新事件路由到同一个 webhook 端点的引入,由新的 type 和 trigger 字段区分。
如果您不希望使用评论 webhook,则无需进行升级。
加载器 Webhook
为了初始化文档,您可以使用 webhook_loader_url 设置(见 配置运行时)。如果请求新的文档,将调用此 URL。
该 webhook 将包含一个头 Authorization,其中包含您的密钥,以及一个 document-name,其中包含请求文档的名称。
如果您返回一个 yjs 更新(在您的端使用 Y.encodeStateAsUpdate),它将应用于文档。如果您返回其他内容,文档将以空文档初始化。 请注意,加载器 webhook 仅在文档创建时调用一次。
觉知 Webhooks
如果您希望在用户连接到或断开与文档的连接时收到通知,可以在 这里 启用觉知 Webhooks。
如果您需要用户参数,请确保将其传递给 TiptapCollabProvider,如 这里 所述。
事件如下所示:
{
"trigger": "user.connected", // 或者 user.disconnected
"user": "user_1",
"numConnectedUsers": 0,
"appName": "",
"name": "testdocument",
"time": "2025-04-21T19:32:55.632Z",
"type": "DOCUMENT"
}版本 Webhooks
当创建新版本时,会向您配置的 webhook URL 发送一个 version.created webhook。有效载荷包含版本的元数据,包括自动生成的 __tiptap 元数据。
{
"trigger": "version.created",
"type": "DOCUMENT",
"appName": "",
"name": "testdocument",
"time": "2026-03-09T12:00:00.000Z",
"version": 5,
"versionName": "版本名称",
"meta": {
"__tiptap": {
"trigger": "websocket",
"changesBy": ["#user1", "#user2"],
"triggeredBy": "user1"
},
"wordCount": 4523
}
}关于 meta.__tiptap 字段的更多细节,请参见 自动版本元数据。
自定义字段
如果您在 Yjs 中使用自定义字段,可以通过在 运行时配置 中设置 webhook_include_fields=1 将它们添加到 webhook。
为了让我们识别 yjs 字段的正确类型,您需要在 Tiptap Typemap 中配置它们。
// 在 Yjs 中存储任何数据。参见官方文档:https://docs.yjs.dev/api/shared-types
// 这里的 "config" 可以替换为任何字符串。map 给您一个键值存储。
const ydoc = new Y.Doc()
ydoc.getMap('config').set('mycustomoption', 'value123');
// 在 provider 中,您需要告诉我们 yjs 类型。
// 我们目前支持的可能选项有:map、array、text、xmlfragment、xmlelement
const provider = new TiptapCollabProvider({document: ydoc})
provider.setFieldType('config', 'map');