Webhook 答卷数据推送
监听某个问卷下的答卷事件。 开启了 Webhook 推送的问卷,在特定事件发生时,会以 POST 方法向指定的一个或多个 URL 发送 HTTP 请求,同时带上请求头为 application/json 类型的 JSON 格式数据。
目前支持的事件:
action | 说明 |
---|---|
answer.create | 用户提交答卷 |
answer.update | 用户/管理员修改答卷 |
answer.delete | 管理员删除答卷 |
若有支持其他类型事件的需求,请联系我们。
#
配置步骤进入问卷编辑页面,点击左上角“设置”,在“回收设置”一栏找到“Webhook”,点击右侧的“设置”,打开 Webhook 设置页;
点击“新建 Webhook”,根据提示填写配置项,“URL”为请求的目标地址,需要为公网可访问的 HTTP/HTTPS 服务地址。后续会增加可选的密钥项目用于校验。(目标地址不能含有
xip.io
,@
,端口号且不能是内网地址)勾选【启用推送】,点击【确定】按钮,即完成配置。此时问卷服务器将会主动推送一个测试请求,供检查使用。
#
数据格式字典#
答卷数据#
通用格式说明{ "id": "33cc555f-056f-4242-a97c-46f3e7d2016f", // uuid "object": "Answer", // 对象 "action": "answer.create", // 事件 "created_at": "2021-01-26 14:00:00", // 推送时间 "payload": { // 问卷编号 "survey_id": 5356056,
// 回答编号 "answer_id": 7,
// 问卷系统中回答者身份ID,非真实 QQ 号 "respondent_id": 60000000001, // 回答者登录类型(微信/QQ/企业微信/手机等) "respondent_type": "",
// 自定义字段 (非微信OpenID,废弃字段) "openid": "",
// 用户开始答卷的时间 "started_at": "2020-02-09 11:55:30", // 用户提交答卷的时间 "ended_at": "2020-02-09 11:58:39", // 回答时长(秒) "duration": 189,
// 地理位置信息 "country": "中国", // 国家或地区 "province": "广东省", // 省份 "city": "深圳市", // 城市
// 客户端信息 "ip": "127.0.0.1", // 答题 IP 地址 "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148", // 浏览器信息 "referrer": "https://wj.qq.com/xxx.html", // 进入答题页的来源地址
// 第三方用户信息(仅第三方对接场景下使用,参考 https://wj.qq.com/docs/openapi/sso/create_user 使用) "third_party_user": { "respondent_id": 60000000001, // 问卷系统中回答者身份ID,接口注册用户时由问卷系统自动生成 "openid": "abcdefg", // 第三方用户标识,接口注册用户时由使用方传入 "nickname": "张三" // 第三方用户昵称,接口注册用户时由使用方传入 },
// 用户的回答详情 "answer": [ // 每个问卷的结构不一样,结构也会有所出入,实际数据结构以实际推送的为准 ] }}
参数 | 说明 |
---|---|
id | uuid |
object | 对象 |
action | 行动 |
created_at | 推送时间 |
payload | 具体内容 |
payload.survey_id | 问卷ID |
payload.answer_id | 答卷ID |
payload.qq | 用户在腾讯问卷的标识(非QQ号) |
payload.openid | 非微信OpenID,废弃字段 |
payload.weixin_openid | 用户在腾讯问卷的微信 OpenID (默认为空) |
payload.started_at | 用户开始回答的时间 |
payload.ended_at | 用户提交答卷的时间 |
payload.answer | 用户的回答详情(含有自定义参数) |
payload.score | 用户回答的分数(仅旧版测评题有值,新版考试问卷请使用获取考试成绩接口) |
payload.third_party_user | 第三方用户信息(特定使用,关联第三方系统对接) |
signature | 用于校验的签名(暂不提供) |
#
payload.answer 说明[ { "id": "p-1-ib8x", // 第一页 "questions": [ { "id": "q-1-IFMp", // 题目ID "type": "radio", // 题目类型 - 单选题 "options": [ { "id": "o-100-ABCD", // 回答ID "checked": 1, // 选中 "text": "<p>选项</p>\n" // 回答内容 } ] }, { "id": "q-2-EcPa", "type": "select", // 题目类型 - 下拉题 "options": [ { "id": "o-101-EFGH", "checked": 1, "text": "选项" } ] }, { "id": "q-3-9K6v", "type": "checkbox", // 题目类型 - 多选题 "options": [ { "id": "o-100-ABCD", "checked": 1, "text": "<p>选项</p>\n" } ] }, { "id": "q-4-Ksi9", "type": "text", // 题目类型 - 单行文本 "text": "123" }, { "id": "q-5-k7p1", "type": "textarea", // 题目类型 - 多行文本 "text": "123123\n123123" }, { "id": "q-6-pZzn", "type": "star", // 题目类型 - 量表题 "text": "5" }, { "id": "q-7-JNkO", "type": "matrix_radio", // 题目类型 - 矩阵单选 "groups": [ { "id": "g-1-ABCD", "options": [ { "id": "o-101-EFGH", "checked": 1, "text": "<p>选项</p>\n" } ] }, { "id": "g-2-EFGH", "options": [ { "id": "o-101-EFGH", "checked": 1, "text": "<p>选项</p>\n" } ] } ] }, { "id": "q-8-a5nI", "type": "matrix_checkbox", // 题目类型 - 矩阵多选 "groups": [ { "id": "g-1-ABCD", "options": [ { "id": "o-100-ABCD", "checked": 1, "text": "<p>选项</p>\n" }, { "id": "o-101-EFGH", "checked": 1, "text": "<p>选项</p>\n" } ] }, { "id": "g-2-EFGH", "options": [ { "id": "o-100-ABCD", "checked": 1, "text": "<p>选项</p>\n" }, { "id": "o-101-EFGH", "checked": 1, "text": "<p>选项</p>\n" } ] } ] } ] }, { "id": "p-2-ohuS", "questions": [ { "id": "q-9-VDhO", "type": "matrix_star", // 题目类型 - 矩阵量表 "groups": [ { "id": "g-1-ABCD", "text": "5" }, { "id": "g-2-EFGH", "text": "5" } ] }, { "id": "q-10-SZMU", "type": "sort", // 题目类型 - 排序题 "options": [ { "id": "o-101-EFGH", "sort_no": 1 }, { "id": "o-100-ABCD", "sort_no": 2 } ] }, { "id": "q-11-vtGs", "type": "chained_selects", // 题目类型 - 联动题 "id_list": [ "2-AK", "3-nV", "4-qA" ], "text_list": [ "1", "2", "3" ] }, { "id": "q-12-MBer", "type": "upload", // 题目类型 - 附件题 "expired": "7d", // 链接有效时间为7天 "url": "", // 弃用,目前支持多附件,请使用 files 字段 "files": [{ "name": "图片1.png", "url": "https://xxx.png" },{ "name": "图片2.png", "url": "https://yyy.png" }] }, { "id": "q-14-Xlvy", "type": "text_multiple", // 题目类型 - 填空题 "blanks": [ { "id": "fillblank-WPph", "value": "wj.qq.com" } ] },
// 疫情申报问卷,获取上传的健康码及图片识别结果 { "id": "q-10-Zr6w", "type": "upload", "expired": "7d", // 链接有效时间为7天 "files": [{ "name": "核酸检测.png", "url": "https://zzz.png" }], }, { "id": "q-9-fRX5-ret", "type": "radio", "options": [{ "id": "o-102-FEAS", "text": "异常", // 目前仅返回【正常/异常】 "checked": 1 }] } ] }, { "id": "custom_args", // 自定义参数 "questions": [ { "id": "custom-arg-01", // 自定义参数ID "type": "text", // 类型 "text": "123", // 内容 "title": "userid", // 自定义参数 key 值 "description": "用户ID,传递用户身份信息" // 自定义参数描述 } ] }]
#
服务端调试示例下面以 PHP
开发语言为示例:
<?php // 接受请求参数 $event = json_decode(file_get_contents("php://input"));
// 写入文件 $myfile = fopen("wj.qq.com.log", "w") or die("Unable to open file!"); fwrite($myfile, json_encode($event)); fclose($myfile);
查看 wj.qq.com.log 内容是否接收到相关测试请求数据,例如下面:
{ "id": "ac3a878b-3ada-4f00-a052-fb60c33414de", // uuid "object": "webhook", // 对象 "action": "webhook.test", // 行动 "created_at": "2021-01-26 14:49:39", // 推送时间}
#
重试机制服务端接受 Webhook 内容成功后,应在5秒钟内返回 HTTP 状态码 200,否则将视为推送失败。推送失败的 Webhook 事件将会进入重试队列,最多重试 7 次。
重试规则如下:
- 第一次重试,首次失败后 2 分钟
- 第二次重试,首次失败后 10 分钟
- 第三次重试,首次失败后 30 分钟
- 第四次重试,首次失败后 1 小时
- 第五次重试,首次失败后 2 小时
- 第六次重试,首次失败后 6 小时
- 第七次重试,首次失败后 15 小时
#
安全#
检测 Webhook 请求是否来自腾讯问卷Webhook 请求时将从一批 IP 地址发起请求,接收端可用于校验请求是否可信。请通过 IP 列表接口获取。