Webhook API
使用方法: Labvanced外部数据存储Webhook API的主要用例是将参与者数据“实时”传输到外部/远程服务器,而不是将记录的数据托管在Labvanced服务器上。
请注意: 与许多API用例相反,这里描述的内容并不是如何调用Labvanced API/端点(目前不存在这种功能),而是您必须如何配置/实现您的后端,以使我们的平台能够自动调用您实现的端点,将参与者数据直接发送到您的后端/数据库,而不是我们的。
可用性: 此功能仅对Labvanced实验室许可证持有者可用。
1. 设置Webhook API
要使用Webhook API,您首先必须在“实验功能”部分的相应Labvanced研究的“研究设置”中激活“外部数据存储”选项。
1.1 参数:
- IP地址: 输入您的静态IP地址,外部服务器正在运行/可公开访问。
- 端口: 应用来发送数据的端口
- URL路径: 应该在端口后附加的URL路径。这对于对您的项目/传入数据进行“命名空间”特别有用,以便来自不同实验的数据发送到不同的URL路径。URL路径是可选的,但我们强烈建议使用它。
2. 创建接收Webhook API数据的服务器/脚本
根据第1步中的设置,您必须实现一个在指定的IP地址、端口和URL路径上可用的服务器。这样的服务器的简化版本/示例可以在我们的Github页面找到。
2.1 数据格式: 数据以JSON格式发送,除了“/file_upload”路由之外。 “/file_upload”路由(用于上传二进制文件,例如录制的视频或音频)编码为“multipart/form-data”,因此请确保您正确解析传入数据为JSON或multipart/form-data /二进制数据。
2.2 CORS设置: 在实现您的后端时,您必须实现/允许跨域资源共享(CORS)。尤其是,您必须设置以下标头:“Access-Control-Allow-Origin”(包括 https://www.labvanced.com/), “Access-Control-Allow-Methods”(包括POST和OPTIONS), “Access-Control-Allow-Headers”(包括Content-Type)
2.3 请求类型: 所有请求类型都是POST请求,因为它们用于发送数据。在此时,仅“/file_upload”路由需要返回值。所有其他路由不需要特殊的返回值。
2.4 请求/路由类型: 每当参与者参加研究时,方将发送总共8种不同类型的POST请求到(外部/您的)服务器。仅在您的研究中包含上传录制的二进制数据(例如音频或视频)的操作时,才会使用“/file_upload”路由。每种类型的POST请求都有不同的路由(URL路径),将在第1步中附加到指定的URL路径。此外,每种类型的请求都有不同的结构/有效负载,这在解析和存储数据时应考虑。详见第3节。
3. Webhook API端点定义/路由:
在下面,您将看到参与者参加实验时使用/调用的每个路由/端点的详细说明。理想情况下,我们建议您实现所有这些端点(除了3.1),确保所有数据都被适当地解析和存储在您的数据库中。
哪些端点被使用,何时调用哪个服务器?
- 端点3.1 “/startExpPlayer”仅发送到Labvanced服务器,以加载实验定义/ JSON文件和相关刺激。
- 端点3.2、3.3、3.4、3.7和3.8同时发送到Labvanced服务器(用于组平衡和一般实验流所需)和外部/您的服务器。
- 端点3.5和3.6仅发送到外部/您的服务器。请注意,所有试验/参与者数据通过路由3.6发送,因此这是最重要的端点需要实现。
- 端点3.9仅发送到外部/您的服务器,并在每次执行“上传操作”以上传二进制(音频或视频)数据时调用。
3.1 加载实验
- 路由: /startExpPlayer
- 类型: POST
- 调用时: 当参与者访问 labvanced.com 上的某个实验URL时。Lavanced服务器上的主要功能:初始化实验的加载。
- 有效负载: JSON,包含以下字段:
字段名称 | 描述 | 数据类型 | 必需 |
---|---|---|---|
expId | 研究的唯一标识符 | 整数 | 是 |
isTestrun | 数据是否被记录 | 布尔 | 否 |
subject_code | 通过URL参数识别的主题 | 字符串 | 否 |
token | 一种用于纵向研究中参与者的唯一标识符 | Token identifier | 否 |
askSubjData | 是否显示初始调查,用于将主题分入不同组 | 布尔 | 是 |
注意: 不需要在外部服务器上实现,因为这只初始化从Labvanced服务器到客户端计算机的实验加载
3.2 组和会话选择
- 路由: /startFirstPlayerSession
- 类型: POST
- 调用时: 路由3.1“/startExpPlayer”从Labvanced服务器成功返回时。
- Lavanced服务器上的主要功能: 用于将组和会话编号分配给参与者(服务器侧平衡)。
- 有效负载: JSON,包含以下字段:
字段名称 | 描述 | 数据类型 | 必需 |
---|---|---|---|
expId | 研究的唯一标识符 | 整数 | 是 |
expSessionNr | 该参与者录制会话的唯一标识符(向上计数) | 字符串 | 是 |
subject_code | 通过URL参数识别的主题 | 字符串 | 否 |
token | 一种用于纵向研究中参与者的唯一标识符 | Token identifier | 否 |
survey_data | 前研究问卷的JSON,字段在下面描述。 | JSON | 否 |
survey_data.selectedGender | 参与者选择的性别 | 字符串 | 否 |
survey_data.selectedAge | 参与者选择的年龄 | 整数 | 否 |
survey_data.selectedCountry | 参与者选择的国家/位置 | 字符串 | 否 |
survey_data.selectedLanguage | 参与者选择的(第一)语言 | 字符串 | 否 |
isTestrun | 数据是否被记录 | 布尔 | 是 |
runOnlyGroupNr | 仅用于测试运行某个特定组编号而不进行数据记录 | 整数 / 假 | 否 |
runOnlySessionNr | 仅用于测试运行某个特定会话编号而不进行数据记录 | 整数 / 假 | 否 |
groupNr | 对于该主题的组编号 | 整数 | 是 |
sessionNr | 纵向研究中的会话编号 | 整数 | 是 |
group_name | 对于该主题的组的名称 | 字符串 | 是 |
session_name | 对于该主题的会话的名称 | 字符串 | 是 |
experiment_name | 实验名称(不是出版名称) | 字符串 | 是 |
3.3 实验开始
- 路由: /setPlayerSessionStartedTime
- 类型: POST
- 调用时: 当参与者按下“开始实验”时
- Lavanced服务器上的功能: 保存实验的开始时间、会话和组名,并开始实验。
- 有效负载: JSON,包含以下字段:
字段名称 | 描述 | 数据类型 | 必需 |
---|---|---|---|
expId | 研究的唯一标识符 | 整数 | 是 |
expSessionNr | 该参与者录制会话的唯一标识符(向上计数) | 字符串 | 是 |
start_time | 实验的开始时间 | UNIX时间戳 | 是 |
sessionNr | 纵向研究中的会话编号 | 整数 | 是 |
groupNr | 对于该主题的组编号 | 整数 | 是 |
token | 一种用于纵向研究中参与者的唯一标识符 | Token identifier | 否 |
3.4 添加元数据
- 路由: /addMetaInfo
- 类型: POST
- 调用时: 当参与者按下“开始实验”时
- Lavanced服务器上的功能: 在服务器上保存元信息。
- 有效负载: JSON,包含以下字段:
字段名称 | 描述 | 数据类型 | 必需 |
---|---|---|---|
expId | 研究的唯一标识符 | 整数 | 是 |
expSessionNr | 该参与者录制会话的唯一标识符(向上计数) | 字符串 | 是 |
var_data | 包含元信息的JSON | JSON | 是 |
var_data.browserSpec | 参与者使用的浏览器 | 字符串 | 否 |
var_data.versionSpec | 参与者使用的浏览器版本 | 字符串 | 否 |
var_data.systemSpec | 参与者使用的设备类型/操作系统 | 字符串 | 否 |
var_data.agentSpec | 完整的用户代理字符串 | 字符串 | 否 |
var_data.fullscreen | 表示研究是否始终全屏 | 布尔 | 否 |
var_data.timeDelayMean | JavaScript回调精度均值偏移(毫秒) | 浮点 | 否 |
var_data.timeDelayStd | JavaScript回调精度标准偏差(毫秒) | 浮点 | 否 |
var_data.crowdsourcingCode | 参与者的众包/完成代码 | 字符串 | 否 |
var_data.crowdsourcinSubjId | 参与者的众包/工人ID | 字符串 | 否 |
var_data.subjCounterGlobal | 研究中参与者的全局计数器 | 整数 | 否 |
var_data.subjCounterPer Group | 研究中每组的参与者计数器 | 整数数组 | 否 |
var_data.roleId | 多用户研究的参与者唯一角色ID | 整数 | 否 |
var_data.multiUserGroupId | 多用户研究的全局唯一多用户组ID | Uuid | 否 |
var_data.displayedLanguage | 多语言研究中选择的显示语言 | 字符串 | 否 |
var_data.pixelDensityPerMM | 屏幕的像素密度 | 浮点 | 否 |
var_data.screenHeight | 屏幕的高度(像素) | 整数 | 否 |
var_data.screenWidth | 屏幕的宽度(像素) | 整数 | 否 |
var_data.windowHeight | 窗口/视口高度(像素) | 整数 | 否 |
var_data.windowWidth | 窗口/视口宽度(像素) | 整数 | 否 |
3.5 记录任务信息
- 路由: /recordStartTask
- 类型: POST
- 调用时: 实验流程中开始一个新任务时
- Lavanced服务器上的功能: 当启用外部API请求时不被调用
- 有效负载: JSON,包含以下字段:
字段名称 | 描述 | 数据类型 | 必需 |
---|---|---|---|
expId | 研究的唯一标识符 | 整数 | 是 |
expSessionNr | 该参与者录制会话的唯一标识符(向上计数) | 字符串 | 是 |
blockNr | 当前块编号(递增计数器) | 整数 | 是 |
blockId | 当前块的唯一ID | Uuid | 是 |
blockName | 块的名称 | 字符串 | 是 |
taskNr | 当前任务编号(递增计数器) | 整数 | 是 |
taskId | 当前任务在编辑器中定义的ID(在参与者之间相同) | Uuid | 是 |
recTaskId | 当前录音任务的服务器生成ID(在参与者之间不同) | 整数 | 是 |
taskName | 当前任务的名称 | 字符串 | 是 |
start_time | 任务的开始时间 | UNIX时间戳 | 是 |
3.6 记录试次数据
- 路由: /recordTrial
- 类型: POST
- 调用时: 试次完成或执行自定义记录操作时
- Lavanced服务器上的功能: 当启用外部API请求时不被调用。
- 有效负载: JSON,包含以下字段:
字段名称 | 描述 | 数据类型 | 必需 |
---|---|---|---|
expId | 研究的唯一标识符 | 整数 | 是 |
expSessionNr | 该参与者录制会话的唯一标识符(向上计数) | 字符串 | 是 |
recTaskId | 当前录音任务的服务器生成ID(在参与者之间不同) | 整数 | 是 |
taskId | 当前任务在编辑器中定义的ID(在参与者之间相同) | Uuid | 是 |
trailNr | 试次编号 | 整数 | 是 |
recData | 其他主要数据/每个试次创建的所有用户变量存储在此 | JSON | 是 |
注意: 每个试次记录的数据的确切内容取决于具体实验和任务。每项研究的概述可以在具体实验的“变量”选项卡下找到(见截图)。还请注意,外部API变量名称将在JSON结构中用作键。因此,请确保变量名称是唯一的。否则您将覆盖数据。Labvanced系统通常要求用户使用唯一的变量名称。
3.7 成功完成实验
- 路由: /finishExpSession
- 类型: POST
- 调用时: 实验成功完成时
- Lavanced服务器上的功能: 完成研究并将数据集标记为已完成(对平衡很重要)。
- 有效负载: JSON,包含以下字段:
字段名称 | 描述 | 数据类型 | 必需 |
---|---|---|---|
expId | 研究的唯一标识符 | 整数 | 是 |
expSessionNr | 该参与者录制会话的唯一标识符(向上计数) | 字符串 | 是 |
end_time | 实验结束的时间 | UNIX时间戳 | 是 |
var_data | 与“/addMetaInfo”路由中的var数据相同(已更新信息) | JSON | 是 |
nextStartTime | 下一个开始时间(仅适用于纵向研究) | UNIX时间戳 | 否 |
nextEndTime | 下一个结束时间(仅适用于纵向研究) | UNIX时间戳 | 否 |
reminderTime | 下一个开始时间之前的时间(仅适用于纵向研究) | 时间字符串 | 否 |
selectedEmail | 发送参与提醒的邮件(仅适用于纵向研究) | 电子邮件地址 | 否 |
emailReminder | 何时发送提醒(仅适用于纵向研究) | 字符串 | 否 |
3.8 实验失败
- 路由: /errExpSession
- 类型: POST
- 调用时: 实验以错误终止
- Lavanced服务器上的功能: 中止研究并将数据集标记为不完整
- 有效负载: JSON,包含以下字段:
字段名称 | 描述 | 数据类型 | 必需 |
---|---|---|---|
expId | 研究的唯一标识符 | 整数 | 是 |
expSessionNr | 该参与者录制会话的唯一标识符(向上计数) | 字符串 | 是 |
err_msg | 错误消息 | 字符串 | 是 |
3.9 上传二进制(音频或视频)数据
- 路由: /file_upload
- 类型: POST
- 调用时: 在与某些音频或视频录制对象相关联的事件系统中执行上传操作时。 Lavanced服务器上的功能:当启用外部API请求时不被调用。
- 注意: 服务器必须为此路由发送返回值(如下所述)。如果不这样做,“onUploadComplete”触发器将不会执行,实验将无法正确传播。还要注意,此路由中的数据编码为“multipart/form-data”,因为它同时包含二进制和非二进制数据。
- 有效负载: JSON,包含以下字段:
字段名称 | 描述 | 数据类型 | 必需 |
---|---|---|---|
expSessionNr | 该参与者录制会话的唯一标识符(向上计数) | 字符串 | 是 |
newFileName | 建议的文件名,用于存储文件。文件名包括相关变量名称,以及当前块、任务和试次编号。 | 字符串 | 是 |
myFile | 实际文件/二进制数据 | 二进制 | 是 |
所需响应:
字段名称 | 描述 | 数据类型 | 必需 |
---|---|---|---|
file_guid | 记录文件的全局唯一标识符(guid)。必须在服务器端生成,并将保存与文件相关联的变量,以便后来容易理解哪个文件来自哪个录制对象。 | Uuid | 是 |
file_name | 服务器用于保存文件的结果文件名。它可以(但不一定)与客户端在请求中建议的文件名相同。这也将存储在关联变量中。 | 字符串 | 是 |