自定义操作

Frame.io 操作提供对常见媒体操作的快速访问权限,如下载、重命名和复制项目,还允许与第三方工具和服务集成,使其直接显示在 Frame.io 的用户界面中。

关于操作

随着自定义操作的推出,开发者可以在 Frame.io V4 中配置和管理自己的操作。自定义操作利用与 Webhook 相同的底层事件系统,为开发者提供了一种替代机制,可以将其资产连接到 Frame.io 帐户中对用户最重要的工具。

操作可以由 Frame.io 工作区中启用该操作的任何成员用户执行。 在执行一项操作时,Frame.io 会将负载发送到您提供的 URL。 接收应用程序使用 HTTP 状态代码响应来确认接收,或使用自定义回调在 Frame.io UI 中渲染其他表单字段。 接收应用程序可以是您自己托管的项目集、服务,甚至是 Workfront Fusion 或 Zapier 等低代码/无代码 IPaaS 工具。

使用自定义操作,可以直接将集成作为可编程的 UI 组件构建到 Frame.io 中。这使工作流程能够利用与 Webhook 相同的底层事件路由,由应用程序内的用户触发。 您可以创建用户触发的单步或多步表单,作为另一个表单或基本响应返回到 Frame.io。 当用户在资产上点击自定义操作时,Frame.io 会将负载发送到您提供的 URL。 接收应用程序使用 HTTP 状态代码响应来确认收到,或使用自定义回调进行响应,该回调可以在 Frame.io 中渲染其他 UI。

V4 中的操作改进

利用从旧版用户吸取的经验,我们在 Frame.io V4 中对操作功能集进行了一些增强:

新字段类型

之前仅限于文本和单选字段,现在我们也支持多选、文本区域(用于更大的文本框)和布尔值字段(用于单选按钮)。

可点击链接

文本字段不方便用户复制/粘贴 URL。 使用我们全新链接字段,即可轻松实现一键复制。

动态模态

根据返回的数据量,您可以信任操作的模态动态调整大小,使其以最佳方式适应表单中的信息,包括在需要时提供可滚动模态。

多资产操作

配置您的操作以在一个请求中定位多达 100 个资产。


新增

混合资产类型

操作不仅限于一种资产类型,还可以跨文件、文件夹和版本堆栈的组合触发。

应用内反馈表单

我们希望了解开发者和最终用户如何使用操作,因此我们在 Web 的设置页面中添加了一个反馈表单。

迁移操作

在将包含之前在旧版 Frame.io 中创建的自定义操作的 Frame.io V4 帐户迁移到该帐户时,需要注意以下几点。

操作状态

帐户迁移到 Frame.io V4 后,在早期版本中创建的所有自定义操作的状态都将为“null”且会自动禁用。 这样,用户就有机会先将操作更新为使用 V4 API 然后再启用,因为任何未更新的操作都将失败。 要识别此状态下的操作,请访问操作设置页面并参考“状态”列,或者如果使用了 API,则检查 is_active 字段。

可操作资源:文件、文件夹和版本堆栈

鉴于在 Frame.io V4 API 中资产类型被分离为独立资源,在解释操作负载中收到的资源 ID 时可能需要考虑某些行为。 单个文件的行为很直接,因为 ID 将反映执行操作的特定文件。 同样,对于文件夹,您将收到执行操作的文件夹 ID;但是,根据您的具体用例,您在定义操作的行为时有多种选择。 如果您想与文件夹资源本身进行交互,请使用文件夹 ID 对 Frame.io API 进行后续调用。 或者,您可能希望获取该文件夹的次项,以便对其中的资产进行进一步处理。 在对版本堆栈执行操作时,您的负载将包含“头部资产”的 ID,它是堆栈中最顶层的文件,也是 Frame.io UI 中显示的内容。

您可以在我们的迁移指南中了解更多关于 Frame.io 旧版 API 和 V4 之间差异的信息。

使用 API 配置自定义操作

自定义操作需要:

字段名称描述
名称您为自定义操作选择的名称。 它将显示在 Frame.io 中可用自定义操作的菜单中。
描述解释操作的作用,以供参考(描述不会显示在 Frame.io Web 应用程序中)。
事件内部事件键,用于帮助您区分标准 Webhook 事件和您自己的事件。
URL事件的传送目标位置。
工作区将使用自定义操作的工作区。

配置您的自定义操作

当用户触发自定义操作时,Frame.io 会将负载发送到您提供的 URL。 接收应用程序可以使用 HTTP 状态代码响应来确认收到,或使用在 Frame.io 中渲染更多 UI 的自定义回调响应。

需要帐户管理员权限才能创建工作区的自定义操作。 如果您没有访问权限,请让您的管理员修改您的权限。

多资产配置

多资产支持由配置驱动,且必须从 Web 端操作的配置模态中明确启用。 这可以在创建新操作期间完成,也可以在更新现有操作时完成。 

启用多资产支持后,负载格式会立即切换。 旧版负载和支持多资产的负载互不兼容。

来自 Frame.io 的负载

当用户单击您的自定义操作时,负载将发送到您在 URL 字段中设置的 URL。 使用此负载来标识:

操作上下文
  • 点击了哪项自定义操作

  • 点击了哪些资源

  • 哪个用户执行了操作

  • 触发了哪种事件类型

组织上下文
  • 哪个帐户与自定义操作关联

  • 哪个工作区与自定义操作关联

  • 哪个项目包含这些资源

自定义操作最初会使用包含一个资产的 resource 对象在每个请求中仅接受一个资产。 启用多资产支持后,负载会使用包含一个或多个资产的 resources 列表(一个请求中最多有 100 个资产)。

1 POST /your/url
2 {
3 "account_id": "1a94720e-f7f5-4c41-ab62-d11eebe3d504",
4 "action_id": "0aeb9feb-f8eb-4100-a8c2-b39b66d354ab",
5 "data": {
6 "description": "Pretty cool video.",
7 "title": "Hey there!"
8 },
9 "interaction_id": "985559de-865a-40e5-a687-2bbed4497eaa",
10 "project": {
11 "id": "3e34e7cb-5c21-49f5-8ca9-a1419584c2ea"
12 },
13 "resources": [
14 {
15 "id": "fe41c5a8-1b8d-417d-a7df-0b88bc19b476",
16 "type": "file"
17 },
18 {
19 "id": "fe81fb2b-1316-4a76-9cf6-0630f474fc39",
20 "type": "file"
21 }
22 ],
23 "type": "some.event",
24 "user": {
25 "id": "68093c1c-4b05-41ce-a3c9-e64d195b1935"
26 },
27 "workspace": {
28 "id": "629086c0-f6aa-4d63-a284-f39bcd415b9f"
29 }
30 }
1 POST /your/url
2 {
3 "account_id": "1a94720e-f7f5-4c41-ab62-d11eebe3d504",
4 "action_id": "0e38b93a-9f10-4bc7-90bc-bd07a16e510a",
5 "data": {
6 "description": "Wow look at this.",
7 "title": "Hey there!!"
8 },
9 "interaction_id": "dff6d369-7150-41f9-8e6f-4f0895f6b416",
10 "project": {
11 "id": "3e34e7cb-5c21-49f5-8ca9-a1419584c2ea"
12 },
13 "resource": {
14 "id": "fe81fb2b-1316-4a76-9cf6-0630f474fc39",
15 "type": "file"
16 },
17 "type": "some.event",
18 "user": {
19 "id": "68093c1c-4b05-41ce-a3c9-e64d195b1935"
20 },
21 "workspace": {
22 "id": "629086c0-f6aa-4d63-a284-f39bcd415b9f"
23 }
24 }

从旧版负载迁移

计划弃用旧版负载

我们已计划弃用旧版负载,强烈建议用户将其服务迁移至处理新的负载。

通过启用配置标志并更新您的负载处理,操作可以无缝过渡以支持多资产负载。

  1. 将单数 resource 对象的用法替换为 resources 列表 2。 更新代码以遍历 resources 列表

  2. 在操作配置中启用多资产标志

字段名称描述
account_id操作的唯一帐户 ID。
action_id操作的唯一 ID。
interaction_idFrame.io 生成的唯一标识符,用于在多个请求中跟踪您的事务,例如链式消息或表单回调。 在操作的每个序列中保持不变。
project_id操作的唯一项目 ID。
resource.id您从中触发操作的资源 ID。
resource.type您从中触发操作的资源类型。
type配置操作时在 event 字段中提供的名称。
user.id触发操作的用户 ID。
workspace.id使用操作的工作区 ID。
data包含表单字段名称和用户选择值的键值对。 您的应用程序会接收此信息,从而了解用户做出的选择。

交互、重试和超时

interaction_id 是用于跟踪交互随时间演变情况的唯一标识符。 如果您不需要响应用户,那么返回 200 状态代码即可。 虽然不是必须的,但我们建议包含操作结果的信息,例如成功消息或错误警报。 自定义操作支持消息回调。

Frame.io 期待在不到 10 秒内得到响应,且在等待成功回复时会最多重试 5 次。 理想情况下会立即响应,异步操作会在通过自定义操作触发后发生。

创建消息回调

在对 Webhook 事件的 HTTP 响应中,您可以返回一个 JSON 对象,描述将在 Frame.io UI 中返回给发起用户的消息。

1{
2 "title": "Success!",
3 "description": "The thing worked! Nice."
4}

消息让您可以直接在 Frame.io UI 中向用户提供反馈。 如果您需要从用户那里收集更多信息,请改用表单回调

创建表单回调

假设您在开始流程之前需要更多信息。 例如,您可能要将内容上传到需要其他详细信息的系统。 您可以在响应中描述表单,用户会填写这个表单并提交回给您。 这里有一个示例:

1{
2 "title": "Need some more info!",
3 "description": "Getting ready to submit this file!",
4 "fields": [
5 {
6 "type": "text",
7 "label": "Title",
8 "name": "title",
9 "value": "MyVideo.mp4"
10 },
11 {
12 "type": "select",
13 "label": "Captions",
14 "name": "captions",
15 "options": [
16 {
17 "name": "Off",
18 "value": "off"
19 },
20 {
21 "name": "On",
22 "value": "on"
23 }
24 ]
25 }
26 ]
27}

当用户提交表单时,您将收到一个事件,发送到与初始 POST 请求相同的 URL 上:

1POST /your/url
2{
3 "type": "your-specified-event-name",
4 "interaction_id": "the-same-id-as-before",
5 "action_id": "unique-id-for-this-custom-action",
6 "data":{
7 "title": "MyVideo.mp4",
8 "captions": "off"
9 }
10}

在表单上添加的所有自定义字段都会显示在 Frame.io 发送的 JSON 负载的 data 部分。 使用 interaction_id 来映射初始请求和此新表单数据。 您可以用消息进行响应,也可以链接另一个表单。 通过链接操作、表单和消息,您可以有效地在 Frame.io 中编写多步骤工作流,并集成来自外部系统的业务逻辑。

表单详情

与消息类似,表单也支持 titledescription 属性,这些属性会显示在表单顶部。 除此之外,每个表单字段还接受以下基础属性:

字段属性
  • type — 告诉 Frame.io UI 期望的数据类型,以及要使用的组件和渲染方式。 * label — 在 UI 中显示为字段上方的标题。
字段数据
  • name — 用于在后续负载中识别该字段的键名。 * value — 用于预填充字段的值。

支持的字段类型

文本字段

无其他参数的简单文本字段。

1{
2 "type": "text",
3 "label": "Title",
4 "name": "title",
5 "value": "MyVideo.mp4"
6}

文本区域

无其他参数的简单文本区域。

1{
2 "type": "textarea",
3 "label": "Description",
4 "name": "description",
5 "value": "This video is really, really popular."
6}

选择列表

定义用户可以从中选择的选择列表。 必须包含一个 options 列表,其中每位成员都应包含一个人类可读的 name 和机器可解析的 value

1{
2 "type": "select",
3 "label": "Captions",
4 "name": "captions",
5 "value": "off",
6 "options": [
7 {
8 "name": "Off",
9 "value": "off"
10 },
11 {
12 "name": "On",
13 "value": "on"
14 }
15 ]
16}

复选框

没有额外参数的简单复选框。

1{
2 "type": "boolean",
3 "name": "enabled",
4 "label": "Enabled",
5 "value": "false"
6}

链接

没有额外参数的简单链接。

1{
2 "type": "link",
3 "name": "videoLink",
4 "label": "Video Link",
5 "value": "https://www.youtube.com/watch?v=XtX1zv9CEVc"
6}

Frame.io 权限模型

自定义操作具有特殊的权限模型:它们属于工作区,而不属于帐户中存在的任何特定用户。 这意味着:

创建和管理
  • 任何管理员都可以在工作区上创建自定义操作。

  • 任何管理员都可以修改或删除团队上存在的自定义操作。

实时更新
  • 一旦修改,所有用户都会立即看到更改的结果。

安全性和验证

默认情况下,所有自定义操作在创建期间都会生成一个签名密钥。 此项不可配置。 此密钥可用于验证请求是否来自 Frame.io。 POST 请求中包含以下内容:

名称描述
X-Frameio-Request-Timestamp您的自定义操作被触发的时间。
X-Frameio-Signature计算得出的签名。
时间戳验证

时间戳是请求在离开 Frame.io 网络时被签名的时间。 这可用于防止重放攻击。 我们建议验证此时间与本地时间相差是否在 5 分钟以内。

签名验证

签名是使用首次创建自定义操作时提供的签名密钥的 HMAC SHA-256 哈希值。

验证签名

1

提取签名

从 HTTP 标头中提取签名。

2

创建要签名的消息

通过合并版本、交付时间和请求体 v0:timestamp:body 来创建一个用于签名的消息。

3

计算 HMAC SHA256

使用您的签名密钥计算 HMAC SHA256 签名。

4

比较签名

将您计算的签名与提供的签名进行比较!

提供的签名以 v0= 为前缀。 目前 Frame.io 只有这一种用于请求签名的版本。 您需要在计算的签名中添加此前缀。

Python
1import hmac
2import hashlib
3
4def verify_signature(curr_time, req_time, signature, body, secret):
5 """
6 Verify webhook/custom action signature
7 :Args:
8 curr_time (float): Current epoch time
9 req_time (float): Request epoch time
10 signature (str): Signature provided by the frame.io API for the given request
11 body (str): Custom Action body from the received POST
12 secret (str): The secret for this Custom Action that you saved when you first created it
13 """
14 if int(curr_time) - int(req_time) < 500:
15 message = 'v0:{}:{}'.format(req_time, body)
16 calculated_signature = 'v0={}'.format(hmac.new(
17 bytes(secret, 'latin-1'),
18 msg=bytes(message, 'latin-1'),
19 digestmod=hashlib.sha256).hexdigest())
20 if calculated_signature == signature:
21 return True
22 return False

反馈

我们很乐意听取开发者和最终用户的意见,了解你们希望如何在 Frame.io V4 中使用操作。 请务必联系我们,提出您的问题、想法和用例,从而帮助我们确定优先级。