牛客网API介绍
- 该文档基于牛客网API
和牛客网API通讯协议V2改写。接口调用协议没有发生变化。
- 线下测试环境域名为: https://dapi.nowcoder.com ,线上正式环境域名为: https://api.nowcoder.com
- 请注意所有请求都需要带上 /v1 前缀
接口协议及规范
接口支持https传输协议,URL接口遵循RESTful相关设计规范。如果使用HTTP协议调用,接口会尝试将请求重定向。
牛客网api验证与授权基于标准OAuth2.0。使用牛客网开放平台API接口之前,请先获取与账号相关联的apiKey
与token
。
具体获取方式为登录牛客网企业版后,点击设置->账户设置->查看API KEY
来查看apiKey
与token
,
若未显示出token
可以刷新页面重试。
名称 | 格式 | 描述 |
---|---|---|
apiKey | String | 标识唯一调用者的Key,这里传参使用api_key |
token | String | 基于OAuth2.0的token值,使用时加前缀 "Bearer " |
请求头
如无特殊说明,非GET请求的请求头中应带有
Content-Type:application/x-www-form-urlencoded
调用每个接口时,需要带上
Authorization
请求头。Authorization
为接口调用时,必须要加上的请求头。其值基于OAuth2.0获得的账号专属的Token值,用于给每个请求添加签名验证。Token值格式为"Bearer ${token}"
,token
在需登录牛客网企业版获取。
名称 | 格式 | 描述 |
---|---|---|
Authorization | String | 基于OAuth2.0的Token值 |
请求参数
- 调用每个接口时,需要带上
api_key
参数;
api_key
为接口调用时必须要带上的参数,其值为apiKey
需登录牛客网企业版获取。在使用Postman执行HTTP请求时,
GET请求的这个参数需要放在Query Params
中,其他类型请求的这个参数需要放在Body
中的x-www-form-unlencoded
中,
值得注意的是,除了api_key
之外,接口的特异化参数也需要按照这个规则传参。
名称 | 格式 | 描述 |
---|---|---|
api_key | String | 标识唯一调用者的Key |
- 多个参数的传递。
某些接口需要传递多个参数,比如在批量创建考生时,就需要传多个考生的信息。对于这种情况,我们需要知道HTTP请求是可以传递键值重复的参数的,
在调用接口时,需要要顺序一次将多个参数填入,比如a=1&a=3&a=3
。在需要传递多个对象形式的参数时,调用接口时可以这样处理:
v1=1&v2=1&v1=2&v2=2
,在牛客服务中,我们使用数组来处理重复参数,参数的在数组中的顺序与HTTP请求时传入的顺序相同。在批量创建考生的场景下,
对于多个考生的不同信息,比如:姓名和考号,我们会同时循环两个数组。分别从每个数组的固定位置取出姓名和考号,组成一个考生信息。最后如果信息无误,才会执行后面的操作。
而调用方在传递参数时,只需按考生顺序,传递所有考生的信息即可,比如:name=user1&key=key1&name=user2&key=key2
,
具体示例可参考添加考生接口。
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import java.util.regex.Matcher;
public class IsPhone {
/**
* 是不是手机号
*/
public static boolean isPhone(String s) {
if (StringUtils.isBlank(s)) {
return false;
}
boolean containLeft = s.contains("(");
boolean containRight = s.contains(")");
if (!(containLeft == containRight)) {
return false;
}
String phone = s.trim().replace("+", "").replace("(", "").replace(")", "");
if (phone.startsWith("86")) {
phone = phone.substring(2);
}
if (phone.length() < 3) {
return false;
}
if (!NumberUtils.isDigits(phone)) {
return false;
}
if (isNativePhonePrefix(phone.substring(0, 3)) && !isOverSeaPhonePreFix(s)) {
// +153076137580 这个是海外手机,但是去掉+,会被判断是国内手机开头,所以加上isOverSeaPhonePreFix判断
return phone.length() == 11;
} else {
//如果是数字而又不是国内手机号,返回true
return true;
}
}
public static boolean isNativePhonePrefix(String prefix) {
java.lang.String regexMobile = "^1([3-9][0-9])$";
java.util.regex.Pattern p = java.util.regex.Pattern.compile(regexMobile);
Matcher m = p.matcher(prefix.trim());
return m.matches();
}
public static boolean isOverSeaPhonePreFix(String s) {
if (!s.startsWith("+")) {
return false;
}
if (s.startsWith("+86")) {
return false;
}
return true;
}
}
- 牛客手机号的校验规则
- 如果是国内手机号在符合正则表达式:
^1([3-9][0-9])\d{8}$
的基础上,手机号开头可以不带"+86"
,带上的话和后面手机号之间不能有空格如: +8615205201314 - 如果是国外手机号需包含
+
和国际地区前缀号码,如:+93701234567
- 如果是国内手机号在符合正则表达式:
import org.apache.commons.lang3.StringUtils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class IsEmail {
public static Pattern emailPattern =
Pattern.compile("^([a-zA-Z0-9_\\+\\.-])+@(([a-zA-Z0-9-])+\\.)+([a-zA-Z0-9]{2,8})");
/**
* 是不是邮箱
*/
public static boolean isEmail(String email) {
if (StringUtils.length(email) <= 40 && StringUtils.length(email) > 0) {
Matcher matcher = emailPattern.matcher(email);
return matcher.matches();
} else {
return false;
}
}
}
- 牛客邮箱的校验规则
需要符合正则表达式:^([a-zA-Z0-9_+.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,8})
且字符长度不超过40个。校验逻辑见java
代码示例。
接口回应
- 接口返回格式
如无特殊说明,接口采用json格式来描述返回信息且接口返回头中带有Content-Type: application/json
,
比如:{"code":0,"msg":"OK","data": 接口返回信息}
,code=0
在业务上表示成功;code!=0
在业务上表示失败,msg
中为具体错误信息。
data
字段可能为空,它的数据结构可能是字符串、数字、json
对象等。data
具体的内容见接口文档。
- 时间格式返回字段
如无特殊说明,接口中返回的时间均为unix时间戳(毫秒级)
- 接口是否正常工作
接口没有返回200
且code!=0
可以视为发生了异常。异常绝大部分是传参不合法,比如请求了不存在的资源、参数传递出现了问题。
接口有可能在传参异常时返回4xx
,4xx
错误通常可以在返回的json中msg
处获取出错原因。若出错原因无法直接解读,可以联系我们。
如果出现了5xx
错误,请联系我们。
建议非200
情况下打印出牛客网返回的完整response
,其中40x
错误建议将msg
中信息在界面中展示给用户,方便用户处理。
- 常见错误:
{"code" : 999,"msg" : "缺少认证参数","details" : null}
这个报错信息代表接口授权失败,需要检查api_key
参数和Authorization
请求头是否传递正确。
- 问题反馈
如果认为接口出现了问题。在向牛客技术反馈问题需提供如下信息:账号id、接口地址、接口入参、调用时间、牛客返回的完整response
。
示例代码
示例代码提供了HTTP接口的调用样例。目前提供了shell和Java语言示例代码。点击右侧的shell
标签或java
标签即可查看。
示例代码,用于帮助开发者快速理解牛客api调用规范。代码仅供测试用。
shell示例代码
shell
代码示例提供了接口的curl
调用示例。开发者替换脚本中的api_key
参数和Authorization
校验头即可进行接口调用。
除此之外,代码示例中还包含了以json
形式表示的接口的返回数据结构。
java示例代码
java
代码示例提供了在Java程序中调用的示例。
为了消除重复代码,简化代码示例代码逻辑,示例代码中使用了NowcoderApiRequestUtils
工具类对HTTP调用过程进行了封装。示例代码中仅保留了接口地址和请求参数信息。
NowcoderApiRequestUtils
工具类和文档中的代码示例均托管在gitee。
下载代码至本地即可调试。
示例代码下载地址:https://gitee.com/nowcoder-guokaijun/nowcoder-api-http-call-demo/tree/master
下面是代码主要结构介绍
ConfigUtils
类
该类为牛客网企业版账户配置类,需要该类中的将TODO
标注的配置改为开发者自己账户的配置。
全局配置类
public class ConfigUtils {
private static final boolean USE_NOWCODER_API_ONLINE =
false; // TODO 牛客接口环境,false的是线下测试环境、需要根据您的代码运行环境灵活配置
private static final long NOWCODER_HR_ID_DEV = 0; // TODO 需要替换为您牛客线下测试环境的HrID
private static final long NOWCODER_HR_ID_ONLINE = 0; // TODO 需要替换为您牛客线上正式环境的HrID
private static final String API_KEY = "huaxinjiayou@126.com"; // TODO 需要替换为您的api_key
private static final String TOKEN =
"95da5da5da5da5da5da5da5da5da5ff81aa9c7a8512638f4c73a4e338f650a5c"; // TODO 需要替换为您的token
private ConfigUtils() throws IllegalAccessException {
throw new IllegalAccessException("Can not instantiate an util class.");
}
private static boolean useNowcoderAPIOnline() {
return USE_NOWCODER_API_ONLINE;
}
public static long getNowcoderHrId() {
if (useNowcoderAPIOnline()) {
return NOWCODER_HR_ID_ONLINE;
}
return NOWCODER_HR_ID_DEV;
}
public static String getApiBaseUrl() {
// 线上正式环境
if (useNowcoderAPIOnline()) {
return "https://api.nowcoder.com/v1";
}
// 线下测试环境
return "https://dapi.nowcoder.com/v1";
}
public static String getApiKey() {
return API_KEY;
}
public static String getAuthorization() {
return "Bearer " + TOKEN;
}
}
NowcoderApiRequestUtils
类
该类为封装了符合牛客API的传输协议的HTTP调用逻辑的静态工具类。在该类中,有两个出口方法request()
和getNowcoderHrId()
。
其中request()
方法的作用是将接口的特异化参数传入并执行HTTP调用,方法支持HTTP的GET、POST、PUT、DELETE方法的请求,
并根据不同的HTTP方法规范设置了api_key
参数、Authorization
校验头、Content-Type
请求参数内容类型。
getNowcoderHrId()
方法的作用是获取用户的HRId,以便在调用需要拼接接口url的方法时使用。
请求牛客API工具类
public class NowcoderApiRequestUtils {
/**
* HTTP调用牛客API并返回字符串,在调用之前根据请求方法设置了通用的请求头和请求参数,并将方法传入的参数置入HTTP请求中。
*
* @param path 请求路径,形如"/users/self"的字符串
* @param params 请求参数,需传递除api_key参数之外的每个接口独有的参数。一个key能对应多个值,值不能为null。
* 如果接口不需要其他参数,需要传递空Map,不能传null。
* @param methodName http方法名称。取值范围为 GET、POST、PUT、DELETE 中的一个
* @return 牛客接口json返回的字符串表示
*/
public static String request(
String path, MultiValuedMap<String, Object> params, String methodName) {
if (HttpGet.METHOD_NAME.equals(methodName)) {
return getRequest(path, params);
}
HttpEntityEnclosingRequestBase uriRequest;
if (HttpPost.METHOD_NAME.equals(methodName)) {
uriRequest = new HttpPost();
} else if (HttpPut.METHOD_NAME.equals(methodName)) {
uriRequest = new HttpPut();
} else if (HttpDelete.METHOD_NAME.equals(methodName)) {
uriRequest = new NowcoderHttpDelete();
} else {
throw new IllegalArgumentException("Bad methodName.");
}
uriRequest.setURI(URI.create(ConfigUtils.getApiBaseUrl() + path));
List<NameValuePair> pairList = new ArrayList<>();
pairList.add(new BasicNameValuePair("api_key", ConfigUtils.getApiKey()));
params
.entries()
.forEach(
(entry) -> {
String key = entry.getKey();
Object val = entry.getValue();
if (key == null || val == null) return;
pairList.add(new BasicNameValuePair(key, val.toString()));
});
uriRequest.setEntity(new UrlEncodedFormEntity(pairList, StandardCharsets.UTF_8));
uriRequest.addHeader("Authorization", ConfigUtils.getAuthorization());
return sendRequest(uriRequest);
}
// 执行GET请求
private static String getRequest(String path, MultiValuedMap<String, Object> params) {
List<String> pairs = new ArrayList<>();
pairs.add("api_key=" + ConfigUtils.getApiKey());
params
.entries()
.forEach(
(entry) -> {
String key = entry.getKey();
Object val = entry.getValue();
if (key == null || val == null) return;
pairs.add(key + "=" + val);
});
String queryParams = StringUtils.join(pairs, "&");
HttpGet get = new HttpGet(ConfigUtils.getApiBaseUrl() + path + "?" + queryParams);
get.addHeader("Authorization", ConfigUtils.getAuthorization());
return sendRequest(get);
}
// 发送请求并打印CURL
private static String sendRequest(HttpRequestBase requestBase) {
CloseableHttpClient httpClient = HttpClients.createDefault();
String responseString = null;
try {
CloseableHttpResponse response = httpClient.execute(requestBase);
HttpEntity entity = response.getEntity();
responseString = EntityUtils.toString(entity, StandardCharsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
String curlStr = toCurlStr(requestBase);
System.out.println(curlStr);
return responseString;
}
// 将一次HTTP请求转换成CURL
private static String toCurlStr(HttpRequestBase requestBase) {
String httpMethod = requestBase.getMethod();
String uri = requestBase.getURI().toString();
List<String> headers = new ArrayList<>();
for (Header header : requestBase.getAllHeaders()) {
headers.add(header.getName() + ": " + header.getValue());
}
String headersStr = "";
if (CollectionUtils.isNotEmpty(headers)) {
for (String header : headers) {
headersStr += "\\\n --header '" + header + "' ";
}
}
String dataRawStr = "";
if (requestBase instanceof HttpEntityEnclosingRequestBase) {
HttpEntity entity = ((HttpEntityEnclosingRequestBase) requestBase).getEntity();
try {
dataRawStr = EntityUtils.toString(entity, StandardCharsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
}
if (StringUtils.isNotEmpty(dataRawStr)) {
dataRawStr = String.format("\\\n --data-raw '%s'", dataRawStr);
}
String template = "curl --location --request %s '%s' %s %s";
return String.format(template, httpMethod, uri, headersStr, dataRawStr);
}
}
NowcoderHTTPDelete
类
由于HTTPDelete
类不支持传递参数内容,故实现了NowcoderHttpDelete
类以便在使用DELETE请求时传递参数。该类仅在NowcoderApiRequestUtils
中使用。
DELETE请求类
public class NowcoderHttpDelete extends HttpEntityEnclosingRequestBase {
public static final String METHOD_NAME = HttpDelete.METHOD_NAME;
public NowcoderHttpDelete() {
super();
}
public NowcoderHttpDelete(final URI uri) {
super();
setURI(uri);
}
/** @throws IllegalArgumentException if the uri is invalid. */
public NowcoderHttpDelete(final String uri) {
super();
setURI(URI.create(uri));
}
@Override
public String getMethod() {
return METHOD_NAME;
}
}
src/test/java
包下的测试类
使用NowcoderApiRequestUtils
工具类对牛客API的接口进行了测试。
具体的测试代码
public class Test {
@Test
public void testGetUserTestInfo() {
String path = "/users/self";
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");
System.out.println(responseString);
}
}
接口文档组织形式
## 一句话描述接口
> 右侧为 java语言 和 shell语言的代码示例
阐明接口的业务背景、作用以及对接中常见问题。
### 接口地址
以`$method $uri`的形式表示接口地址,实际请求时,需要拼接`https://api.nowcoder.com/v1`的前缀。
### 请求参数
以表格形式展现的接口全部或部分主要的请求参数。
### 返回数据
以表格形式展现的接口全部或部分主要的返回数据。
接口文档模版
每一个接口除了描述接口的调用协议,还讲述了业务背景和对接中的常见问题。具体的组织形式见右侧示例代码。
接口目录简述
已“笔试-”开头的为笔试系统对接需要关注的接口。 已“面试-”开头的为面试系统对接需要关注的接口。 系统接口为获取用户信息所需接口。
牛客网回调服务介绍
牛客网回调服务提供了实现了一种事件发布订阅机制。开发者在订阅某些事件之后,牛客网回调服务将会在事件发生时,通过HTTP请求的形式通知开发者。
名词解释
- 开发者系统:需要与牛客进行信息互通且支持HTTP调用的系统。
- 回调:指从牛客回调服务发送HTTP请求至开发者系统这一动作。一般来说,开发者系统通过HTTP请求的方式调用牛客API来获取牛客系统中的信息, 如果我们将这个过程逆向,由牛客中调用开发者系统,向开发者系统传递信息,就成了“回调”。
- 回调时机:回调发生的时间节点,一般是指牛客系统中发生了某一关键业务需要告知开发者系统。
- 回调参数:在回调时,需要告知开发者系统的信息。
- 回调类型:按照业务、回调参数等信息划分的回调抽象。不同的回调类型也对应着不同的回调时机、回调参数以及回调配置形式。
- 回调配置:如需触发回调,需要开发者通过某些方式进行配置。
回调配置
目前来说回调支持两种配置方式:
- 在调用创建实体接口(比如:笔试考生、面试房间)时订阅一个实体的回调。
- 由牛客开发者来配置回调。
回调接口协议
回调协议包含一次HTTP调用时牛客的请求形式和期望开发者系统的返回形式。
回调请求格式
对于GET请求,所有参数都放在HTTP的Query params
中;对于POST请求,请求头为application/x-www-form-urlencoded
,参数放在了Body中。
回调成功/失败判定
开发者系统的服务返回success
这6个字符,视为回调成功。如果没有返回这六个字符,则视为回调失败。回调失败将会触发重试机制。
回调成功示例:纯HTTP响应格式如下:
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 7
success
回调重试机制
对于一次回调,牛客回调服务可能会尝试进行两次HTTP调用。 牛客回调服务会先尝试发送GET请求、如果请求失败,然后尝试发送POST请求。如果两次请求都失败了,牛客回调服务会认为这次请求失败了,并触发重试机制。
回调频率、次数
如果遇到回调失败,牛客回调服务会尝试重试4次,带上第一次失败的请求,总共尝试5次。
第几次调用 | 回调时机 |
---|---|
第一次调用 | 回调触发 |
第二次调用 | 第一次失败10分钟后 |
第三次调用 | 第二次失败30分钟后 |
第四次调用 | 第三次失败60分钟后 |
第五次调用 | 第四次失败120分钟后 |
其他事项
回调类型
不同的回调类型
有不同的回调配置
方式,会携带不同的回调参数
并在不同的回调时机
回调开发者。
回调服务地址
线下测试服务ip为:47.114.96.253
,线上回调服务ip:47.99.92.255
牛客系统对接最佳实践
牛客网企业版作为成熟的技术人才招聘解决方案提供商,根据多年系统对接经验,总结了下面几种系统对接最佳实践。
名词解释
ATS:applicant tracking system,求职跟踪系统。在这里也可以指开发者需要与牛客对接的系统。
牛客/牛客网企业版:指牛客提供的接口服务以及回调服务
笔试系统对接最佳实践
对接模式一(推荐)
系统交互流程
- 企业的HR或者牛客项目同学,使用牛客网企业版管理后台在牛客系统创建试卷。
- ATS通过调用牛客API接口,可以查询在牛客中已经创建好的试卷。
- ATS中通过调用牛客API接口的方式,安排考生到牛客的试卷中。安排成功后,可以获取到考生的考试链接。在调用接口创建考生的同时,传递需要回调的地址。
- 在考生完成考试、作弊检测完成、人工判题完成等动作触发之后,牛客将考试成绩、成绩报告通过回调地址回传给ATS。 同时,ATS也可以选择在某一个时间点调用牛客API接口获取考生成绩。
代表企业:字节跳动、网易、moka、大易等绝大部分企业
对接模式二
系统交互流程
- 企业的HR或者牛客项目同学,使用牛客网企业版管理后台在牛客系统创建好试卷,并填好职位id(这个职位id用于关联企业ATS中的职位)。
- 试卷创建完成之后,可通过职位id定位一张试卷来创建考生。在调用接口创建考生的同时,传递需要回调的地址。
- 在考生完成考试、作弊检测完成、人工判题完成等动作触发之后,牛客将考试成绩、成绩报告通过回调地址回传给ATS。 同时,ATS也可以选择在某一个时间点调用牛客API接口获取考生成绩。
代表企业:阿里巴巴、中兴、OPPO等部分企业
对接模式三
系统交互流程:
- 企业的HR或者牛客项目同学,使用牛客网企业版管理后台在牛客系统创建试卷。
- 试卷创建完成之后,在ATS系统中关联岗位、试卷。在ATS中将候选人转移状态即可安排笔试、拿到考生考试链接。
- 在考生完成考试、作弊检测完成、人工判题完成等动作触发之后,牛客将考试成绩、成绩报告回传给ATS。 同时,ATS也可以选择在某一个时间点调用牛客API接口获取考生成绩。
代表企业:北森
面试系统对接最佳实践
对接模式一
系统交互流程
- 客户在牛客端创建账号,到对接方配置认证使用的api_key
- 在对接方推进面试流程,在牛客端进行面试
- 对接方、牛客端之间进行面试结果同步
笔试-试卷管理
一张试卷包含考试时长、考试起止时间、防作弊机制配置以及添加考生时需要录入信息等配置元信息。 在牛客系统中试卷可以认为是一场考试的抽象,在校园招聘业务场景下,一场考试应与一张试卷一一对应; 在社会招聘业务场景下,一张试卷可以认为是相似职位的通用考题。 一张试卷可以对应多个考生,所有的考生都属于一张试卷。考生在试卷之间没有关联关系,不同的试卷中可以创建唯一编号(添加考生接口的key字段)相同的考生。
试卷实体的关键字段
试卷实体的创建、删除和查询可调用试卷管理接口获取,下面是试卷实体的一些关键字段。
参数 | 类型 | 描述 |
---|---|---|
id | long | 试卷id,唯一标识一张试卷。 |
paperName | String | 试卷名字。 |
type | int | 试卷类型: 1.普通笔试,2.ai面试 |
duration | int | 试卷考试时长。 |
beginTime | Date | 试卷的开始时间。 |
endTime | Date | 试卷结束时间(对长期有效试卷,默认取值'2114-10-10T00:00')。 |
forever | boolean | 试卷是否长期有效,true是,false否。 |
createTime | Date | 试卷的创建时间。 |
beenTested | boolean | 试卷是否已经被使用。 |
started | boolean | 试卷是否已经开始。 |
finished | boolean | 试卷是否已结束。 |
summary | String | 试卷简介,考生在考试开始前会看到这些信息。 |
questionCount | int | 试卷试题的数量。 |
testCount | int | 试卷测评的数量。 |
needJudge | int | 试卷是否需要人工判题, 0表示需要,1表示不需要。 |
assignedCount | int | 已经分配的判卷数量。 |
setting | Object | 试卷相关配置信息, json格式。其中,试卷适用的职位id列表为该json下的"otherJobIds"字段,取值为int类型的职位id列表,职位id之间用","分隔,取值示例:""10000001,10000002" |
score | Float | 试卷总分。 |
passScoreLine | Float | 及格线。 |
antiCheatStr | String | 防作弊机制。 |
signUpFieldTitles | String | 考生需要录入信息的所有字段,逗号拼接。 |
paperCodeLangInfo | Object | 试卷中编程题语言信息,对象结构见右侧说明 |
paperCodeLangInfo结构:
{
"codeQuestionCount": 2, // 编程题的数量,为0表示没有编程题
"ojExerciseUrl": "https://xxx", // codeQuestionCount大于0时有值,表示:OJ在线编程常见输入输出练习地址
"codeLangList": [ //codeQuestionCount大于0时有值,表示:对应题目数量和其支持的编程语言
{
"count": 2, // 题目数量
"langList": ["C","C#","C++","Go","Groovy","Java","Javascript"] // 编程语言列表,为null表示不限语言
}
]
}
获取试卷列表
public class Main {
@Test
public void testGetPaperList() {
String path = String.format("/papers/oid-%d", ConfigUtils.getNowcoderHrId());
long projectId = 1643;
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
mvMap.put("page", 1);
mvMap.put("pageCount", 20);
mvMap.put("orderBy", 0);
mvMap.put("order", 2);
mvMap.put("filter", 0);
mvMap.put("query", "");
mvMap.put("progressType", 0);
mvMap.put("projectIdList", projectId);
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");
System.out.println(responseString);
}
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/papers/oid-30?api_key=huaxinjiayou@126.com&filter=0&pageCount=20&progressType=0&query=&orderBy=0&page=1&projectIdList=1643&order=2' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'
{
"code" : 0,
"msg" : "OK",
"data" : {
"totalCount" : 1,
"totalPage" : 1,
"currentPage" : 1,
"datas" : [ {
"id" : 17131890,
"paperName" : "一张很久才开始的试卷",
"createTime" : 1628137829000,
"duration" : 120,
"score" : 20,
"personTotal" : 0,
"avgTotal" : 0.0,
"summary" : "1、考前请关闭其他浏览器窗口,关闭QQ、微信等即时通信软件,关闭屏保、Outlook等弹窗提示软件,考试中不要切换到考试窗口之外的区域。<br/>\n2、请在规定时间内完成题目,答题过程中系统自动即时,到时自动交卷,请掌握好答题进度;<br/>\n3、请诚信答题,考试全程不要跳出考试页面(在线编程题除外),后台将记录你的跳出次数。编程题交卷后,我们将进行代码相似度判断,标示作弊嫌疑代码。<br/>\n4、笔试过程中遇到任务问题,请通过在线咨询小窗发消息给我们,我们会有相应人员解答。<br/>",
"logo" : null,
"questionCount" : 1,
"diffcult" : 0,
"beginTime" : 1735660800000,
"endTime" : 1738339200000,
"previewUrl" : "https://examd.nowcoder.com/cts/preview/papers/17131890?p_token=L9mTCQXQaLsBUEfFzKlJMrKLgROj5Xk4",
"testUrl" : "https://examd.nowcoder.com/cts/17131890/summary",
"mobileTestUrl" : null,
"assigned" : true,
"testCount" : 0,
"assignedCount" : 0,
"paperSetting" : null,
"presetUserCount" : 3,
"paperExcelDownloadUrl" : null,
"excelTaskStatus" : 0,
"finished" : false,
"started" : false,
"setting" : {
"logo" : "https://dev-private-public.oss-cn-hangzhou.aliyuncs.com/images/20201130/30_1606732062638/3669B06677BFB1053B71DAA1400C3083",
"paperSummary" : "1. 请使用最新版Chrome浏览器作答(不低于82版),如考试需开启摄像头,请确保电脑带有摄像头。\n2. 一旦开始考试,请勿离开答题页面,除非当前目录明确提醒可以离开,前三次离开会有提醒,之后将不再提醒。各目录是否支持离开答题页面则取决于试卷具体设置,进入每个目录会有提示。\n3. 考试过程中允许使用草稿纸,请提前准备纸笔。允许上厕所等短暂离开,请控制离开时间。\n4. 考试期间如遇到断电、断网、死机等问题,关闭浏览器重新打开试卷链接即可继续做题。\n5. 遇到问题请即时反馈给考试主办方。",
"examDisclaimer" : null,
"antiJumpOut" : false,
"antiDesignJumpOut" : true,
"antiCodingJumpOut" : false,
"codeSimilarRate" : 80,
"setSourceCoderCheat" : false,
"monitorPhone" : false,
"allowMobileTest" : false,
"noQueueUp" : true,
"signUpFields" : [ {
"title" : "姓名",
"name" : "name",
"format" : "",
"need" : true,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "投递编号",
"name" : "key",
"format" : "",
"need" : true,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "手机号码",
"name" : "phone",
"format" : "Phone",
"need" : false,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "邮箱",
"name" : "email",
"format" : "Email",
"need" : false,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "职位",
"name" : "zhi2_wei4",
"format" : "",
"need" : false,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "学校",
"name" : "xue2_xiao4",
"format" : "",
"need" : false,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "学历",
"name" : "xue2_li4",
"format" : "",
"need" : false,
"edit" : 0,
"valueType" : 0,
"valueList" : null
} ],
"relationType" : 0,
"questionCategories" : {
"5" : "问答"
},
"questionIdsTypes" : { },
"questionScores" : null,
"questionNewCounts" : null,
"relationJsonString" : null,
"questionCategoryRule" : null,
"questionCategoryOrder" : "1,2,3,4,5",
"randomQuestion" : false,
"customCategory" : false,
"randomFrequentType" : 0,
"version" : "1.0",
"questionTagNames" : { },
"codingScoreRule" : 1,
"chooseScoreRule" : 3,
"checkCheat" : true,
"allowCopy" : false,
"allowCalculator" : false,
"contestDomain" : null,
"navLogoUrl" : null,
"hideNowcoder" : false,
"simulation" : false,
"languageLimit" : false,
"languageList" : [ ],
"reportPlatform" : true,
"forbidPreview" : true,
"needMobileCamera" : false,
"codePlayback" : false,
"timeLimitType" : 0,
"timeLimitDetail" : null,
"tiankongScores" : "{}",
"otherJobIds" : null,
"subPaperSetting" : null,
"uploadFileTimeRange" : 0,
"videoAnswerQuestionRule" : null,
"lateNoticeSetting" : null,
"paper_end_summary" : "本场考试已结束,请保持您的手机、邮箱畅通,方便接收后续通知。",
"allow_new" : false,
"allow_camera" : false,
"allow_screen_record" : false,
"allow_message" : false,
"question_disorder" : false,
"option_disorder" : false,
"not_need_judge_type" : "3_4",
"need_judge_type" : "5",
"faq" : [ ],
"hide_return_button" : true
},
"beenTested" : false,
"passScoreLine" : null,
"projectId" : 1643,
"projectName" : "liumeng测试",
"departmentList" : null,
"previewOverdueTime" : null,
"paperType" : null,
"hasNotAttendTestUser" : false,
"antiCheatStr" : "开启举报平台",
"signUpFieldTitles" : "投递编号,姓名,手机号码,邮箱,职位,学校,学历",
"creatorHrId" : 30,
"creatorHrName" : null,
"needJudge" : 0,
"notStartedCount" : 0,
"inProgressCount" : 0,
"expiredCount" : 0,
"cheatTaskStatus" : 0,
"faceDetectedRation" : 0.0,
"codeDetectedRation" : 0.0,
"screenDetectedRation" : 0.0,
"hasCodeQuestion" : false,
"hasCtsPic" : false,
"hasScreen" : false,
"questionDesc" : "问答 1 道",
"interviewPaper" : null,
"forever" : false
} ],
"ext" : null,
"allTotalCount" : 1,
"notStartedPaperCount" : 1,
"testingPaperCount" : 0,
"finishedPaperCount" : 0,
"archivePaperCount" : 0
}
}
获取一个账户下的试卷列表。支持分页。这个接口可以用于遍历牛客系统中已经创建好的试卷。
接口地址
GET /papers/oid-{ownerId}
请求参数
参数 | 类型 | 是否必传 | 默认值 | 描述 |
---|---|---|---|---|
ownerId | int | 是 | HR系统的用户ID,需填充在url中 | |
page | int | 否 | 1 | 第几页,从1开始。 |
pageCount | int | 否 | 20 | 每页20多少数据。无数量限制,可以传较大的值,但试卷数量多之后响应时长可能很长,不推荐这么做 |
orderBy | int | 否 | 0 | 试卷排序的依据项。0根据create_time排序,1根据做题人数排序,2根据平均分排序,3开考时间 |
order | int | 是 | 试卷的排列顺序。1代表升序,2代表降序 | |
filter | int | 否 | 2 | 是否过滤。可不传,默认0。0不过滤, 1过滤掉不需要人工判卷的试卷 |
query | String | 否 | 试卷名称搜索,实现方式为SQLLIKE 关键字的模糊搜索 |
|
paperType | int | 否 | 试卷类型:0.全部,1.普通笔试,2.ai面试。当paperType未传值或该参数不存在时,默认值为0,会返回笔试试卷+AI面试试卷(AI试卷名称自动添加#AI面试#前缀,以便于与笔试试卷区分) | |
progressType | int | 是 | 试卷的状态:0.代表不限,1.表示未开始,2.表示进行中,3.表示结束 | |
progressTypeList | List<Integer> | 否 | progressType的多值查询参数,多个参数之间用OR关系取并集;当启用该参数时,建议progressType参数默认取值0(progressType和progressTypeList两参数间,是And关系取交集的逻辑) | |
projectIdList | List<Long> | 否 | 限定试卷所属项目id,可传多个 | |
otherJobIdList | List<Long> | 否 | 限定职位id,一般情况下不用传,可传多个,用于筛选出“试卷配置中指定了职位id“的试卷列表。关于职位id更多信息见系统对接模式2 |
返回数据
参数 | 描述 |
---|---|
totalCount | 数据(试卷)总数 |
totalPage | 总共多少页 |
currentPage | 当前是第几页,从第一页开始 |
datas | 试卷信息数组,试卷关键信息见试卷关键返回字段 |
批量获取试卷
public class Main {
@Test
public void testGetPaperListByMultiPaperIds() {
String path = "/papers/multi";
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
mvMap.put("paperIds", 17071483);
mvMap.put("paperIds", 17071578);
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");
System.out.println(responseString);
}
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/papers/multi?api_key=huaxinjiayou@126.com&paperIds=17071483&paperIds=17071578' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'
{
"code" : 0,
"msg" : "OK",
"data" : [ {
"id" : 17071483,
"paperName" : "121",
"createTime" : 1611214578000,
"duration" : 120,
"score" : 112,
"personTotal" : 0,
"avgTotal" : 0.0,
"summary" : "1、考前请关闭其他浏览器窗口,关闭QQ、微信等即时通信软件,关闭屏保、Outlook等弹窗提示软件,考试中不要切换到考试窗口之外的区域。<br/>\n2、请在规定时间内完成题目,答题过程中系统自动即时,到时自动交卷,请掌握好答题进度;<br/>\n3、请诚信答题,考试全程不要跳出考试页面(在线编程题除外),后台将记录你的跳出次数。编程题交卷后,我们将进行代码相似度判断,标示作弊嫌疑代码。<br/>\n4、笔试过程中遇到任务问题,请通过在线咨询小窗发消息给我们,我们会有相应人员解答。<br/>",
"logo" : null,
"questionCount" : 4,
"diffcult" : 0,
"beginTime" : 1611214578000,
"endTime" : 4568544000000,
"previewUrl" : "https://examd.nowcoder.com/cts/preview/papers/17071483?p_token=L9mTCQXQaLsBUEfFzKlJMrKLgROj5Xk4",
"testUrl" : "https://examd.nowcoder.com/cts/17071483/summary",
"mobileTestUrl" : null,
"assigned" : true,
"testCount" : 0,
"assignedCount" : 0,
"paperSetting" : null,
"presetUserCount" : 0,
"paperExcelDownloadUrl" : null,
"excelTaskStatus" : 0,
"finished" : false,
"started" : true,
"setting" : {
"logo" : "https://dev-private-public.oss-cn-hangzhou.aliyuncs.com/images/20201130/30_1606732062638/3669B06677BFB1053B71DAA1400C3083",
"paperSummary" : "1. 请使用最新版Chrome浏览器作答(不低于82版),如考试需开启摄像头,请确保电脑带有摄像头。\n2. 一旦开始考试,请勿离开答题页面,除非当前目录明确提醒可以离开,前三次离开会有提醒,之后将不再提醒。各目录是否支持离开答题页面则取决于试卷具体设置,进入每个目录会有提示。\n3. 考试过程中允许使用草稿纸,请提前准备纸笔。允许上厕所等短暂离开,请控制离开时间。\n4. 考试期间如遇到断电、断网、死机等问题,关闭浏览器重新打开试卷链接即可继续做题。\n5. 遇到问题请即时反馈给考试主办方。",
"examDisclaimer" : null,
"antiJumpOut" : false,
"antiDesignJumpOut" : true,
"antiCodingJumpOut" : false,
"codeSimilarRate" : 80,
"setSourceCoderCheat" : false,
"monitorPhone" : false,
"allowMobileTest" : false,
"noQueueUp" : false,
"signUpFields" : [ {
"title" : "姓名",
"name" : "name",
"format" : "",
"need" : true,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "投递编号",
"name" : "key",
"format" : "",
"need" : true,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "手机号码",
"name" : "phone",
"format" : "Phone",
"need" : false,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "邮箱",
"name" : "email",
"format" : "Email",
"need" : false,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "职位",
"name" : "zhi2_wei4",
"format" : "",
"need" : false,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "学校",
"name" : "xue2_xiao4",
"format" : "",
"need" : false,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "学历",
"name" : "xue2_li4",
"format" : "",
"need" : false,
"edit" : 0,
"valueType" : 0,
"valueList" : null
} ],
"relationType" : 0,
"questionCategories" : {
"100" : "1",
"101" : "2",
"102" : "3",
"103" : "4"
},
"questionIdsTypes" : { },
"questionScores" : null,
"questionNewCounts" : null,
"relationJsonString" : null,
"questionCategoryRule" : null,
"questionCategoryOrder" : null,
"randomQuestion" : false,
"customCategory" : true,
"randomFrequentType" : 0,
"version" : "1.0",
"questionTagNames" : { },
"codingScoreRule" : 1,
"chooseScoreRule" : 3,
"checkCheat" : true,
"allowCopy" : false,
"allowCalculator" : false,
"contestDomain" : null,
"navLogoUrl" : null,
"hideNowcoder" : false,
"simulation" : false,
"languageLimit" : false,
"languageList" : [ ],
"reportPlatform" : true,
"forbidPreview" : true,
"needMobileCamera" : false,
"codePlayback" : false,
"timeLimitType" : 0,
"timeLimitDetail" : null,
"tiankongScores" : "{\"803922\":[20,21,22,23]}",
"otherJobIds" : null,
"subPaperSetting" : [ {
"id" : 1,
"name" : "子卷1",
"intro" : "子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明子卷1说明",
"categories" : "102,100,101"
}, {
"id" : 2,
"name" : "子卷2",
"intro" : "子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明子卷2说明",
"categories" : "101,102,103"
} ],
"uploadFileTimeRange" : 0,
"videoAnswerQuestionRule" : null,
"lateNoticeSetting" : null,
"paper_end_summary" : "本场考试已结束,请保持您的手机、邮箱畅通,方便接收后续通知。",
"allow_new" : false,
"allow_camera" : true,
"allow_screen_record" : false,
"allow_message" : false,
"question_disorder" : true,
"option_disorder" : true,
"not_need_judge_type" : "3_4",
"need_judge_type" : "5",
"faq" : [ ],
"hide_return_button" : true
},
"beenTested" : false,
"passScoreLine" : null,
"projectId" : 1643,
"projectName" : "liumeng测试",
"departmentList" : null,
"previewOverdueTime" : null,
"paperType" : null,
"hasNotAttendTestUser" : false,
"antiCheatStr" : "开启摄像头,题目乱序,选择题选项乱序,开启举报平台",
"signUpFieldTitles" : "投递编号,姓名,手机号码,邮箱,职位,学校,学历",
"creatorHrId" : 30,
"creatorHrName" : null,
"needJudge" : 0,
"notStartedCount" : 0,
"inProgressCount" : 0,
"expiredCount" : 0,
"cheatTaskStatus" : 0,
"faceDetectedRation" : 0.0,
"codeDetectedRation" : 0.0,
"screenDetectedRation" : 0.0,
"hasCodeQuestion" : false,
"hasCtsPic" : true,
"hasScreen" : false,
"questionDesc" : "子卷1: 1 1 道,2 1 道,3 1 道<br>子卷2: 2 1 道,3 1 道,4 1 道<br>",
"interviewPaper" : null,
"forever" : true
}, {
"id" : 17071578,
"paperName" : "magictest",
"createTime" : 1615197295000,
"duration" : 60,
"score" : 36,
"personTotal" : 3,
"avgTotal" : 0.0,
"summary" : "1、考前请关闭其他浏览器窗口,关闭QQ、微信等即时通信软件,关闭屏保、Outlook等弹窗提示软件,考试中不要切换到考试窗口之外的区域。<br/>\n2、请在规定时间内完成题目,答题过程中系统自动即时,到时自动交卷,请掌握好答题进度;<br/>\n3、请诚信答题,考试全程不要跳出考试页面(在线编程题除外),后台将记录你的跳出次数。编程题交卷后,我们将进行代码相似度判断,标示作弊嫌疑代码。<br/>\n4、笔试过程中遇到任务问题,请通过在线咨询小窗发消息给我们,我们会有相应人员解答。<br/>",
"logo" : null,
"questionCount" : 12,
"diffcult" : 0,
"beginTime" : 1615197295000,
"endTime" : 1616818200000,
"previewUrl" : "https://examd.nowcoder.com/cts/preview/papers/17071578?p_token=L9mTCQXQaLsBUEfFzKlJMrKLgROj5Xk4",
"testUrl" : "https://examd.nowcoder.com/cts/17071578/summary",
"mobileTestUrl" : null,
"assigned" : false,
"testCount" : 4,
"assignedCount" : 0,
"paperSetting" : null,
"presetUserCount" : 7,
"paperExcelDownloadUrl" : null,
"excelTaskStatus" : 0,
"finished" : true,
"started" : true,
"setting" : {
"logo" : "https://dev-private-public.oss-cn-hangzhou.aliyuncs.com/images/20201130/30_1606732062638/3669B06677BFB1053B71DAA1400C3083",
"paperSummary" : "1. 请使用最新版Chrome浏览器作答(不低于82版),如考试需开启摄像头,请确保电脑带有摄像头。\n2. 一旦开始考试,请勿离开答题页面,除非当前目录明确提醒可以离开,前三次离开会有提醒,之后将不再提醒。各目录是否支持离开答题页面则取决于试卷具体设置,进入每个目录会有提示。\n3. 考试过程中允许使用草稿纸,请提前准备纸笔。允许上厕所等短暂离开,请控制离开时间。\n4. 考试期间如遇到断电、断网、死机等问题,关闭浏览器重新打开试卷链接即可继续做题。\n5. 遇到问题请即时反馈给考试主办方。",
"examDisclaimer" : null,
"antiJumpOut" : false,
"antiDesignJumpOut" : false,
"antiCodingJumpOut" : false,
"codeSimilarRate" : 80,
"setSourceCoderCheat" : false,
"monitorPhone" : false,
"allowMobileTest" : false,
"noQueueUp" : false,
"signUpFields" : [ {
"title" : "姓名",
"name" : "name",
"format" : "",
"need" : true,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "投递编号",
"name" : "key",
"format" : "",
"need" : true,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "手机号码",
"name" : "phone",
"format" : "Phone",
"need" : false,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "邮箱",
"name" : "email",
"format" : "Email",
"need" : false,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "职位",
"name" : "zhi2_wei4",
"format" : "",
"need" : false,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "学校",
"name" : "xue2_xiao4",
"format" : "",
"need" : false,
"edit" : 0,
"valueType" : 0,
"valueList" : null
}, {
"title" : "学历",
"name" : "xue2_li4",
"format" : "",
"need" : false,
"edit" : 0,
"valueType" : 0,
"valueList" : null
} ],
"relationType" : 0,
"questionCategories" : {
"1" : "单选"
},
"questionIdsTypes" : { },
"questionScores" : null,
"questionNewCounts" : null,
"relationJsonString" : null,
"questionCategoryRule" : null,
"questionCategoryOrder" : "1,2,3,4,5",
"randomQuestion" : false,
"customCategory" : false,
"randomFrequentType" : 0,
"version" : "1.0",
"questionTagNames" : { },
"codingScoreRule" : 1,
"chooseScoreRule" : 3,
"checkCheat" : true,
"allowCopy" : false,
"allowCalculator" : false,
"contestDomain" : null,
"navLogoUrl" : null,
"hideNowcoder" : false,
"simulation" : false,
"languageLimit" : false,
"languageList" : [ ],
"reportPlatform" : true,
"forbidPreview" : true,
"needMobileCamera" : false,
"codePlayback" : false,
"timeLimitType" : 0,
"timeLimitDetail" : null,
"tiankongScores" : "{}",
"otherJobIds" : null,
"subPaperSetting" : null,
"uploadFileTimeRange" : 0,
"videoAnswerQuestionRule" : null,
"lateNoticeSetting" : null,
"paper_end_summary" : "本场考试已结束,请保持您的手机、邮箱畅通,方便接收后续通知。",
"allow_new" : false,
"allow_camera" : true,
"allow_screen_record" : false,
"allow_message" : false,
"question_disorder" : true,
"option_disorder" : true,
"not_need_judge_type" : "3_4",
"need_judge_type" : "5",
"faq" : [ ],
"hide_return_button" : true
},
"beenTested" : false,
"passScoreLine" : null,
"projectId" : 1643,
"projectName" : "liumeng测试",
"departmentList" : null,
"previewOverdueTime" : null,
"paperType" : null,
"hasNotAttendTestUser" : false,
"antiCheatStr" : "开启摄像头,题目乱序,选择题选项乱序,开启举报平台",
"signUpFieldTitles" : "投递编号,姓名,手机号码,邮箱,职位,学校,学历",
"creatorHrId" : 30,
"creatorHrName" : null,
"needJudge" : 0,
"notStartedCount" : 0,
"inProgressCount" : 0,
"expiredCount" : 0,
"cheatTaskStatus" : 3,
"faceDetectedRation" : 0.0,
"codeDetectedRation" : 0.0,
"screenDetectedRation" : 0.0,
"hasCodeQuestion" : false,
"hasCtsPic" : true,
"hasScreen" : false,
"questionDesc" : "单选 12 道",
"interviewPaper" : null,
"forever" : false
} ]
}
根据试卷id批量获取试卷。开发者可以通过考生所属的试卷id来获取试卷的详细信息。如果试卷id不存在,会返回code=1
的报错。
接口地址
GET /papers/multi
请求参数
参数 | 类型 | 是否必传 | 默认值 | 描述 |
---|---|---|---|---|
paperIds | List<Long> | 是 | 试卷id |
返回数据
试卷信息数组,试卷关键信息见试卷关键返回字段
删除试卷
public class Main {
@Test
public void testDeletePaper() {
long paperId = 17131854;
String path = String.format("/papers/%d", paperId);
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "DELETE");
System.out.println(responseString);
}
}
curl --location --request DELETE 'https://dapi.nowcoder.com/v1/papers/17131854' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
--data-raw 'api_key=huaxinjiayou%40126.com'
{
"code" : 0,
"msg" : "OK",
"data" : "OK"
}
根据试卷id删除试卷,删除之后,试卷的做题记录将同时清除。这个接口是幂等的,可以删除已经删除的试卷(无事发生)。
接口地址
DELETE /papers/{paperId}
请求参数
参数 | 类型 | 是否必传 | 默认值 | 描述 |
---|---|---|---|---|
paperId | int | 是 | 需填充在url中 | 试卷id |
返回数据
不需要关注返回数据。只需要检查接口请求是否成功(返回HTTP状态码为 200
且内容中的code=0
)
根据试卷ID获取试卷信息
public class Main {
@Test
public void testGetPaperPreview() {
long paperId = 17071578;
String path = String.format("/papers/%d", paperId);
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "POST");
System.out.println(responseString);
}
}
curl --location --request POST 'https://dapi.nowcoder.com/v1/papers/17071578/previews' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
--data-raw 'api_key=huaxinjiayou%40126.com&shortUrl=true'
{
"code" : 0,
"msg" : "OK",
"data" : "https://dwz.cn/HTQwVSEe"
}
接口地址
GET /papers/{paperId}
请求参数
参数 | 类型 | 是否必传 | 默认值 | 描述 |
---|---|---|---|---|
paperId | int | 是 | 不能小于1,需填充在url中 | 试卷id |
返回数据
试卷信息数组,试卷关键信息见试卷关键返回字段
分享试卷预览
public class Main {
@Test
public void testGetPaperPreview() {
long paperId = 17071578;
String path = String.format("/papers/%d/previews", paperId);
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
mvMap.put("shortUrl", true);
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "POST");
System.out.println(responseString);
}
}
curl --location --request POST 'https://dapi.nowcoder.com/v1/papers/17071578/previews' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
--data-raw 'api_key=huaxinjiayou%40126.com&shortUrl=true'
{
"code" : 0,
"msg" : "OK",
"data" : "https://dwz.cn/U4QdDWK8"
}
接口可以用于在开发者自己的系统中预览牛客的试卷。
接口地址
POST /papers/{paperId}/previews
请求参数
参数 | 类型 | 是否必传 | 默认值 | 描述 |
---|---|---|---|---|
paperId | long | 是 | 不能小于1,需填充在url中 | 试卷id |
shortUrl | boolean | 否 | 默认true,可以为false | 是否需要转换成短链接 |
返回数据
字符串类型的链接地址。
笔试-考生管理
(考生实体)关键字段
考生包含了考生的个人信息,每一位考生归属一张试卷,每一位考生有自己的专属笔试链接。
考生实体的创建、删除和查询可调用考生管理接口获取,下面是考生实体的一些关键字段。
参数 | 类型 | 描述 |
---|---|---|
id | long | 考生id |
testId | String | 考生id加密版,32位字符 (该字段建议入库保存,成绩报告回调时会回传testId字段,可用于进行考生成绩关联) |
userKey | String | 业务侧唯一用户标识,同张试卷下userKey唯一(通过paperId+userKey,也可以用于成绩报告回调时关联) |
name | String | 姓名 |
String | 邮箱 | |
phone | String | 手机号 |
testUrl | String | 考生的专属考试链接 |
shortTestUrl | String | 考生的专属考试链接(短链形式,打开自动跳转testUrl,目前仅对AI面试场景开放) |
testBeginTime | Date | 考试链接最早可以开始作答时间,如果试卷当前正在使用,该时间默认为考试链接生成时间;但如果试卷未开始,则该时间可能晚于当前时间 |
testExpireTime | Date | 考试链接过期时间(对长期有效链接,默认取值'9999-12-31';20240614之前创建的长期有效链接,该字段则为null) |
started | boolean | 考生的考试是否已开始,true已开始 |
testStatus | int | 考生考试状态,1没有开始考试,2表示已经打开,3表示已经提交 |
note | String | 考生备注 |
paperId | long | 试卷id |
paperName | String | 试卷名称 |
paperType | int | 试卷类型:1.普通笔试,2.ai面试 |
paperStarted | boolean | 试卷是否已开始 |
signStatus | int | 考生确认是否参加考试状态 |
noSignReason | String | 拒绝参加考试的原因 |
emailNotification | int | 邮件发起通知次数 |
smsNotification | int | 短信发起通知次数 |
emailSentStatus | int | 邮件发送状态, 0未发送,1发送中,2发送失败,3接收成功,4接收失败,5定时发送,6取消发送 |
smsSentStatus | int | 短信发送状态, 0未发送,1发送中,2发送失败,3接收成功,4接收失败,5定时发送,6取消发送 |
createTime | Date | 创建时间 |
(添加考生前)检测余额是否充足
public class Main {
@Test
public void testAddTestUsersCheckBalance() {
String path = "/papers/test_users/checkBalance";
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
long paperId = 17071600;
int userCnt = 2;
mvMap.put("paperId_userCounts", paperId + "_" + userCnt);
long anotherPaperId = 17071600;
int anotherUserCnt = 2;
mvMap.put("paperId_userCounts", anotherPaperId + "_" + anotherUserCnt);
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");
System.out.println(responseString);
}
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/papers/test_users/checkBalance?api_key=huaxinjiayou@126.com&paperId_userCounts=17071600_2&paperId_userCounts=17071600_2' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'
{
"code" : 0,
"msg" : "OK",
"data" : {
"hostId" : 30,
"adminHrId" : 30,
"moneyEnough" : true,
"subAccountLimitEnough" : true
}
}
在添加考生前,可以通过该接口预估添加考生时是否余额足够。
接口地址
GET /papers/test_users/checkBalance
请求参数
参数 | 类型 | 是否必传 | 默认值 | 描述 |
---|---|---|---|---|
paperId_userCounts | List<String> | 是 | 格式为:试卷id_考生数量。可传多个 | 按试卷id聚合考生数量, |
返回数据
参数 | 描述 |
---|---|
hostId | 当前账号id |
adminHrId | 当前账号的公司主账号id |
moneyEnough | 公司主账号的余额是否充足 |
subAccountLimitEnough | 子账号分配的业务额度是否充足 |
添加考生
public class Main {
@Test
public void testAddTestUsers() {
long paperId = 17131890;
String path = String.format("/papers/%d/test_users", paperId);
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
mvMap.put("name", "郭凯俊1");
mvMap.put("key", "gkj1");
mvMap.put("phone", "18812341234");
mvMap.put("email", "guokaijun@nowcoder.com");
mvMap.put("shen1_fen4_zheng4", "431123199911116666");
mvMap.put("zhi2_wei4", "Java开发工程师");
mvMap.put("xue2_xiao4", "清北大学");
mvMap.put("xue2_li4", "本科");
mvMap.put("note", "这个考生是通过API添加的");
mvMap.put("name", "郭凯俊2");
mvMap.put("key", "gkj2");
mvMap.put("phone", "18812341234");
mvMap.put("email", "guokaijun@nowcoder.com");
mvMap.put("shen1_fen4_zheng4", "431123199911116666");
mvMap.put("zhi2_wei4", "Java开发工程师");
mvMap.put("xue2_xiao4", "清北大学");
mvMap.put("xue2_li4", "本科");
mvMap.put("note", "这个考生是通过API添加的");
mvMap.put("failOnExist", false);
mvMap.put("notice", false);
mvMap.put("version", 0);
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "POST");
System.out.println(responseString);
}
}
curl --location --request POST 'https://dapi.nowcoder.com/v1/papers/17131890/test_users' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
--data-raw 'api_key=huaxinjiayou%40126.com¬e=%E8%BF%99%E4%B8%AA%E8%80%83%E7%94%9F%E6%98%AF%E9%80%9A%E8%BF%87API%E6%B7%BB%E5%8A%A0%E7%9A%84¬e=%E8%BF%99%E4%B8%AA%E8%80%83%E7%94%9F%E6%98%AF%E9%80%9A%E8%BF%87API%E6%B7%BB%E5%8A%A0%E7%9A%84&failOnExist=false&phone=18812341234&phone=18812341234&shen1_fen4_zheng4=431123199911116666&shen1_fen4_zheng4=431123199911116666&name=%E9%83%AD%E5%87%AF%E4%BF%8A1&name=%E9%83%AD%E5%87%AF%E4%BF%8A2&xue2_xiao4=%E6%B8%85%E5%8C%97%E5%A4%A7%E5%AD%A6&xue2_xiao4=%E6%B8%85%E5%8C%97%E5%A4%A7%E5%AD%A6&zhi2_wei4=Java%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88&zhi2_wei4=Java%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88&version=0&key=gkj1&key=gkj2&email=guokaijun%40nowcoder.com&email=guokaijun%40nowcoder.com&xue2_li4=%E6%9C%AC%E7%A7%91&xue2_li4=%E6%9C%AC%E7%A7%91¬ice=false'
{
"code" : 0,
"msg" : "OK",
"data" : [ {
"id" : 2115087,
"email" : null,
"phone" : null,
"testId" : "DCC8EDB8828E22D5",
"paperId" : 17131890,
"paperName" : null,
"userKey" : "gkj1",
"name" : null,
"ext" : null,
"testUrl" : "https://examd.nowcoder.com/cts/17131890/summary?id=DCC8EDB8828E22D5",
"started" : false,
"signStatus" : 0,
"noSignReason" : null,
"emailNotification" : 0,
"smsNotification" : 0,
"emailSentStatus" : 0,
"smsSentStatus" : 0,
"note" : null,
"createTime" : null,
"testStatus" : 0,
"realTestId" : 0,
"ctsDepartment" : null,
"creatorHrUid" : 0,
"creatorHrName" : null,
"apiRole" : 0,
"emailRecordCount" : 0,
"smsRecordCount" : 0,
"emailRecord" : null,
"smsRecord" : null,
"emailSuccessCount" : 0,
"smsSuccessCount" : 0,
"paperStarted" : false,
"arrangeFeedbackId" : 0,
"arrangeFeedbackTime" : null,
"arrangeFeedbackContent" : null,
"errMsg" : null,
"paperStartTime" : 1735660800000,
"paperEndTime" : 1738339200000
}, {
"id" : 2115088,
"email" : null,
"phone" : null,
"testId" : "C72B030BD2287647",
"paperId" : 17131890,
"paperName" : null,
"userKey" : "gkj2",
"name" : null,
"ext" : null,
"testUrl" : "https://examd.nowcoder.com/cts/17131890/summary?id=C72B030BD2287647",
"started" : false,
"signStatus" : 0,
"noSignReason" : null,
"emailNotification" : 0,
"smsNotification" : 0,
"emailSentStatus" : 0,
"smsSentStatus" : 0,
"note" : null,
"createTime" : null,
"testStatus" : 0,
"realTestId" : 0,
"ctsDepartment" : null,
"creatorHrUid" : 0,
"creatorHrName" : null,
"apiRole" : 0,
"emailRecordCount" : 0,
"smsRecordCount" : 0,
"emailRecord" : null,
"smsRecord" : null,
"emailSuccessCount" : 0,
"smsSuccessCount" : 0,
"paperStarted" : false,
"arrangeFeedbackId" : 0,
"arrangeFeedbackTime" : null,
"arrangeFeedbackContent" : null,
"errMsg" : null,
"paperStartTime" : 1735660800000,
"paperEndTime" : 1738339200000
} ]
}
接口用于向试卷中添加考生。如果试卷不允许用户自己报名参加,只有再这里添加的用户才能参加考试(直接打开接口返回的URL来考试)。 接口可以同时添加多个用户,即传多个keys和names参数,数量要保持一致。其他选填字段如手机、邮箱等,方式相同。 试卷配置中默认的手机字段为phone, 邮箱为email,其他为汉语拼音加声调加下划线。例如职位zhi2_wei4, 学历xue2_li4。
接口地址
POST /papers/{paperId}/test_users
请求参数
除列表中展示的字段外,还可以填入考生的其他选填字段。例如职位zhi2_wei4, 学历xue2_li4。详情见代码示例
参数 | 类型 | 是否必传 | 默认值 | 描述 |
---|---|---|---|---|
paperId | long | 是 | 需填充在url中 | 试卷id |
key | List<String> | 是 | 考试编号,在同一个试卷内唯一确定一个用户的字符串,不能包含emoji字符 | |
name | List<String> | 是 | 和key对应的用户的姓名,姓名不能包含如下字符: `~!@#$%^&*()+=|{}':;[]<>/?!¥…()—【】‘;:”“’。、? | |
foreignKey | List<String> | 否 | 同1位候选人(自然人)在其它场景(比如AI面试)使用的考试编号,与key字段相对应。比如笔试场景下,key代表的是该候选人在本场考试下的考试编号,而foreignKey可代表该候选人在后续AI面试中的编号,通过这2个Key可以跨场景关联到同1个人。 | |
userData | List<String> | 否 | 候选人信息,主要用于AI面试智能化出题、智能追问等场景,数据类型为json对象转string,json结构定义请参考文档候选人信息Json结构定义 | |
callback | String | 否 | 回调地址,填写后将配置:完成考试、作弊检测、人工判题、考生被删除 四种类型的回调。更多关于回调类型的信息见:链接 | |
failOnExist | boolean | 是 | 为true时,如果导入前这个考生的key已经存在,则直接返回失败 | |
userType | int | 否 | 考生类型: 0 普通考生 1 测试考生,可提前进入考试答题。每张试卷可免费添加10个测试考生,超过部分将扣费 | |
confirm | boolean | 否 | 当添加测试考生且即将扣费时,需要confirm=true时才能继续操作。 | |
note | List<String> | 否 | 和key对应的用户的备注,可以不传 | |
version | int | 是 | 0:当所有考生格式正确才会添加,1:格式正确考生会录入成功 | |
notice | boolean | 是 | true:使用牛客默认模版发送手机短信和邮件通知,false:不发送 | |
emailTemplateId | int | 否 | 仅在notice=true时有效,用于指定本次通知的邮件版本 | |
smsTemplateId | int | 否 | 仅在notice=true时有效,用于指定本次通知的短信版本 |
返回数据
已经添加过的考生信息数组。接口需要关心下面的字段
参数 | 描述 |
---|---|
errMsg | 添加考生失败的时候,返回的考生id=0,此时这个字段会返回错误原因 |
其他参数见考生关键信息见考生关键返回字段
删除考生
public class Main {
@Test
public void testDeleteTestUser() {
long paperId = 17131890;
long testUserId = 2115115;
String path = String.format("/papers/%d/test_users/%d", paperId, testUserId);
// 考试已经开始无法删除考生。
// 已经删除的考生无法删除。
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "DELETE");
System.out.println(responseString);
}
}
curl --location --request DELETE 'http://localhost:8888/v1/papers/17131890/test_users/2115115' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
--data-raw 'api_key=huaxinjiayou%40126.com'
# 删除成功
{
"code" : 0,
"msg" : "OK",
"data" : "该考生未参加考试,考试费用15.0元已退回您的账户。"
}
# 考生曾经删除成功 或者 考生没有被添加过
{
"code" : 1,
"msg" : "考生不存在",
"details" : null
}
通过考生id删除牛客系统中的一个考生。
接口地址
DELETE /papers/{paperId}/test_users/{id}
请求参数
参数 | 类型 | 是否必传 | 默认值 | 描述 |
---|---|---|---|---|
paperId | long | 是 | 需填充在url中 | 试卷id |
id | long | 是 | 需填充在url中 | 考生id |
返回数据
无需关心返回数据,接口请求成功则视为删除成功
批量删除考生
public class Main {
@Test
public void testDeleteMultiTestUsers() {
String delUsersPath = String.format("/papers/%d/test_users", 0);
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
mvMap.put("ids", 2115077);
mvMap.put("ids", 2115081);
mvMap.put("paperIds", 17131890);
mvMap.put("paperIds", 17131891);
mvMap.put("isAll", 2);
String responseString = NowcoderApiRequestUtils.request(delUsersPath, mvMap, "DELETE");
System.out.println(responseString);
}
}
curl --location --request DELETE 'https://dapi.nowcoder.com/v1/papers/0/test_users' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
--data-raw 'api_key=huaxinjiayou%40126.com&ids=2115077&ids=2115081&isAll=2&paperIds=17131890&paperIds=17131891'
{
"code" : 0,
"msg" : "OK",
"data" : "UBfCoqS08apsZ8QIEojbsmfpyxUCaYgh"
}
通过多个考生id批量删除牛客系统中的考生。该接口会异步进行处理。无需关心返回数据,接口请求成功则视为删除成功
接口地址
DELETE /papers/{paperId}/test_users
请求参数
参数 | 类型 | 是否必传 | 默认值 | 描述 |
---|---|---|---|---|
ids | List<Long> | 是 | 考生id。可以填多个 | |
paperIds | List<Long> | 是 | 试卷id,需要包含所有考生所属的试卷ids。可以填多个,但列表中id不能重复 | |
isAll | int | 是 | 需传2 | 用于指定接口取paperIds |
paperId | long | 是 | 需传0 | 用于填充参数中的url |
返回数据
牛客异步任务id。
查询单个考生信息
public class Main {
@Test
public void testGetTestUser() {
long paperId = 17131890;
long testUserId = 2115086;
String path = String.format("/papers/%d/test_users/%d", paperId, testUserId);
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");
System.out.println(responseString);
}
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/papers/17131890/test_users/2115086?api_key=huaxinjiayou@126.com' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'
{
"code" : 0,
"msg" : "OK",
"data" : {
"id" : 2115086,
"email" : "guokaijun@nowcoder.com",
"phone" : "18812341234",
"testId" : null,
"paperId" : 17131890,
"paperName" : null,
"userKey" : "gkj",
"name" : "郭凯俊",
"ext" : "{\"phone\":\"18812341234\",\"name\":\"郭凯俊\",\"xue2_xiao4\":\"清北大学\",\"zhi2_wei4\":\"Java开发工程师\",\"key\":\"gkj\",\"email\":\"guokaijun@nowcoder.com\",\"xue2_li4\":\"本科\"}",
"testUrl" : null,
"started" : false,
"signStatus" : 0,
"noSignReason" : "",
"emailNotification" : 0,
"smsNotification" : 0,
"emailSentStatus" : 0,
"smsSentStatus" : 0,
"note" : "这个考生是通过API添加的",
"createTime" : 1628147456000,
"testStatus" : 1,
"realTestId" : 0,
"ctsDepartment" : null,
"creatorHrUid" : 30,
"creatorHrName" : null,
"apiRole" : 2,
"emailRecordCount" : 0,
"smsRecordCount" : 0,
"emailRecord" : null,
"smsRecord" : null,
"emailSuccessCount" : 0,
"smsSuccessCount" : 0,
"paperStarted" : false,
"arrangeFeedbackId" : 0,
"arrangeFeedbackTime" : 1628147456000,
"arrangeFeedbackContent" : null,
"errMsg" : null,
"paperStartTime" : null,
"paperEndTime" : null
}
}
接口用于查询单个考生的信息
接口地址
GET /papers/{paperId}/test_users/{id}
请求参数
参数 | 类型 | 是否必传 | 默认值 | 描述 |
---|---|---|---|---|
paperId | long | 是 | 需填充在url中 | 试卷id |
id | long | 是 | 需填充在url中 | 考生id |
返回数据
考生关键信息见考生关键返回字段。
更新单个考生信息
public class Main {
@Test
public void testUpdateTestUser() {
long paperId = 17131890;
long testUserId = 2115086;
String path = String.format("/papers/%d/test_users/%d", paperId, testUserId);
// 考试已经开始无法删除考生。
// 已经删除的考生无法删除。
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
mvMap.put("name", "郭凯俊");
mvMap.put("key", "gkj");
mvMap.put("phone", "18812341234");
mvMap.put("email", "guokaijun@nowcoder.com");
mvMap.put("shen1_fen4_zheng4", "431123199911116666");
mvMap.put("zhi2_wei4", "Java开发工程师");
mvMap.put("xue2_xiao4", "清北大学");
mvMap.put("xue2_li4", "本科");
mvMap.put("note", "这个考生是通过API添加的");
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "PUT");
System.out.println(responseString);
}
}
curl --location --request PUT 'https://dapi.nowcoder.com/v1/papers/17131890/test_users/2115086' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
--data-raw 'api_key=huaxinjiayou%40126.com¬e=%E8%BF%99%E4%B8%AA%E8%80%83%E7%94%9F%E6%98%AF%E9%80%9A%E8%BF%87API%E6%B7%BB%E5%8A%A0%E7%9A%84&phone=18812341234&shen1_fen4_zheng4=431123199911116666&name=%E9%83%AD%E5%87%AF%E4%BF%8A&xue2_xiao4=%E6%B8%85%E5%8C%97%E5%A4%A7%E5%AD%A6&zhi2_wei4=Java%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88&key=gkj&email=guokaijun%40nowcoder.com&xue2_li4=%E6%9C%AC%E7%A7%91'
{
"code" : 0,
"msg" : "OK",
"data" : null
}
接口用于更新单个考生的信息
接口地址
PUT /papers/{paperId}/test_users/{id}
请求参数
参数 | 类型 | 是否必传 | 默认值 | 描述 |
---|---|---|---|---|
paperId | long | 是 | 需填充在url中 | 试卷id |
id | long | 是 | 需填充在url中 | 考生id |
name | String | 是 | 考生姓名 | |
key | String | 是 | 考试编号,在同一个试卷内唯一确定一个用户的字符串,不能包含emoji字符 | |
departmentId | long | 否 | 所属部门,为0表示公开 | |
userType | int | 否 | 考生类型 | |
note | String | 否 | 备注 | |
notice | boolean | 否 | 是否发送通知,true发送、false不发送 | |
emailTemplateId | int | 否 | 默认模板 | 仅在notice=true时有效,用于指定本次通知的邮件版本 |
smsTemplateId | int | 否 | 默认模板 | 仅在notice=true时有效,用于指定本次通知的短信版本 |
返回数据
无需关心返回数据,接口请求成功则视为删除成功
批量查询当前考生状态
接口地址
/v1/partners/paper/batch_user_status
请求方法和类型
post, application/json
请求和回报参数见右边
请求参数:
{
"paperId": "必填,long,试卷id",
"userKeyList": "必填,string array,考试编号,单次最多查询50个考生"
}
回包参数:
{
"code": "int:0表示成功,非0表示失败",
"msg": "string:code非0时表示报错原因",
"data": {
"userList": [
{
"id": "long, 考生id",
"userKey": "string, 考试编号",
"status": "int, 考生状态,ai面试场景:1.面试未开始,2.待面试,3.已过期,4.面试中,5.已完成,6.判题完成;笔试场景:210.未进入考试,220.已开考,230.作答完成"
}
]
}
}
笔试-考生成绩管理
查询单个考生考试结果
public class Main {
@Test
public void testGetUserTestInfo() {
String path = "/papers/usertestinfo";
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
mvMap.put("paperId", 17131674);
mvMap.put("userkey", "qwe");
mvMap.put("needCategoryScore", true);
mvMap.put("needCheatInfo", true);
mvMap.put("needJudgeInfo", true);
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");
System.out.println(responseString);
}
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/papers/usertestinfo?api_key=huaxinjiayou@126.com&needCategoryScore=true&needCheatInfo=true&needJudgeInfo=true&paperId=17131674&userkey=qwe' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'
{
"code" : 0,
"msg" : "OK",
"data" : [ {
"paperName" : "编程题测试2",
"pdfUrl" : "https://dapi.nowcoder.com/v1/test-pdf/F23269B6DFB0F586?paperId=17131674&tokenValue=cbe1f318a47b50c7e7f096ff6cbf2ed8746df596943e48f971a2a191a36ab07d&download=false",
"userScore" : 0.0,
"paperScore" : 60,
"status" : 2,
"cheatStatus" : 3,
"beginTime" : 1626785242000,
"finishTime" : 1626797842000,
"createTime" : 1626785226000,
"apiCategoryScores" : [ {
"score" : 0.0,
"categoryType" : 5,
"questionType" : 5,
"categoryName" : "问答"
} ],
"rankPercent" : 0.25,
"cheatReasonList" : null,
"judgeAssignAccountAndJudgeStatuses" : null,
"judgeRemarkInfos" : null,
"cheatInfoDesc" : null,
"finalScore" : true
} ]
}
查询单个考生考试结果信息。如果考生没有参加考试无法查到信息。
接口地址
GET /papers/usertestinfo
请求参数
参数 | 类型 | 是否必传 | 默认值 | 描述 |
---|---|---|---|---|
paperId | Long | 否 | 试卷id(不传的话会查询所有试卷中考试编号为userkey的考生,传了就查指定试卷中的) | |
userkey | String | 是 | 考试编号,对应添加考生接口中key字段值 | |
needCategoryScore | boolean | 否 | 是否需要不同题型得分 | |
needCheatInfo | boolean | 否 | 是否需要作弊信息 | |
needJudgeInfo | boolean | 否 | 是否需要人工判题信息,仅在paperId>0时有效 | |
pdfFileType | int | 否 | 0 | 0表示返回在线预览的pdf地址,1表示返回可下载的pdf地址 |
返回数据
接口的返回数据由考生信息与考生测评信息结合而成。
参数 | 描述 |
---|---|
paperName | 试卷名称 |
pdfUrl | 报告pdf链接 |
webReportUrl | 在线报告链接 |
userScore | 考生得分 |
paperScore | 试卷满分 |
testResult | 表示考试结果,取值passed表示“通过”,failed表示“不通过” |
rejectionReasons | 表示筛选不通过的原因(仅在testResult="failed"时有效);原因存在多项时,采用";"进行拼接;没值时用null表示 |
specialNotes | 表示报告中需要特别关注的事情;存在多个关注事项时,采用";"进行拼接;没值时用null表示 |
moduleScores | 表示考生按能力项维度聚合的得分情况。这个参数会有多个,每一个的参数格式是moduleScore|moduleName 如 "70.5|英语能力 ",moduleScore为skillScore的上级维度 |
skillScores | 表示考生按技能项维度聚合的得分情况。这个参数会有多个,每一个的参数格式是skillScore|skillName 如 "60.5|抗压能力 ",skillScore为moduleScore的下级维度 |
status | 考生未参加考试(-1),系统判题未完成(1), 考试进行中(0), 已交卷(2), 人工判题完成(4) |
cheatStatus | 作弊检测未完成(0), 作弊(1), 未作弊(2), 作弊疑似(3) |
beginTime | 开始答卷时间 |
finishTime | 交卷时间 |
createTime | 笔试的安排时间 |
elapseTime | 测评消耗时间,单位是秒 |
rankPercent | 浮点型排名百分比 |
rankScore | 考生得分中位数 |
finalScore | 是否是最终成绩:需要人工判题的,若人工判题完成则为最终成绩;无需人工判题的,只要交卷就是最终成绩 |
judgeRemarkInfos | 判题备注,对象数组 |
cheatInfoDesc | 作弊描述信息,单个字符串 |
apiCategoryScores | 各个目录得分,对象数组 |
cheatReasonList | 以文字表述的作弊原因字符串数组。具体信息见链接 |
judgeAssignAccountAndJudgeStatuses | 判题备注 ,对象数组。分配的判题账户列表以及相应的完成状态 |
headUrl | 考生自拍头像链接 |
目录得分数据结构
参数 | 描述 |
---|---|
score | 目录得分 |
categoryType | 目录类型 |
questionType | 题目类型:单选(1), 不定项选择(2), 填空(3), 编程(4), 问答(5) , |
categoryName | 目录名称 |
目录得分数据结构
参数 | 描述 |
---|---|
userId | 判题的账号id |
userName | 判题的账号名称 |
judgeStatus | 判题完成的状态,值枚举:已判题/未判题 |
判题备注数据结构
参数 | 描述 |
---|---|
userName | 判题的账号名称 |
summaryRemark | 总体评价 |
questionRemarkInfos | 各题目备注,对象数组 |
题目备注数据结构
字段 | 描述 |
---|---|
questionName | 例如:填空题第1题 |
remark | 备注内容 |
获取某个用户拥有卷子的测评信息
public class Main {
@Test
public void testGetPaperTestsInfo() {
String path = String.format("/tests/poid-%d", ConfigUtils.getNowcoderHrId());
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
mvMap.put("projectIdList", 2227);
mvMap.put("paperIds", 17131674);
mvMap.put("page", 1);
mvMap.put("pageSize", 1);
mvMap.put("order", 2);
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "POST");
System.out.println(responseString);
}
}
curl --location --request POST 'https://dapi.nowcoder.com/v1/tests/poid-30' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
--data-raw 'api_key=huaxinjiayou%40126.com&pageSize=1&page=1&projectIdList=2227&paperIds=17131674&order=2'
{
"code" : 0,
"msg" : "OK",
"data" : {
"totalCount" : 4,
"totalPage" : 4,
"currentPage" : 1,
"datas" : [ {
"id" : 1838108,
"encryptId" : null,
"actorId" : 2114808,
"paperId" : 17131674,
"paperName" : "编程题测试2",
"finishTime" : 1626797842000,
"status" : 2,
"score" : 0.0,
"paperScore" : 60.0,
"paperOpenCount" : 4,
"createTime" : 1626785242000,
"actorType" : 10,
"elapseTime" : 40,
"leaveCount" : 4,
"headUrl" : "",
"signatureUrl" : null,
"ipAddress" : "北京市",
"ip" : "123.118.109.227",
"cheated" : 3,
"ncUser" : {
"id" : 2114808,
"email" : null,
"nickname" : "aweqwe",
"phone" : null,
"displayName" : "aweqwe"
},
"user" : {
"id" : 2114808,
"email" : null,
"nickname" : "aweqwe",
"phone" : null,
"displayName" : "aweqwe"
},
"testUserKey" : "qwe",
"questionCount" : 0,
"rightCount" : 0,
"numberRank" : 1,
"percentRank" : 0,
"difficulty" : 0,
"key" : null,
"keyTitle" : null,
"name" : null,
"nameTitle" : null,
"creatorHrUid" : 0,
"creatorHrName" : "管理员",
"pdfUrl" : null,
"testResultUrl" : "https://dapi.nowcoder.com/v1/test-pdf/F23269B6DFB0F586?paperId=17131674&tokenValue=cbe1f318a47b50c7e7f096ff6cbf2ed8746df596943e48f971a2a191a36ab07d&download=false",
"notJudgedTypes" : [ 3 ],
"needJudge" : true,
"picCount" : 0,
"review" : null,
"questionTypeList" : null,
"categoryTypeList" : null,
"signUpFields" : null,
"userExt" : {
"phone" : "",
"name" : "aweqwe",
"xue2_xiao4" : "",
"zhi2_wei4" : "",
"email" : "",
"xue2_li4" : "",
"key" : "qwe"
},
"remarkList" : null,
"antiJumpOut" : false,
"allowCamera" : false,
"allowScreenRecord" : false,
"monitorPhone" : false,
"needMobileCamera" : false,
"hasCodeProblem" : false,
"hasHistoryData" : false,
"judgingPermission" : null,
"canSee" : true,
"price" : 30.0,
"cheatReasonList" : [ ],
"testUserNote" : null,
"paperSimulation" : false,
"categoryScores" : null,
"categoryTotalScores" : null,
"timeCount" : null,
"resumeId" : 0,
"resumePermit" : 0,
"recruitProjectId" : 0,
"judged" : true,
"notJudgedReason" : null,
"judgingTip" : "需要人工阅卷的题目答案为空,系统自动判题",
"resumeForJudge" : null,
"deliverId" : 0,
"testPeriod" : null,
"clientSystem" : 1,
"longValidTime" : true,
"previewOverdueTime" : null,
"tagNameList" : [ ],
"bought" : true,
"tagList" : null
} ],
"ext" : {
"lackCount" : "0"
}
}
}
根据查询条件,查询当前账户下的考生成绩。
接口地址
POST /tests/poid-{paperOwnerId}
请求参数
参数 | 类型 | 是否必传 | 描述 |
---|---|---|---|
paperOwnerId | int | 必传,需填充在url中 | 当前用户的HRId |
paperIds | List<Long> | 非必传 | 用于筛选试卷id,可不传 |
projectIdList | List<Long> | 非必传 | 用于筛选项目id,可不传 |
page | int | 非必传,从1开始,默认为1 | 当前页数 |
pageSize | int | 非必传,默认为20 | 每页数量 |
orderBy | int | 非必传,默认0 | 根据什么排序,默认为0;0根据考生开始测评的时间排序,1根据考生完成测评的时间排序,2根据考生测评的分数排序 |
order | int | 非必传,默认1 | 升序还是降序,默认为1升序。1代表升序,2代表降序。 |
返回数据
参数 | 描述 |
---|---|
totalCount | 列表数据总数 |
totalPage | 列表总页数 |
currentPage | 当前是第几页,从1开始 |
datas | 考生成绩数据数组 |
考生成绩对象数据结构
参数 | 描述 |
---|---|
id | 测评ID |
encryptId | 加密id |
actorId | 测评用户ID |
paperId | 测评点的试卷 |
paperName | 试卷名字 |
finishTime | 测评完成时间 |
status | 测评状态 |
score | 测评的分数 |
paperScore | 试卷总分 |
paperOpenCount | 试卷到场人数 |
createTime | 测评开始时间 |
actorType | 测评用户的类型 |
elapseTime | 测评消耗时间,单位是秒 |
leaveCount | 跳出次数 |
headUrl | 头像 |
signatureUrl | 签名url |
ipAddress | 考试地址 |
ip | 考生考试ip地址 |
cheated | 是否作弊:0-作弊检测任务未完成,1-作弊,2-未作弊,3-疑似作弊 |
testUserKey | 考试测评用户的主key |
questionCount | 试题数量 |
rightCount | 试题正确的数量 |
numberRank | 名次 |
percentRank | 百分比排名 |
key | 唯一识别用户的Key |
keyTitle | key的标题 |
name | 测评用户名字 |
nameTitle | 测评用户名字的标题 |
creatorHrUid | 创建测评用户的hr的uid |
creatorHrName | 创建测评用户的hr名字 |
pdfUrl | 测评结果的PDF地址 |
testResultUrl | 笔试报告地址,三方系统请使用此链接查看笔试报告 |
notJudgedTypes | 不判题的题目类型 |
needJudge | 试卷是否需要人工判题 |
picCount | 截图的数量 |
review | 牛客系统评语 |
questionTypeList | 题型 |
signUpFields | 需要录入的考生信息 |
judgingPermission | 面试官查看权限 |
cheatReasonList | 作弊原因,仅在cheated=1的时候有值,具体信息见链接 |
judged | 是否已经判题 |
notJudgedReason | 未判题的原因 |
clientSystem | 答题设备1表示pc ,2表示ios 3表示android |
tagNameList | 判题所打的标签名字列表 |
笔试-回调服务
笔试回调服务以考生为维度进行回调,回调的信息为考生信息、考生的考试信息等信息。 回调地址为业务方在调用添加考生接口(POST /papers/{paperId}/test_user)中传入的callback参数。
回调类型、回调时机与回调配置
下面这些回调类型需要在调用创建考生接口时,添加callback
参数配置回调地址即可订阅一个考生下列回调类型的回调。
回调类型 | 回调时机 | 回调说明 |
---|---|---|
完成考试 | 考生手动交卷或考试时间截止自动交卷 | 无 |
作弊检测完成 | 牛客后台完成了对考生的作弊检测 | 如果存在作弊重判,可能触发多次回调 |
人工判题完成 | 牛客系统中有用户对考生进行了人工判题 | 仅对开启人工判题的试卷有效 |
考生被删除 | 在牛客系统或通过API删除了某个考生 | 只允许考前删除考生,不涉及成绩报告相关数据 |
附件上传结束 | 到了试卷设置附件上传截止时间或这期间的每天0点 | 仅对考后仍允许上传附件的试卷有效 |
下面这些回调类型需要联系牛客开发人员。进行配置
回调类型 | 回调时机 | 回调说明 |
---|---|---|
考试结束 | 非长期有效试卷考试结束 | 无 |
成绩报告变化 | 考生成绩报告发生变化 | 无 |
如果无特殊要求,建议回调接收方按“可重入”的思路进行方案设计,默认以最新1次的回调结果为准。
回调参数
通用回调参数
完成考试
、作弊检测
、人工判题
、考试结束
和成绩报告变化
这几种回调类型采用的时通用的回调参数。
考生删除
、链接过期
等回调事件,不涉及成绩报告相关信息。
回调字段 | 类型 | 是否必填 | 描述 |
---|---|---|---|
callbackType | int | 是 | 笔试场景下的回调类型:1.人工判题完成,3.完成考试,4.考试结束,5.成绩报告变化,6.作弊检测完成,8.考生被删除。 AI面试场景下的回调类型:201. 候选人被删除, 202. ai面试结束, 203. ai面试判题完成, 204. ai面试pdf报告生成完毕。使用建议:非特殊需要,不建议客户方对callbackType进行任何判断,牛客成绩报告默认均以最后1次回调为准,客户方客户保证回调操作可重入/覆盖式更新即可 |
testId | String | 是 | 测评id唯一标识(String类型),对应到添加考生接口返回的考生实体中的testId字段 |
numTestId | long | 是 | 测评id唯一标识(long类型),对应到添加考生接口返回的考生实体中的id字段 |
key | String | 是 | 业务侧用户唯一标识,对应到考生实体的userKey字段 |
status | String | 否 | 测评的状态 NOT_DO-未做题,DOING-正在做题,DONE-做完题,JUDGED-人工阅卷完成, CHEAT_DETECT_DONE-作弊检测完成,DELETE-删除 |
cheatStatus | int | 否 | 作弊检测状态 作弊检测未完成(0), 作弊(1), 未作弊(2), 作弊疑似(3) |
cheatReasonList | String | 否 | 以文字表述的作弊原因字符串数组,具体格式为json中的string array转换出来的字符串。具体信息见链接,有值示例:["摄像头监控异常"],无值示例:[] |
testStartTime | long | 是 | 考生开始考试时间(豪秒级) |
testFinishTime | long | 是 | 考生交卷时间(豪秒级) |
headUrl | String | 否 | 考生自拍头像链接 |
score | float | 否 | 考生试卷总得分(%.1f),笔试场景默认为必传,AI面试场景可能为null |
scoreLeverType | int | 否 | 取值:0表示百分制形式;1表示5星形式; |
scoreLever | float | 否 | 取值定义由scoreLeverType控制,当ScoreLeverType=0时,取值为score(%0.1f)字段值;当scoreLeverType=1时,取值为0.0,0.5,1.0,1.5,...,4.5,5.0,分别对应到5星档位; |
testResult | String | 否 | 表示考试结果,取值passed表示“通过”,failed表示“不通过” |
rejectionReasons | String | 否 | 表示筛选不通过的原因(仅在testResult="failed"时有效);原因存在多项时,采用";"进行拼接;没值时用null表示 |
specialNotes | String | 否 | 表示报告中需要特别关注的事情;存在多个关注事项时,采用";"进行拼接;没值时用null表示 |
isFinalScore | boolean | 是 | 是否是用户的最终成绩 |
moduleScores | List[String] | 是 | 表示考生按能力项维度聚合的得分情况。这个参数会有多个,每一个的参数格式是moduleScore|moduleName 如 "70.5|英语能力 ",moduleScore为skillScore的上级维度 |
moduleScoreLevers | List[String] | 是 | 表示考生按能力项维度聚合的得分等级情况。这个参数会有多个,每一个的参数格式是moduleScoreLever|moduleName 如 "3.5|英语能力 ",其中的moduleName与moduleScores中的moduleName一一对应 |
skillScores | List[String] | 是 | 表示考生按技能项维度聚合的得分情况。这个参数会有多个,每一个的参数格式是skillScore|skillName 如 "60.5|抗压能力 ",skillScore为moduleScore的下级维度 |
skillScoreLevers | List[String] | 是 | 表示考生按技能项维度聚合的得分等级情况。这个参数会有多个,每一个的参数格式是skillScoreLever|skillName 如 "4.0|抗压能力 ",其中的skillName与skillScores中的skillName一一对应 |
categoryScores | List[String] | 是 | 表示考生按试卷目录维度聚合的得分情况。这个参数会有多个,每一个的参数格式是score|categoryId|categoryName 如1.5|100| 选择题。笔试场景默认为必传,AI面试场景为空 |
extDataItems | List[String] | 是 | 可扩展的信息维度。这个参数会有多个,每一个的参数格式是json string。结构:{"id": "xx", "name": "xxx", "value": "xxx"} 例子:{"name":"不通过原因","id":"rejectionReasons","value":"候选人放弃面试"} |
rank | int | 否 | 考生排名,这个排名是在回调的时间点计算出来 |
isCheated | boolean | 是 | true、false 是否作弊,疑似作弊时为null(待废弃,以cheatStatus字段为准) |
resultPdfUrl | String | 否 | 测评成绩报告的PDF版本的URL,支持按需配置 |
onlineTestResultUrl | String | 否 | 测评成绩报告的网页版本的URL,支持按需配置 |
paperName | String | 是 | 试卷名称 |
paperId | long | 是 | 试卷id |
paperScore | int | 是 | 试卷满分,笔试和试卷中的题目总分有关,ai面试默认100分 |
needJudge | boolean | 否 | 试卷是否需要人工判题,true表示需要,false不表示不需要 |
isArchived | boolean | 是 | 代表当前考生是否可以归档,true表示可以归档,false表示还不能归档(该标识仅代表系统判定考生分数不再改变,但是可能存在手动修改考生成绩以及多次重新判题修改分数的情况) |
public class Main {
@Test
public void escapeOnlineTestResultUrl() throws UnsupportedEncodingException {
String onlineTestResultUrl = "https://dhr.nowcoder.com/console?theme=tinyLeft&access_token=1b60b47668a2459416985edfb4c4a2207cf318999c51715e00f722fd235b0b0b#paper/{\"tab\":\"index\",\"action\":\"candidate/result/index\",\"testId\":1837423}";
int anchorIndex = onlineTestResultUrl.indexOf("#paper/");
int encodeStrStartIndex = anchorIndex + "#paper/".length();
String anchorStr = StringUtils.substring(onlineTestResultUrl, encodeStrStartIndex);
String encodedAnchorStr = URLEncoder.encode(anchorStr, "UTF-8");
System.out.println(onlineTestResultUrl.substring(0, encodeStrStartIndex) + encodedAnchorStr);
}
}
考生被删除
考试被删除时,只会回传考生的信息,具体参数如下:
回调字段 | 描述 |
---|---|
hrId | 用户id |
status | 测评的状态,在考生删除时为:DELETE(删除) |
id | 考生id |
paperId | 试卷id |
paperName | 试卷名称 |
key | 唯一确定一个用户的字符串 |
note | 考生备注 |
除了这些字段外,还会带上创建考生时填入的其他字段比如:phone
、email
等字段。更多考生个人信息字段详见:添加考生接口
笔试-免登录判题
无需登录系统,开放给第三方的判题能力,该接口可获取判题链接,判题链接会失效过期,无需保存,需要时实时获取即可
接口地址
GET /judging-tests/quick-judge-url
请求参数
参数 | 类型 | 是否必传 | 默认值 | 描述 |
---|---|---|---|---|
paperId | Long | 是 | 试卷id | |
userKey | String | 是 | 考试编号,对应添加考生接口中key字段值 |
返回数据
免登录判题短链
注意:链接有效期默认是2个月,从第一次请求接口生成时算起;同一个考生判题链接只会生成一次重复请求接口返回的是同一个判题链接
参数类型 | 描述 |
---|
String 免登录判题短链
面试-项目管理
一个面试项目通常代表一次面试计划,候选人信息字段设置、现场管理功能都是以项目为单位。
面试项目实体的关键字段
字段名 | 类型 | 描述 |
---|---|---|
id | long | id |
name | String | 名称 |
remark | String | 备注 |
jobNums | long | 职位数目 |
studentNums | long | 面试数目 |
roundNums | long | 最大轮次数 |
status | int | 状态,0正常、1归档 |
type | int | 类型,0用户创建、1系统创建、2面试官自主预约 |
star | int | 是否置顶,0不置顶、1置顶 |
获取所有面试项目
public class Main {
@Test
public void testGetProjects() {
String path = "/user/interview-projects/all";
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");
System.out.println(responseString);
}
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/user/interview-projects/all?api_key=huaxinjiayou@126.com' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'
{
"code" : 0,
"msg" : "OK",
"data" : [ {
"id" : 1638,
"name" : "小程序测试",
"remark" : "",
"jobNums" : 2,
"studentNums" : 32,
"roundNums" : 5,
"status" : 1,
"type" : 0,
"star" : 1,
}, {
"id" : 1746,
"name" : "小程序",
"remark" : "",
"jobNums" : 10,
"studentNums" : 88,
"roundNums" : 4,
"status" : 0,
"type" : 0,
"star" : 1,
}, {
"id" : 1291,
"name" : "liumeng测试",
"remark" : "liumeng 测试",
"jobNums" : 30,
"studentNums" : 357,
"roundNums" : 14,
"status" : 0,
"type" : 0,
"star" : 0,
}, {
"id" : 1293,
"name" : "测试",
"remark" : "呵呵呵",
"jobNums" : 15,
"studentNums" : 130,
"roundNums" : 8,
"status" : 0,
"type" : 0,
"star" : 0,
}]
}
接口地址
GET /user/interview-projects/all
请求参数
空
返回数据
字段名 | 类型 | 描述 |
---|---|---|
data | array | 面试项目数组,关键信息见面试项目关键返回字段 |
面试-面试管理
面试实体关键字段
字段名 | 类型 | 描述 |
---|---|---|
id | long | id |
interviewProjectId | long | 面试项目id |
intervieweeName | String | 面试者(候选人)姓名 |
intervieweeEmail | String | 面试者(候选人)的邮箱 |
intervieweePhone | String | 面试者(候选人)的手机 |
jobType | int | 技术or非技术, 1技术面试、2非技术面试 |
job | String | 职位名称 |
deliverId | String | 投递编号 |
resumeUrl | String | 用户简历地址 |
testResultUrl | String | 笔试结果 |
round | int | 当前处于第几轮 |
rounds | array | 轮次实体关键字段 |
interviewReportUrl | String | 面试报告地址 |
startTime | long | 毫秒级时间戳、面试开始时间,即第一轮面试开始时间 |
expireTime | long | 毫秒级时间戳、过期时间,到达过期时间且面试未使用过会标记为过期并且退费 |
elapsedTime | int | 使用时长,单位毫秒 |
validTime | int | 总的可用时长,单位是秒, 如果为0则默认为3小时。使用时长超过可用时长后面试房间会无法使用,除非延长面试 |
interviewerUrl | String | 面试官面试地址 |
interviewerOfflineUrl | String | 面试官线下面试地址, 只有开启了线下面试权限才能使用 |
intervieweeUrl | String | 候选人面试地址 |
status | int | 状态,0表示正常,1表示删除,2表示过期。 |
轮次实体关键字段
字段名 | 类型 | 描述 |
---|---|---|
id | long | id |
interviewId | long | 面试id |
round | int | 第几轮面试 |
bookTime | long | 预约时间、毫秒级时间戳 |
multi | int | 是否多对一面试,0一对一面试,1多对一面试 |
offline | int | 是否线下面试, 0线上,1线下 |
interviewerName | String | 一对一面试字段,面试官姓名 |
interviewerPhone | String | 一对一面试字段,面试官电话 |
interviewerEmail | String | 一对一面试字段,面试官邮箱 |
userList | array | 多对一面试字段,面试官实体关键字段 |
score | int | 面试评分,0未评分, 1-2未通过,3-5通过 |
evaluation | String | 评语 |
elapsedTime | long | 该轮使用时长,单位毫秒 |
intervieweeImage | String | 候选人面试过程中的一张照片 |
status | int | 轮次状态,0未开始、1进行中、3结束、4删除、5暂停、7面试淘汰被自动取消 |
面试官实体关键字段
字段名 | 类型 | 描述 |
---|---|---|
id | long | id |
interviewId | long | 面试id |
roundId | long | 轮次id |
round | int | 第几轮面试 |
name | String | 面试官姓名 |
phone | String | 面试官电话 |
String | 面试官邮箱 | |
host | int | 是否主持人,0非主持人,1主持人 |
evaluation | String | 面试评价 |
elapsedTime | long | 面试官面试时长, 单位毫秒, 非实时更新 |
status | int | 状态, 0初始、1删除、2面试中、4结束 |
额度检查
优先检查服务对应可用次数,当可用次数不够时使用账户余额进行检查
public class Main {
@Test
public void testCheckBalance() {
String path = "/interviews/checkBalance";
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
mvMap.put("techCount", 10);
mvMap.put("unTechCount", 10);
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");
System.out.println(responseString);
}
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/interviews/checkBalance?api_key=huaxinjiayou@126.com&unTechCount=10&techCount=10' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'
{
"code" : 0,
"msg" : "OK",
"data" : {
"hostId" : 30,
"adminHrId" : 30,
"moneyEnough" : true,
"subAccountLimitEnough" : true
}
}
接口地址
GET /interviews/checkBalance
请求参数
参数 | 类型 | 是否必填 | 描述 |
---|---|---|---|
techCount | int | 必填 | 技术类面试数量 |
unTechCount | int | 必填 | 非技术类面试数量 |
copilotFlag | boolean | 非必填 | 是否开启智能面试(同时对techCount和unTechCount生效),不传默认是false |
返回数据
参数 | 类型 | 描述 |
---|---|---|
hostId | long | 当前账号id |
adminHrId | long | 当前账号的公司主账号id |
moneyEnough | boolean | 公司主账号的余额是否充足 |
subAccountLimitEnough | boolean | 子账号分配的业务额度是否充足 |
创建面试
public class Main {
@Test
public void testCreateInterview(){
String path = "/interviews";
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
mvMap.put("projectId", 2071);
mvMap.put("intervieweeName", "nowcoder");
mvMap.put("intervieweeEmail", "ee@nowcoder.com");
mvMap.put("intervieweePhone", "10000000000");
mvMap.put("copilotFlag", false);
mvMap.put("job", "java");
mvMap.put("jobType", 1);
mvMap.put("jobDesc", "职业介绍");
mvMap.put("deliverId", "TD6879239819");
mvMap.put("resumeUrl", "https://www.nowcoder.com");
mvMap.put("resumeText", "简历文本内容");
mvMap.put("testResultUrl", "https://www.nowcoder.com");
mvMap.put("rounds", "2021-08-26 11:00:00|coder|10000000000|er@nowcoder.com|0|0");
mvMap.put("rounds", "2021-08-26 11:30:00|-|-|-|0|1");
mvMap.put("multiUsers", "2|0|coder1|er1@nowcoder.com|10000000001|1");
mvMap.put("multiUsers", "2|0|coder2|er2@nowcoder.com|10000000002|0");
mvMap.put("callback", null);
mvMap.put("callback2", null);
mvMap.put("finishRedirectUrl", "https://www.nowcoder.com");
mvMap.put("finishRedirectUrls", "https://www.nowcoder.com");
mvMap.put("finishRedirectUrls", "https://www.nowcoder.com");
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "POST");
System.out.println(responseString);
}
}
curl --location --request POST 'https://dapi.nowcoder.com/v1/interviews' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
--data-raw 'api_key=huaxinjiayou%40126.com&intervieweeName=nowcoder&multiUsers=2%7C0%7Ccoder1%7Cer1%40nowcoder.com%7C10000000001%7C1&multiUsers=2%7C0%7Ccoder2%7Cer2%40nowcoder.com%7C10000000002%7C0&finishRedirectUrl=https%3A%2F%2Fwww.nowcoder.com&intervieweePhone=10000000000&deliverId=TD6879239819&intervieweeEmail=ee%40nowcoder.com&resumeUrl=https%3A%2F%2Fwww.nowcoder.com&testResultUrl=https%3A%2F%2Fwww.nowcoder.com&job=java&jobType=1&projectId=2071&rounds=2021-08-26+11%3A00%3A00%7Ccoder%7C10000000000%7Cer%40nowcoder.com%7C0%7C0&rounds=2021-08-26+11%3A30%3A00%7C-%7C-%7C-%7C0%7C1&finishRedirectUrls=https%3A%2F%2Fwww.nowcoder.com&finishRedirectUrls=https%3A%2F%2Fwww.nowcoder.com'
{
"code" : 0,
"msg" : "OK",
"data" : {
"id" : 36724903,
"interviewProjectId" : 2071,
"intervieweeName" : "nowcoder",
"intervieweeEmail" : "ee@nowcoder.com",
"intervieweePhone" : "10000000000",
"jobType" : 1,
"job" : "java",
"deliverId" : "TD6879239819",
"resumeUrl" : "https://www.nowcoder.com",
"testResultUrl" : "https://www.nowcoder.com",
"round" : 0,
"rounds" : [ {
"id" : 289423,
"interviewId" : 36724903,
"round" : 1,
"bookTime" : 1629946800000,
"multi" : 0,
"offline" : 0,
"interviewerName" : "coder",
"interviewerPhone" : "10000000000",
"interviewerEmail" : "er@nowcoder.com",
"userList" : null,
"score" : 0,
"evaluation" : null,
"elapsedTime" : 0,
"status" : 0,
}, {
"id" : 289424,
"interviewId" : 36724903,
"round" : 2,
"bookTime" : 1629948600000,
"multi" : 1,
"offline" : 0,
"interviewerName" : null,
"interviewerPhone" : null,
"interviewerEmail" : null,
"userList" : [{
"id" : 186503,
"interviewId" : 36724903,
"roundId" : 289424,
"round" : 2,
"name" : "coder1",
"email" : "er1@nowcoder.com",
"phone" : "10000000001",
"host" : 1,
"evaluation" : null,
"elapsedTime" : 0,
"status" : 0
}, {
"id" : 186504,
"interviewId" : 36724903,
"roundId" : 289424,
"round" : 2,
"name" : "coder2",
"email" : "er2@nowcoder.com",
"phone" : "10000000002",
"host" : 0,
"evaluation" : null,
"elapsedTime" : 0,
"status" : 0
}],
"score" : 0,
"evaluation" : null,
"elapsedTime" : 0,
"status" : 0
}],
"interviewReportUrl" : "https://dapi.nowcoder.com/v1/interview-report/712E34F318A80DEC5D2B1AAD67C4DCC3/report_pdf?code=NstxvwnE",
"startTime" : null,
"expireTime" : 1635072309584,
"elapsedTime" : 0,
"validTime" : 0,
"interviewerUrl" : "https://examd.nowcoder.com/interview/36724903/interviewer?code=NstxvwnE",
"interviewerOfflineUrl" : "https://examd.nowcoder.com/interview/36724903/offline?code=NstxvwnE",
"intervieweeUrl" : "https://examd.nowcoder.com/interview/36724903/interviewee?code=WNDyBdkI",
"status" : 0
}
}
接口地址
POST /interviews
请求参数
参数 | 类型 | 是否必填 | 描述 |
---|---|---|---|
projectId | long | 非必填 | 所属项目id |
intervieweeName | String | 非必填 | 面试者的姓名 |
intervieweeEmail | String | 非必填 | 面试者email |
intervieweePhone | String | 非必填 | 面试者手机号码 |
copilotFlag | boolean | 非必填(默认false) | 是否开启智能面试 |
job | String | 非必填 | 面试职位名称 |
jobType | int | 必填 | 职位类型1-技术,2-非技术 |
jobDesc | String | 非必填(长度上限4K) | 职位介绍 |
deliverId | String | 非必填 | 投递编号 |
resumeUrl | String | 非必填 | 简历URL |
resumeText | String | 非必填(长度上限12K) | 简历文本内容 |
testResultUrl | String | 非必填 | 笔试结果URL |
rounds | array | 必填 | 轮次信息字符串 |
multiUsers | array | 多对一面试必填(一对一面试非必填) | 多对一面试字段,面试官信息字符串 |
callback | String | 非必填(想使用对应回调功能必填) | 面试轮次评价回调, 录音完成回调 |
callback2 | String | 非必填(想使用对应回调功能必填) | 面试状态回调 |
finishRedirectUrl | String | 非必填(想使用对应回调功能必填) | 面试结束后跳转链接,一般用于三方对接填写面试评价使用, 搭配评分接口使用 |
finishRedirectUrls | array | 非必填(想使用对应回调功能必填) | 面试结束后跳转链接,一般用于三方对接填写面试评价使用, 搭配评分接口使用,这里适用于每一轮都需要不同的跳转链接,大小必须和rounds参数一样 |
轮次参数字段
参数 | 类型 | 是否必填 | 描述 |
---|---|---|---|
bookTime | String/long | 非必填 | 预约时间, yyyy-MM-dd HH:mm:ss 或者 毫秒级时间戳 |
interviewerName | String | 非必填 | 一对一面试字段,面试官姓名 |
interviewerPhone | String | 非必填 | 一对一面试字段,面试官号码 |
interviewerEmail | String | 非必填 | 一对一面试字段,面试官邮箱 |
offline | int | 必填 | 0线上、1线下 |
multi | int | 必填 | 0一对一面试、1多对一面试 |
使用时按照列表顺序以'|'为分割符拼接起来,为空的参数可以用'-'替代
面试官参数字段
参数 | 类型 | 是否必填 | 描述 |
---|---|---|---|
round | int | 非必填 | 第几轮的面试官 |
role | int | 非必填 | 固定值0 |
name | String | 非必填 | 面试官姓名 |
String | 非必填 | 面试官邮箱 | |
phone | String | 非必填 | 面试官号码 |
host | int | 必填 | 0非主持人、1主持人 |
使用时按照列表顺序以'|'为分割符拼接起来,为空的参数可以用'-'替代
返回数据
修改面试
public class Main {
@Test
public void testUpdateInterview(){
long interviewId = 36724903;
String path = String.format("/interviews/%d/interview", interviewId);
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
mvMap.put("intervieweeName", "javaCoder");
mvMap.put("intervieweeEmail", "java@nowcoder.com");
mvMap.put("intervieweePhone", "10000000000");
mvMap.put("job", "java");
mvMap.put("jobType", 1);
mvMap.put("deliverId", "TD6879239819");
mvMap.put("resumeUrl", "https://www.nowcoder.com");
mvMap.put("testResultUrl", "https://www.nowcoder.com");
mvMap.put("rounds", "289423|2021-08-26 11:00:00|coder|10000000000|er@nowcoder.com|0|0");
mvMap.put("rounds", "289424|2021-08-26 11:30:00|-|-|-|0|1");
mvMap.put("multiUsers", "186503|2|0|coder1|er1@nowcoder.com|10000000001|1");
mvMap.put("multiUsers", "186504|2|0|coder2|er2@nowcoder.com|10000000002|0");
mvMap.put("callback", null);
mvMap.put("callback2", null);
mvMap.put("finishRedirectUrl", "https://www.nowcoder.com");
mvMap.put("finishRedirectUrls", "https://www.nowcoder.com");
mvMap.put("finishRedirectUrls", "https://www.nowcoder.com");
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "PUT");
System.out.println(responseString);
}
}
curl --location --request PUT 'https://dapi.nowcoder.com/v1/interviews/36724903/interview' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
--data-raw 'api_key=huaxinjiayou%40126.com&intervieweeName=javaCoder&multiUsers=186503%7C2%7C0%7Ccoder1%7Cer1%40nowcoder.com%7C10000000001%7C1&multiUsers=186504%7C2%7C0%7Ccoder2%7Cer2%40nowcoder.com%7C10000000002%7C0&finishRedirectUrl=https%3A%2F%2Fwww.nowcoder.com&intervieweePhone=10000000000&deliverId=TD6879239819&intervieweeEmail=java%40nowcoder.com&resumeUrl=https%3A%2F%2Fwww.nowcoder.com&testResultUrl=https%3A%2F%2Fwww.nowcoder.com&job=java&jobType=1&rounds=289423%7C2021-08-26+11%3A00%3A00%7Ccoder%7C10000000000%7Cer%40nowcoder.com%7C0%7C0&rounds=289424%7C2021-08-26+11%3A30%3A00%7C-%7C-%7C-%7C0%7C1&finishRedirectUrls=https%3A%2F%2Fwww.nowcoder.com&finishRedirectUrls=https%3A%2F%2Fwww.nowcoder.com'
{
"code" : 0,
"msg" : "OK",
"data" : {
"id" : 36724903,
"interviewProjectId" : 2071,
"intervieweeName" : "javaCoder",
"intervieweeEmail" : "java@nowcoder.com",
"intervieweePhone" : "10000000000",
"jobType" : 1,
"job" : "java",
"deliverId" : "TD6879239819",
"resumeUrl" : "https://www.nowcoder.com",
"testResultUrl" : "https://www.nowcoder.com",
"round" : 0,
"rounds" : [ {
"id" : 289423,
"interviewId" : 36724903,
"round" : 1,
"bookTime" : 1629946800000,
"multi" : 0,
"offline" : 0,
"interviewerName" : "coder",
"interviewerPhone" : "10000000000",
"interviewerEmail" : "er@nowcoder.com",
"userList" : null,
"score" : 0,
"evaluation" : null,
"elapsedTime" : 0,
"status" : 0
}, {
"id" : 289424,
"interviewId" : 36724903,
"round" : 2,
"bookTime" : 1629948600000,
"multi" : 1,
"offline" : 0,
"interviewerName" : null,
"interviewerPhone" : null,
"interviewerEmail" : null,
"userList" : [{
"id" : 186503,
"interviewId" : 36724903,
"roundId" : 289424,
"round" : 2,
"name" : "coder1",
"email" : "er1@nowcoder.com",
"phone" : "10000000001",
"host" : 1,
"evaluation" : null,
"elapsedTime" : 0,
"status" : 0
}, {
"id" : 186504,
"interviewId" : 36724903,
"roundId" : 289424,
"round" : 2,
"name" : "coder2",
"email" : "er2@nowcoder.com",
"phone" : "10000000002",
"host" : 0,
"evaluation" : null,
"elapsedTime" : 0,
"status" : 0
}],
"score" : 0,
"evaluation" : null,
"elapsedTime" : 0,
"status" : 0
}],
"interviewReportUrl" : "https://dapi.nowcoder.com/v1/interview-report/712E34F318A80DEC5D2B1AAD67C4DCC3/report_pdf?code=NstxvwnE",
"startTime" : null,
"expireTime" : 1635072309584,
"elapsedTime" : 0,
"validTime" : 0,
"interviewerUrl" : "https://examd.nowcoder.com/interview/36724903/interviewer?code=NstxvwnE",
"interviewerOfflineUrl" : "https://examd.nowcoder.com/interview/36724903/offline?code=NstxvwnE",
"intervieweeUrl" : "https://examd.nowcoder.com/interview/36724903/interviewee?code=WNDyBdkI",
"status" : 0
}
}
接口地址
PUT /interviews/{id:[0-9]+}/interview
请求参数
参数 | 类型 | 是否必填 | 描述 |
---|---|---|---|
id | long | 必填 | 面试id |
intervieweeName | String | 非必填 | 面试者的姓名 |
intervieweeEmail | String | 非必填 | 面试者email |
intervieweePhone | String | 非必填 | 面试者手机号码 |
job | String | 非必填 | 面试职位名称 |
jobType | int | 必填 | 职位类型1-技术,2-非技术 |
deliverId | String | 非必填 | 投递编号 |
resumeUrl | String | 非必填 | 简历URL |
testResultUrl | String | 非必填 | 笔试结果URL |
rounds | array | 必填 | 轮次信息字符串 |
multiUsers | array | 多对一面试必填 | 多对一面试字段,面试官信息字符串 |
finishRedirectUrl | String | 非必填 | 面试结束后跳转链接,用于三方对接填写面试评价使用 |
轮次参数字段
参数 | 类型 | 是否必填 | 描述 |
---|---|---|---|
id | long | 必填 | 轮次id |
bookTime | String/long | 非必填 | 预约时间, yyyy-MM-dd HH:mm:ss 或者 毫秒级时间戳 |
interviewerName | String | 非必填 | 一对一面试字段,面试官姓名 |
interviewerPhone | String | 非必填 | 一对一面试字段,面试官号码 |
interviewerEmail | String | 非必填 | 一对一面试字段,面试官邮箱 |
offline | int | 必填 | 0线上、1线下 |
multi | int | 必填 | 0一对一面试、1多对一面试 |
使用时按照列表顺序以'|'为分割符拼接起来,为空的参数可以用'-'替代
面试官参数字段
参数 | 类型 | 是否必填 | 描述 |
---|---|---|---|
id | long | 非必填 | 面试官id |
round | int | 非必填 | 第几轮的面试官 |
role | int | 非必填 | 固定值0 |
name | String | 非必填 | 面试官姓名 |
String | 非必填 | 面试官邮箱 | |
phone | String | 非必填 | 面试官号码 |
host | int | 必填 | 0非主持人、1主持人 |
使用时按照列表顺序以'|'为分割符拼接起来,为空的参数可以用'-'替代
返回数据
取消一轮面试
public class Main {
@Test
public void testCancelInterviewRound(){
long interviewId = 36724903;
long roundId = 289424;
String path = String.format("/interviews/%d/%d", interviewId, roundId);
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
mvMap.put("cancelCurrentRoundOnly", true);
mvMap.put("needSendCancelNotice", false);
mvMap.put("cancelReason", "test");
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "DELETE");
System.out.println(responseString);
}
}
curl --location --request DELETE 'https://dapi.nowcoder.com/v1/interviews/36724903/289424' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
--data-raw 'api_key=huaxinjiayou%40126.com&needSendCancelNotice=false&cancelCurrentRoundOnly=true&cancelReason=test'
{
"code" : 0,
"msg" : "OK",
"data" : null
}
接口地址
DELETE /interviews/{id:[0-9]+}/{roundId:[0-9]+}
请求参数
参数 | 类型 | 是否必填 | 描述 |
---|---|---|---|
id | long | 必填 | 面试Id |
roundId | long | 必填 | 面试轮次id |
cancelCurrentRoundOnly | boolean | 必填(默认为false) | 是否只取消当前轮次而保留后面轮次 |
needSendCancelNotice | boolean | 必填(默认为false) | 是否发送取消通知 |
cancelReason | String | 非必填 | 取消原因 |
返回数据
空
获取面试
public class Main {
@Test
public void testGetById() {
long interviewId = 36724903;
String path = String.format("/interviews/%d", interviewId);
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");
System.out.println(responseString);
}
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/interviews/36724903?api_key=huaxinjiayou@126.com' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'
{
"code" : 0,
"msg" : "OK",
"data" : {
"id" : 36724903,
"interviewProjectId" : 2071,
"intervieweeName" : "javaCoder",
"intervieweeEmail" : "java@nowcoder.com",
"intervieweePhone" : "10000000000",
"jobType" : 1,
"job" : "java",
"deliverId" : "TD6879239819",
"resumeUrl" : "https://www.nowcoder.com",
"testResultUrl" : "https://www.nowcoder.com",
"round" : 0,
"rounds" : [{
"id" : 289423,
"interviewId" : 36724903,
"round" : 1,
"bookTime" : 1629946800000,
"multi" : 0,
"offline" : 0,
"interviewerName" : "coder",
"interviewerPhone" : "10000000000",
"interviewerEmail" : "er@nowcoder.com",
"userList" : null,
"score" : 0,
"evaluation" : null,
"elapsedTime" : 0,
"status" : 0,
}],
"interviewReportUrl" : "https://dapi.nowcoder.com/v1/interview-report/712E34F318A80DEC5D2B1AAD67C4DCC3/report_pdf?code=NstxvwnE",
"startTime" : null,
"expireTime" : 1635072309584,
"elapsedTime" : 0,
"validTime" : 0,
"interviewerUrl" : "https://examd.nowcoder.com/interview/36724903/interviewer?code=NstxvwnE",
"interviewerOfflineUrl" : "https://examd.nowcoder.com/interview/36724903/offline?code=NstxvwnE",
"intervieweeUrl" : "https://examd.nowcoder.com/interview/36724903/interviewee?code=WNDyBdkI",
"status" : 0
}
}
接口地址
GET /interviews/{id:[0-9]+}
请求参数
参数 | 类型 | 是否必填 | 描述 |
---|---|---|---|
id | long | 必填 | 面试房间id |
返回数据
获取面试房间状态
public class Main {
@Test
public void testGetRoomStatus() {
String path = "/interviews/room-status";
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
mvMap.put("roomId", 36724903);
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");
System.out.println(responseString);
}
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/interviews/room-status?api_key=huaxinjiayou@126.com&roomId=36724903' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'
{
"code" : 0,
"msg" : "OK",
"data" : {
"roomId" : 36724903,
"timeRunOut" : false,
"roomStatus" : 0,
"remainMinitus" : 180
}
}
接口地址
GET /interviews/room-status
请求参数
参数 | 类型 | 是否必填 | 描述 |
---|---|---|---|
roomId | long | 必填 | 面试id |
返回数据
参数 | 类型 | 描述 |
---|---|---|
roomId | long | 面试id |
timeRunOut | boolean | 面试是否已经超时 |
roomStatus | int | 房间状态:0-正常,1-取消,2-过期 |
remainMinitus | int | 剩余可用时长,单位:分钟. validTime - elapsedTime |
批量获取面试官、候选人在线状态
public class Main {
@Test
public void testGetPersonStatus() {
String path = "/interviews/rooms-status";
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
mvMap.put("roomIdList", 36724903);
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "GET");
System.out.println(responseString);
}
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/interviews/rooms-status?api_key=huaxinjiayou@126.com&roomIdList=36724903' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'
{
"code" : 0,
"msg" : "OK",
"data" : [ {
"roomId" : 36724903,
"intervieweeStatus" : 0,
"interviewerStatus" : 0
} ]
}
接口地址
GET /interviews/rooms-status
请求参数
参数 | 类型 | 是否必填 | 描述 |
---|---|---|---|
roomIdList | array | 必填 | 面试id数组 |
返回数据
参数 | 类型 | 描述 |
---|---|---|
roomId | long | 房间id |
intervieweeStatus | int | 候选人在线状态:0-离线, 1-在线 |
interviewerStatus | int | 面试官在线状态:0-离线, 1-在线 |
延长面试
当面试的超时导致面试无法使用时,可以通过该接口延长可用时长,每次调用会延长一次初始时长,但会收取一次费用。
public class Main {
@Test
public void testExtendInterview() {
long interviewId = 36724903;
String path = String.format("/interviews/%d/extend", interviewId);
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "PUT");
System.out.println(responseString);
}
}
curl --location --request PUT 'https://dapi.nowcoder.com/v1/interviews/36724903/extend' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
--data-raw 'api_key=huaxinjiayou%40126.com'
{
"code" : 0,
"msg" : "OK",
"data" : null
}
接口地址
PUT /interviews/{id:[0-9]+}/extend
请求参数
参数 | 类型 | 是否必填 | 描述 |
---|---|---|---|
id | long | 必填 | 面试id |
返回数据
空
轮次评分
public class Main {
@Test
public void testInterviewEvaluation() {
String path = "/user/interviews-other/round/evaluations";
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
mvMap.put("version", 1);
mvMap.put("roundId", 289423);
mvMap.put("interviewId", 36724903);
mvMap.put("roundIdx", 1);
mvMap.put("isPass", true);
String responseString = NowcoderApiRequestUtils.request(path, mvMap, "PUT");
System.out.println(responseString);
}
}
curl --location --request PUT 'https://dapi.nowcoder.com/v1/user/interviews-other/round/evaluations' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
--data-raw 'api_key=huaxinjiayou%40126.com&interviewId=36724903&roundIdx=1&isPass=true&version=1&roundId=289423'
{
"code" : 0,
"msg" : "OK",
"data" : { }
}
接口地址
PUT /user/interviews-other/round/evaluations
请求参数
参数 | 类型 | 是否必填 | 描述 |
---|---|---|---|
version | int | 必填 | 固定值 1 |
roundId | long | 必填 | 轮次id |
interviewId | long | 必填 | 面试id |
roundIdx | int | 必填 | 第几轮 |
isPass | bool | 必填 | 是否通过 |
返回数据
空json串
ai智能报告点赞点踩
接口地址
/v1/partners/interview/report/prefer
请求方法和类型
post, application/json
鉴权方式
- url后面添加api_key的query参数,如:/v1/partners/interview/report/prefer?api_key=xxx
- 请求添加一个Authorization头,值为:Bearer token,这个token可以从hr系统获得
请求和回报参数见右边
请求参数:
{
"roundId": "面试轮次id,long",
"sceneType": "场景类型,int:1.报告点赞,2.报告点踩,3.评价维度点赞,4.评价维度点踩,5.答题分析点赞,6.答题分析点踩",
"sceneId": "场景id,string:sceneType=1,2时不传;sceneType=3,4时,代表dimensionId;sceneType=5,6时,代表analysisId"
}
回包参数:
{
"code": "int:0表示成功,非0表示失败",
"msg": "string:code非0时表示报错原因"
}
面试-新版面试管理
基础规范
Content-Type
统一使用application/json
- 如果参数的非空校验、格式校验等基础校验失败,
Response Status
会返回400。其他情况Response Status
统一使用200,返回值中code
为0代表成功,其他代表失败
面试实体字段
字段名称 | 类型 | 描述 |
---|---|---|
interviewId | long | 面试id |
expireTime | long | 秒级时间戳,过期失效时间 |
validDuration | long | 可用时长 |
interviewReportUrl | String | 面试报告地址 |
interviewRounds | array | 轮次信息 |
轮次实体字段
字段名称 | 类型 | 描述 |
---|---|---|
roundId | long | 轮次id |
roundIdx | int | 第几轮,从1开始计数 |
offline | int | 线上视频面试 或 线下面试, 0表示线上视频,1表示线下面试 |
interviewType | int | 技术面试 或 非技术面试, 1表示技术面试,2表示非技术面试 |
panelFlag | int | 1对1面试 或 多对1面试, 0表示1对1面试,1表示多对1面试 |
bookTime | long | 面试预约时间,秒级时间戳 |
interviewers | array | 面试官信息 |
interviewee | json | 候选人信息 |
面试官实体字段
字段名称 | 类型 | 描述 |
---|---|---|
interviewerId | long | 多对一面试字段, 面试官id |
name | String | 面试官姓名 |
String | 面试官邮箱 | |
phone | String | 面试官电话 |
host | int | 是否主持人,0代表非主持人,1代表主持人 |
interviewUrl | String | 面试官链接,https格式 |
候选人实体字段
字段名称 | 类型 | 描述 |
---|---|---|
name | String | 候选人姓名 |
String | 候选人邮箱 | |
phone | String | 候选人电话 |
interviewUrl | String | 候选人链接,https格式,如果线下面试则不存在 |
创建面试-新版
public class Main {
@Test
public void testNewCreateInterview(){
String path = "/partners/interview/create_interview";
PartnerInterviewDTO partnerInterviewDTO = new PartnerInterviewDTO();
PartnerInterviewDTO.OrgInfo orgInfo = new PartnerInterviewDTO.OrgInfo();
orgInfo.projectId = 2071L;
orgInfo.deptId = null;
PartnerInterviewDTO.Interviewee interviewee = new PartnerInterviewDTO.Interviewee();
interviewee.name = "coder";
interviewee.email = "coder@nowcoder.com";
interviewee.phone = "10000000000";
interviewee.resumeUrl = "https://www.nowcoder.com";
PartnerInterviewDTO.JobInfo jobInfo = new PartnerInterviewDTO.JobInfo();
jobInfo.jobName = "java";
jobInfo.deliverId = "TD12983710892";
List<PartnerInterviewDTO.InterviewRound> interviewRounds = new ArrayList<>();
PartnerInterviewDTO.InterviewRound interviewRound = new PartnerInterviewDTO.InterviewRound();
interviewRound.offline = 0;
interviewRound.interviewType = 1;
interviewRound.panelFlag = 0;
interviewRound.bookTime = 1629982394L;
interviewRounds.add(interviewRound);
List<PartnerInterviewDTO.Interviewer> interviewers = new ArrayList<>();
PartnerInterviewDTO.Interviewer interviewer = new PartnerInterviewDTO.Interviewer();
interviewer.name = "er";
interviewer.email = "er@nowcoder.com";
interviewer.phone = "10000000000";
interviewer.host = 1;
interviewers.add(interviewer);
interviewRound.interviewers = interviewers;
partnerInterviewDTO.interviewee = interviewee;
partnerInterviewDTO.jobInfo = jobInfo;
partnerInterviewDTO.interviewRounds = interviewRounds;
partnerInterviewDTO.orgInfo = orgInfo;
String response = NowcoderApiRequestUtils.jsonRequest(path, partnerInterviewDTO, "POST");
System.out.println(response);
}
}
curl --location --request POST 'https://dapi.nowcoder.com/v1/partners/interview/create_interview?api_key=huaxinjiayou@126.com' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
--header 'Content-Type: application/json' \
--data-raw '{"interviewRounds":[{"bookTime":1629982394,"interviewType":1,"interviewers":[{"email":"er@nowcoder.com","host":1,"name":"er","phone":"10000000000"}],"offline":0,"panelFlag":0}],"interviewee":{"email":"coder@nowcoder.com","name":"coder","phone":"10000000000","resumeUrl":"https://www.nowcoder.com"},"jobInfo":{"deliverId":"TD12983710892","jobName":"java"},"orgInfo":{"projectId":2071}}'
{
"code" : 0,
"msg" : "OK",
"data" : {
"interviewId" : 37000637,
"expireTime" : 1635080281,
"validDuration" : 10800,
"interviewReportUrl" : "https://dapi.nowcoder.com/v1/interview-report/844C0F4B8BD9E8685D2B1AAD67C4DCC3/report_pdf?code=QQGnFJCH",
"interviewRounds" : [ {
"roundId" : 289426,
"roundIdx" : 1,
"offline" : 0,
"panelFlag" : 0,
"bookTime" : 1629982394,
"interviewer" : [ {
"interviewerId" : null,
"name" : "er",
"email" : "er@nowcoder.com",
"phone" : "10000000000",
"host" : 1,
"interviewUrl" : "https://examd.nowcoder.com/interview/37000637/interviewer?code=QQGnFJCH"
} ],
"interviewee" : {
"name" : "coder",
"email" : "coder@nowcoder.com",
"phone" : "10000000000",
"interviewUrl" : "https://examd.nowcoder.com/interview/37000637/interviewee?code=SSEb3BCn"
},
"interviewType" : 1
} ]
}
}
接口地址
POST /partners/interview/create_interview
Content-type
application/json
请求参数
参数 | 类型 | 是否必填 | 描述 |
---|---|---|---|
orgInfo | json | 必填 | 系统信息 |
interviewee | json | 必填 | 候选人信息 |
jobInfo | json | 必填 | 岗位信息 |
interviewRounds | array | 必填 | 轮次信息 |
callback | json | 非必填 | 回调信息 |
系统信息
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
projectId | long | 必填 | 面试所属项目id |
deptId | long | 非必填 | 面试所属部门id |
copilotFlag | boolean | 非必填(默认false) | 是否开启智能面试 |
resumeText | String | 非必填(长度上限12K) | 简历文本内容 |
候选人信息
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
name | String | 非必填 | 候选人姓名 |
String | 非必填 | 候选人邮箱 | |
phone | String | 非必填 | 候选人电话 |
resumeUrl | String | 非必填 | 候选人简历地址 |
岗位信息
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
deliverId | String | 非必填 | 投递编号, 同一个面试项目下唯一 |
jobName | String | 非必填 | 应聘岗位名称 |
轮次信息
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
offline | int | 必填 | 线上视频 或 线下面试, 0表示线上视频,1表示线下面试 |
interviewType | int | 必填 | 技术面试 或 非技术面试, 1表示技术面试,2表示非技术面试 |
panelFlag | int | 必填 | 1对1面试 或 多对1面试, 0表示1对1面试,1表示多对1面试 |
bookTime | long | 必填 | 面试预约时间, 秒级时间戳 |
redirectUrl | json | 非必填, 一对一面试用到 | 重定向链接 |
interviewers | array | 必填 | 面试官信息 |
面试官信息
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
name | String | 非必填 | 面试官姓名 |
String | 非必填 | 面试官邮箱 | |
phone | String | 非必填 | 面试官电话 |
host | int | 必填 | 是否主持人 0代表非主持人, 1代表主持人 |
feedbackCb | String | 非必填, 多对一面试用到 | 自定义面评表地址, https格式。 |
redirectUrl | json | 非必填, 多对一面试用到 | 重定向链接 |
重定向链接
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
finishRedirectUrl | String | 非必填 | 结束时的重定向链接 |
回调链接
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
evaluationCallbackUrl | String | 非必填(想使用对应回调功能必填) | 面试轮次评价回调, 录音完成回调 |
返回数据
非全量修改面试-新版
public class Main {
@Test
public void testNewUpdateInterview(){
String path = "/partners/interview/part-update-interview";
PartnerInterviewDTO partnerInterviewDTO = new PartnerInterviewDTO();
PartnerInterviewDTO.OrgInfo orgInfo = new PartnerInterviewDTO.OrgInfo();
orgInfo.deptId = null;
PartnerInterviewDTO.Interviewee interviewee = new PartnerInterviewDTO.Interviewee();
interviewee.name = "coder5";
partnerInterviewDTO.interviewId = 37000637L;
partnerInterviewDTO.interviewee = interviewee;
String response = NowcoderApiRequestUtils.jsonRequest(path, partnerInterviewDTO, "POST");
System.out.println(response);
}
}
curl --location --request POST 'https://dapi.nowcoder.com/v1/partners/interview/part-update-interview?api_key=huaxinjiayou@126.com' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
--header 'Content-Type: application/json' \
--data-raw '{"interviewId":37000637,"interviewee":{"name":"coder5"}}'
{
"code" : 0,
"msg" : "OK",
"data" : {
"interviewId" : 37000637,
"expireTime" : 1856005081,
"validDuration" : 10800,
"interviewReportUrl" : "https://dapi.nowcoder.com/v1/interview-report/844C0F4B8BD9E8685D2B1AAD67C4DCC3/report_pdf?code=QQGnFJCH",
"interviewRounds" : [ {
"roundId" : 289426,
"roundIdx" : 1,
"offline" : 0,
"panelFlag" : 0,
"bookTime" : 1629982394,
"interviewer" : [ {
"interviewerId" : null,
"name" : "er",
"email" : "er@nowcoder.com",
"phone" : "10000000000",
"host" : 1,
"interviewUrl" : "https://examd.nowcoder.com/interview/37000637/interviewer?code=QQGnFJCH"
} ],
"interviewee" : {
"name" : "coder5",
"email" : "coder2@nowcoder.com",
"phone" : "10000000000",
"interviewUrl" : "https://examd.nowcoder.com/interview/37000637/interviewee?code=SSEb3BCn"
},
"interviewType" : 1
}, {
"roundId" : 289428,
"roundIdx" : 2,
"offline" : 0,
"panelFlag" : 0,
"bookTime" : 1656322593,
"interviewer" : [ {
"interviewerId" : null,
"name" : null,
"email" : null,
"phone" : "14700000000",
"host" : 1,
"interviewUrl" : "https://examd.nowcoder.com/interview/37000637/interviewer?code=QQGnFJCH"
} ],
"interviewee" : {
"name" : "coder5",
"email" : "coder2@nowcoder.com",
"phone" : "10000000000",
"interviewUrl" : "https://examd.nowcoder.com/interview/37000637/interviewee?code=SSEb3BCn"
},
"interviewType" : 1
} ]
}
}
接口地址
POST /partners/interview/part-update-interview
Content-type
application/json
请求参数
参数 | 类型 | 是否必填 | 描述 |
---|---|---|---|
interviewId | long | 必填 | 面试id |
orgInfo | json | 非必填 | 系统信息 |
interviewee | json | 非必填 | 候选人信息 |
jobInfo | json | 非必填 | 岗位信息 |
interviewRounds | array | 非必填 | 轮次信息 |
系统信息
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
deptId | long | 非必填 | 面试所属部门id |
候选人信息
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
name | String | 非必填 | 候选人姓名 |
String | 非必填 | 候选人邮箱 | |
phone | String | 非必填 | 候选人电话 |
resumeUrl | String | 非必填 | 候选人简历地址 |
岗位信息
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
deliverId | String | 非必填 | 投递编号,同一个面试项目下唯一 |
jobName | String | 非必填 | 应聘岗位名称 |
轮次信息
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
roundId | long | 需要修改轮次时填写 | 需要修改的轮次id,新增时不填 |
offline | int | 非必填 | 线上视频 或 线下面试, 0表示线上视频,1表示线下面试, 必填 |
interviewType | int | 非必填 | 技术面试 或 非技术面试, 1表示技术面试,2表示非技术面试, 必填 |
panelFlag | int | 非必填 | 1对1面试 或 多对1面试, 0表示1对1面试,1表示多对1面试, 必填 |
bookTime | long | 非必填 | 面试预约时间, 秒级时间戳, 必填 |
redirectUrl | json | 非必填, 一对一面试用到 | 重定向链接 |
interviewers | array | 非必填 | 面试官信息 |
面试官信息
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
interviewerId | long | 多对一面试修改面试官填写 | 面试官id,多对一面试修改时传入 |
name | String | 非必填 | 面试官姓名, 必填 |
String | 非必填 | 面试官邮箱 | |
phone | String | 非必填 | 面试官电话 |
host | int | 非必填 | 是否主持人 0代表非主持人, 1代表主持人 必填 |
delete | boolean | 非必填,默认false | 是否删除面试官,多对一时用到 |
feedbackCb | String | 非必填,多对一面试用到 | 自定义面评表地址, https格式 |
redirectUrl | json | 非必填,多对一面试用到 | 重定向链接 |
重定向链接
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
finishRedirectUrl | String | 非必填 | 结束时的重定向链接 |
返回数据
修改面试-新版(建议使用非全量修改接口)
public class Main {
@Test
public void testNewUpdateInterview(){
String path = "/partners/interview/update_interview";
PartnerInterviewDTO partnerInterviewDTO = new PartnerInterviewDTO();
PartnerInterviewDTO.OrgInfo orgInfo = new PartnerInterviewDTO.OrgInfo();
orgInfo.deptId = null;
PartnerInterviewDTO.Interviewee interviewee = new PartnerInterviewDTO.Interviewee();
interviewee.name = "coder2";
interviewee.email = "coder2@nowcoder.com";
interviewee.phone = "10000000000";
interviewee.resumeUrl = "https://www.nowcoder.com";
PartnerInterviewDTO.JobInfo jobInfo = new PartnerInterviewDTO.JobInfo();
jobInfo.jobName = "java";
jobInfo.deliverId = "TD12983710892";
List<PartnerInterviewDTO.InterviewRound> interviewRounds = new ArrayList<>();
PartnerInterviewDTO.InterviewRound interviewRound = new PartnerInterviewDTO.InterviewRound();
interviewRound.roundId = 289426L;
interviewRound.offline = 0;
interviewRound.interviewType = 1;
interviewRound.panelFlag = 0;
interviewRound.bookTime = 1629982394L;
interviewRounds.add(interviewRound);
List<PartnerInterviewDTO.Interviewer> interviewers = new ArrayList<>();
PartnerInterviewDTO.Interviewer interviewer = new PartnerInterviewDTO.Interviewer();
interviewer.name = "er";
interviewer.email = "er@nowcoder.com";
interviewer.phone = "10000000000";
interviewer.host = 1;
interviewers.add(interviewer);
interviewRound.interviewers = interviewers;
partnerInterviewDTO.interviewId = 37000637L;
partnerInterviewDTO.interviewee = interviewee;
partnerInterviewDTO.jobInfo = jobInfo;
partnerInterviewDTO.interviewRounds = interviewRounds;
partnerInterviewDTO.orgInfo = orgInfo;
String response = NowcoderApiRequestUtils.jsonRequest(path, partnerInterviewDTO, "POST");
System.out.println(response);
}
}
curl --location --request POST 'https://dapi.nowcoder.com/v1/partners/interview/update_interview?api_key=huaxinjiayou@126.com' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c' \
--header 'Content-Type: application/json' \
--data-raw '{"interviewId":37000637,"interviewRounds":[{"bookTime":1629982394,"interviewType":1,"interviewers":[{"email":"er@nowcoder.com","host":1,"name":"er","phone":"10000000000"}],"offline":0,"panelFlag":0,"roundId":289426}],"interviewee":{"email":"coder2@nowcoder.com","name":"coder2","phone":"10000000000","resumeUrl":"https://www.nowcoder.com"},"jobInfo":{"deliverId":"TD12983710892","jobName":"java"},"orgInfo":{}}'
{
"code" : 0,
"msg" : "OK",
"data" : {
"interviewId" : 37000637,
"expireTime" : 1635080281,
"validDuration" : 10800,
"interviewReportUrl" : "https://dapi.nowcoder.com/v1/interview-report/844C0F4B8BD9E8685D2B1AAD67C4DCC3/report_pdf?code=QQGnFJCH",
"interviewRounds" : [ {
"roundId" : 289426,
"roundIdx" : 1,
"offline" : 0,
"panelFlag" : 0,
"bookTime" : 1629982394,
"interviewer" : [ {
"interviewerId" : null,
"name" : "er",
"email" : "er@nowcoder.com",
"phone" : "10000000000",
"host" : 1,
"interviewUrl" : "https://examd.nowcoder.com/interview/37000637/interviewer?code=QQGnFJCH"
} ],
"interviewee" : {
"name" : "coder2",
"email" : "coder2@nowcoder.com",
"phone" : "10000000000",
"interviewUrl" : "https://examd.nowcoder.com/interview/37000637/interviewee?code=SSEb3BCn"
},
"interviewType" : 1
} ]
}
}
接口地址
POST /partners/interview/update_interview
Content-type
application/json
请求参数
参数 | 类型 | 是否必填 | 描述 |
---|---|---|---|
interviewId | long | 必填 | 面试id |
orgInfo | json | 必填 | 系统信息 |
interviewee | json | 必填 | 候选人信息 |
jobInfo | json | 必填 | 岗位信息 |
interviewRounds | array | 必填 | 轮次信息 |
系统信息
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
deptId | long | 必填 | 面试所属部门id |
候选人信息
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
name | String | 非必填 | 候选人姓名 |
String | 非必填 | 候选人邮箱 | |
phone | String | 非必填 | 候选人电话 |
resumeUrl | String | 非必填 | 候选人简历地址 |
岗位信息
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
deliverId | String | 必填 | 投递编号,同一个面试项目下唯一 |
jobName | String | 非必填 | 应聘岗位名称 |
轮次信息
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
roundId | long | 修改轮次信息时必填,增加轮次时不填 | 需要修改的轮次id |
offline | int | 必填 | 线上视频 或 线下面试, 0表示线上视频,1表示线下面试, 必填 |
interviewType | int | 必填 | 技术面试 或 非技术面试, 1表示技术面试,2表示非技术面试, 必填 |
panelFlag | int | 必填 | 1对1面试 或 多对1面试, 0表示1对1面试,1表示多对1面试, 必填 |
bookTime | long | 必填 | 面试预约时间, 秒级时间戳, 必填 |
redirectUrl | json | 非必填, 一对一面试用到 | 重定向链接 |
interviewers | array | 必填 | 面试官信息 |
面试官信息
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
interviewerId | long | 多对一面试修改必填 | 面试官id,多对一面试修改时传入 |
name | String | 非必填 | 面试官姓名, 必填 |
String | 非必填 | 面试官邮箱 | |
phone | String | 非必填 | 面试官电话 |
host | int | 必填 | 是否主持人 0代表非主持人, 1代表主持人 必填 |
feedbackCb | String | 非必填, 多对一面试用到 | 自定义面评表地址, https格式 |
redirectUrl | json | 非必填,多对一面试用到 | 重定向链接 |
重定向链接
参数名称 | 类型 | 是否必填 | 描述 |
---|---|---|---|
finishRedirectUrl | String | 非必填 | 结束时的重定向链接 |
返回数据
面试录音下载
public class Main {
@Test
public void testGetJobProcess() {
String interviewId = "31310396";
String path = String.format("/partners/interview/get-record-url/%s", interviewId);
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
String responseString = CommonUtils.request(path, mvMap, "GET");
System.out.println(responseString);
}
}
curl --location --request GET 'https://dapi.nowcoder.com/v1/partners/interview/get-record-url?interviewId=31310396&api_key=huaxinjiayou@126.com' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c1273a4e338f650a5c'
{
"code": 0,
"msg": "OK",
"data": {
"interviewId": 31310396,
"roundRecordDatas": [
{
"roundId": 430801,
"round": 1,
"roundStatus": 3,
"recordUrl": null,
"recordExpireTime": null
},
{
"roundId": 430802,
"round": 2,
"roundStatus": 3,
"recordUrl": null,
"recordExpireTime": null
}
]
}
}
接口地址
GET /partners/interview/get-record-url
Content-type
application/json
请求参数
参数 | 类型 | 是否必填 | 描述 |
---|---|---|---|
interviewId | long | 必填 | 面试房间id |
返回数据
字段名 | 类型 | 描述 |
---|---|---|
interviewId | long | 面试房间id |
roundRecordDatas | array | 录音数组,关键信息见录音信息实体 |
录音实体字段
字段名称 | 类型 | 描述 |
---|---|---|
rounId | long | 轮次id |
round | int | 当前轮次 |
roundStatus | int | 轮次状态,0未开始、1进行中、3结束、4删除、5暂停、7面试淘汰被自动取消 |
recordUrl | String | 录音下载链接 (不存在返回null) |
recordExpireTime | long | 下载链接过期时间(注意是秒级时间戳,不存在返回null) |
面试-回调服务
面试轮次评价回调
回调时机
- 每一轮面试结束时进行回调
- 轮次评分修改分数后进行回调
回调参数
参数名称 | 类型 | 描述 |
---|---|---|
interviewId | long | 面试id |
roundId | long | 面试轮次id |
round | int | 第几轮 |
score | int | 0未评分、1-2淘汰、3-5通过 |
evaluation | String | 评语 |
reportUrl | Stirng | 报告链接 |
deliverId | String | 投递编号 |
interviewerName | String | 面试官姓名,以最后评价填写的为准 |
roundStatus | int | 固定值3,代表面试结束 |
roundStartTime | long | 该轮面试开始时间 |
roundEndTime | long | 该轮面试结束时间 |
roundElapsedTime | String | 该轮使用时长,单位毫秒 |
autoCancelRounds | array | 自动取消轮次信息,如果开启了淘汰取消后续轮次这里会携带被自动取消的轮次信息 |
interviewerEvaluations | array | 多对一面试非主持人评价信息 |
自动取消轮次信息
参数名称 | 类型 | 描述 |
---|---|---|
id | long | 轮次id |
round | int | 第几轮, 被折叠的轮次也会记录 |
多对一面试非主持人评价信息
参数名称 | 类型 | 描述 |
---|---|---|
interviewerName | String | 面试官姓名 |
interviewerEvaluations | String | 面试官评价 |
面试状态回调
回调时机
- 面试开始使用
- 面试删除、过期
- 候选人或面试官上线
回调参数
参数名称 | 类型 | 描述 |
---|---|---|
interviewId | long | 面试id |
status | int | 状态, 1取消、2过期、3开始使用、4面试官或候选人上线 |
参数名称 | 类型 | 描述 |
---|---|---|
round | int | 第几轮 |
roundId | long | 轮次id |
role | int | 0面试官、1候选人 |
onlineTime | long | 毫秒级时间戳, 上线时间 |
bookTime | long | 毫秒级时间戳,预约时间 |
uid | long | 多对一面试时面试官id |
录音文件生成回调
回调时机
- 生成面试录音文件
回调参数
参数名称 | 类型 | 描述 |
---|---|---|
interviewId | long | 面试id |
roundId | long | 面试轮次id |
round | int | 第几轮 |
score | int | 0未评分、1-2淘汰、3-5通过 |
evaluation | String | 评语 |
deliverId | String | 投递编号 |
interviewerName | String | 面试官姓名,以最后评价填写的为准 |
recordUrl | String | 面试录音下载链接 |
roundStatus | int | 固定值3,代表面试结束 |
roundStartTime | long | 该轮面试开始时间 |
roundEndTime | long | 该轮面试结束时间 |
roundElapsedTime | String | 该轮使用时长,单位毫秒 |
autoCancelRounds | array | 自动取消轮次信息,如果开启了淘汰取消后续轮次这里会携带被自动取消的轮次信息 |
ai智能报告回调
回调说明
收到该回调表示面试轮次ai智能报告已经生成,相关答题分析和面试记录可以通过下面两个接口来拉取
请求方法和类型
post, application/x-www-form-urlencoded
回调参数
参数名称 | 类型 | 描述 |
---|---|---|
uid | string | 账号id |
time | long | 时间戳 |
sec | string | 加密后的内容 |
data | string | 回调的数据,是个json字符串,结构见右边 |
回调参数中data对应的json结构:
{
"interviewId": "面试id,long",
"roundId": "面试轮次id,long",
"round": "表示第几轮,int",
}
回包参数:
{
"code": "int:200表示成功,非200表示失败",
"message": "string:表示失败时的报错原因"
}
答题分析获取接口
接口地址
/v1/partners/interview/report/answer-analysis
请求方法和类型
get
鉴权方式
- url后面添加api_key的query参数,如:/v1/partners/interview/answer-analysis?api_key=xxx
- 请求添加一个Authorization头,值为:"Bearer token",其中的token可以从hr系统获得
请求query参数
参数名称 | 类型 | 描述 |
---|---|---|
roundId | long | 必填,轮次id |
回包参数见右边
{
"code": "int:0表示成功,非0表示失败",
"msg": "string:code非0时表示报错原因",
"data": {
"assessmentDimensionList": [
{
"name": "维度名称,string:学习能力",
"assessment": "维度评价内容,string:候选人应对挫折和卡点,容易陷入自我怀疑与否定...",
"dimensionId": "维度评价id,string:249483jsfjoe"
}
],
"answerAnalysisList": [
{
"chatList": [
{
"roleType": "角色类型,int: 0.面试官,1.候选人",
"roleName": "角色名称,string:面试官",
"content": "对话的内容,string:请你做个自我介绍"
}
],
"skills": [
"考察技能名称,string:Java"
],
"advice": "答题分析建议,string:候选人回答基本正确,但掌握比较基础,建议深入考核",
"analysisId": "答题分析建议id,string:2898598543jfosdjfoi"
}
]
}
}
面试记录获取接口
接口地址
/v1/partners/interview/report/chat-list
请求方法和类型
get
鉴权方式
- url后面添加api_key的query参数,如:/v1/partners/interview/chat-list?api_key=xxx
- 请求添加一个Authorization头,值为:"Bearer token",其中的token可以从hr系统获得
请求query参数
参数名称 | 类型 | 描述 |
---|---|---|
roundId | long | 必填,轮次id |
curPage | int | 选填,请求页,默认值1 |
pageSize | int | 选填,每页大小,默认值20 |
回包参数见右边
{
"code": "int:0表示成功,非0表示失败",
"msg": "string:code非0时表示报错原因",
"data": {
"totalCount": "int: 总条数",
"totalPage": "int:总页数",
"curPage": "int:当前页",
"pageSize": "int:当前每页大小",
"originChatList": [
{
"roleType": "角色类型,int: 0.面试官,1.候选人",
"roleName": "角色名称,string:比如面试官",
"content": "对话的内容,string:请你做个自我介绍",
"actionTime": "对话时间戳,long:毫秒时间戳"
}
]
}
}
系统接口
获取用户当前账户信息
public class Main {
@Test
public void testGetUserTestInfo() {
String path = "/users/self";
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
String responseString = CommonUtils.request(path, mvMap, "GET");
System.out.println(responseString);
}
}
curl --location --request GET 'http://localhost:8888/v1/users/self?api_key=huaxinjiayou@126.com' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'
{
"code" : 0,
"msg" : "OK",
"data" : {
"id" : 30,
"email" : "huaxinjiayou@126.com",
"phone" : null,
"companyName" : "华鑫加油",
"headUrl" : null,
"accountConfig" : null,
"validBeginTime" : null,
"validEndTime" : null,
"encryptPassword" : null
}
}
查询当前用户的账户信息
接口地址
GET /users/self
请求参数
无
返回数据
参数 | 描述 |
---|---|
id | 账号id |
账号登录邮箱 | |
phone | 账号手机 |
companyName | 公司名称,不同于账号名称 |
headUrl | 头像 |
validBeginTime | 有效期开始时间 |
validEndTime | 有效期开始时间 |
encryptPassword | 加密密码 |
获取hr系统每种服务的最大可用额度
public class Main {
@Test
public void testGetPaperTestsInfo() {
String path = "/user/checkBalance/count";
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
mvMap.put("serviceTypes", 1);
mvMap.put("serviceTypes", 3);
mvMap.put("serviceTypes", 7);
mvMap.put("serviceTypes", 8);
mvMap.put("serviceTypes", 9);
String responseString = CommonUtils.request(path, mvMap, "GET");
System.out.println(responseString);
}
}
curl --location --request GET 'http://localhost:8888/v1/user/checkBalance/count?api_key=huaxinjiayou@126.com&serviceTypes=1&serviceTypes=3&serviceTypes=7&serviceTypes=8&serviceTypes=9' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'
{
"code" : 0,
"msg" : "OK",
"data" : {
"hostId" : 30,
"adminHrId" : 30,
"techContestCount" : 2176,
"untechContestCount" : 4352,
"techInterviewCount" : 932,
"untechInterviewCount" : 1865,
"extendPackageCount" : 3264
}
}
查询每个服务类型最大可以使用的额度(包括额度和账户余额),包括技术笔试、非技术笔试、技术面试、非技术面试、面试扩展包。
最大可以使用额度计算方式:
技术笔试额度=合同剩余技术笔试额度+取整(账户余额/30)
非技术笔试额度=合同剩余非技术笔试额度+取整(账户余额/15)
技术面试额度=合同剩余技术面试额度+取整(账户余额/70)
非技术面试额度=合同剩余非技术笔试额度+取整(账户余额/35)
面试扩展包=合同剩余扩展包额度+取整(账户余额/20)
注:子账号查询,返回总账号/子账号的额度限制,取最小值
支持指定类型查询最大额度,例如 只查询笔试的;也可以支持不指定类型,查询全部最大额度;
接口地址
GET /user/checkBalance/count
请求参数
参数 | 描述| |
---|---|
serviceTypes | 需要查询的服务类型,可以传多个值。1:技术面试,3:技术笔试,7:非技术面试,8:非技术笔试,9:面试扩展包 |
返回数据
参数 | 描述 |
---|---|
hostId | 当前用户ID |
adminHrId | 用户主账号ID,如果当前用户为主账号与用户ID相同 |
techContestCount | 技术笔试可用额度,-1为无限制 |
untechContestCount | 非技术笔试可用额度,-1为无限制 |
techInterviewCount | 技术面试可用额度,-1为无限制 |
untechInterviewCount | 非技术面试可用额度,-1为无限制 |
extendPackageCount | 面试扩展包可用额度,-1为无限制,子账户此项默认返回父账可用最大额度 |
获取异步任务进度
public class Main {
@Test
public void testGetJobProcess() {
String processId = "LntWBG4tD1YRyJ4z7woVSqaU5sxulx36";
String path = String.format("/job-progress/%s", processId);
MultiValuedMap<String, Object> mvMap = new ArrayListValuedHashMap<>();
String responseString = CommonUtils.request(path, mvMap, "GET");
System.out.println(responseString);
}
}
curl --location --request GET 'http://localhost:8888/v1/job-progress/LntWBG4tD1YRyJ4z7woVSqaU5sxulx36?api_key=huaxinjiayou@126.com' \
--header 'Authorization: Bearer 9e906c093a59bc80e312d2821d5daff81aa9c7a8512638f4c73a4e338f650a5c'
{
"code" : 0,
"msg" : "OK",
"data" : {
"ownerId" : 0,
"content" : "",
"end" : true,
"error" : false,
"type" : 2,
"progress" : 100,
"jobId" : "LntWBG4tD1YRyJ4z7woVSqaU5sxulx36",
"jobInfo" : null
}
}
获取异步任务进度
接口地址
GET /job-progress/{id}
请求参数
参数 | 描述 |
---|---|
id | 异步任务id |
返回数据
参数 | 描述 |
---|---|
ownerId | 账号id |
jobId | 异步任务id |
progress | 异步任务进度,0~100之间的整数 |
end | 异步任务是否结束。true结束、false未结束 |
error | 异步任务是否发生异常。true发生了异常、false未发生异常 |
content | 异步任务返回信息 |
type | content字段的类型,1-下载链接 2-文字结果 3-JSON字符串 |