智能应用开放平台

请求数据指的是平台发送 http(s) post 请求时 body 中的数据,数据格式为 application/json 。


1. 请求数据对象结构

字段名

type

描述

是否必要

sessionId

String

会话ID,session内的对话此ID相同

utterance

String

进入意图时用户所说的语句

requestData

Map<String,String>

请求附带参数,使用天猫精灵音箱调用技能时额外携带的信息,

在线测试无此数据

token

String

技能配置 OAuth2.0 授权并且用户登录授权账号后可以得到此 token,详细请查看【OAuth2.0配置文档】,

在线测试无此数据

botId

Long

应用ID,标识用户所使用的的天猫精灵设备的种类

domainId

Long

领域ID

skillId

Long

技能ID

skillName

String

技能名称

intentId

Long

意图ID

intentName

String

意图标识

slotEntities

List

从用户语句中抽取出的 slot 参数信息

selectIndexList

List<Integer>

上一轮状态标识 resultType: SELECT 时,

用户所做选择的索引值。

confirmStatus

String

上一轮状态标识 resultType: CONFIRM 时,

用户所进行的确定(CONFIRMED)或否定(DENIED)回答。

device

Device

用户的设备信息。在线测试没有设备,不会携带设备数据

requestId

String

本次请求的ID

skillSession

SkillSession

技能粒度的session信息


RequestData 中包含的主要信息字段:

字段名

type

描述

userOpenId

String

天猫精灵用户id和技能id混合加密,只能在当前技能中唯一标识用户

deviceOpenId

String

天猫精灵设备id和技能id混合加密,只能在当前技能中唯一标识设备

city

String

天猫精灵设备所处的城市

screenStatus

String

用户使用带屏设备的标识: "screenStatus": "online"

若用户使用的是无屏设备,则没有此条数据。

需要到 权限包管理 中申请“设备有无屏特性”权限包

deviceUnionIds

String

如果技能挂载到组织下,设备在各个组织中的加密id。默认没有此数据,需要额外开通服务卡片账号打通功能

userUnionIds

String

如果技能挂载到组织下,用户在各个组织中的加密id。默认没有此数据,需要额外开通服务卡片账号打通功能


SlotEntities 中每一个数组对象SlotEntity的具体字段:

字段名

type

描述

是否必要

intentParameterId

Long

意图参数ID

intentParameterName

String

意图参数名

originalValue

String

原始句子中抽取出来的未做处理的 slot 值

standardValue

String

 slot 归一化后的值

liveTime

Integer

该 slot 已存在的会话轮数

createTimeStamp

Long

 该 slot 产生时的时间戳


SkillSession 中包含的主要信息字段:

字段名

type

描述

skillSessionId

String

技能粒度session的id

newSession

Boolean

用户首次进入技能时:true

用户后续在技能中对话:false

如果技能交互中用户有跳出技能,再次进入技能时:true



2. Webhook 服务请求结构样例

POST http://your-webhook-service.com/skill/weather

 Headers:
 //默认已填充,规定请求体中的数据格式
 Content-type: application/json
 //开发者自定义的headers
 //key1: value1
 //key2: value2

POST body:
{
    "sessionId": "b112a091-1523-4d2d-8059-e09461dafd73", 
    "utterance": "魔都今天天气", 
    "token": "ozkYw9Y8*******lffDM",		//技能配置OAuth2授权,并且用户登陆授权账号后会携带
    "requestData": {
        "userOpenId": "XXXXXXXX==", 
        "deviceOpenId": "YYYYYYYYY==", 
        "city": "上海" 
    }, 
    "botId": 10, 
    "domainId": 12345, 
    "skillId": 23456, 
    "skillName": "天气小助手", 
    "intentId": 34567, 
    "intentName": "weather", 
    "slotEntities": [
		{
            "intentParameterId": 45678, 
            "intentParameterName": "city", 
            "originalValue": "魔都", 
            "standardValue": "上海", 
            "liveTime": 0, 
            "createTimeStamp": 1564110905331, 
            "slotName": "city:city",
            "slotValue": "魔都"
        },
        {
            "intentParameterId": 56789, 
            "intentParameterName": "time(公共实体)", 
            "originalValue": "今天", 
            "standardValue": "今天", 
            "liveTime": 0, 
            "createTimeStamp": 1564110905331, 
            "slotName": "time(公共实体):sys.time", 
            "slotValue": "今天"
        }
	], 
    "requestId": "20190726111511958-508551760", 
    "device": { },
  	"skillSession": {
        "skillSessionId":"8d7501fe-a80a-46cf-a43f-ff8743a7ec66",
        "newSession":true
    }
}


3.java方式的处理范例

@RequestMapping(value = "/skill/weather", method = RequestMethod.POST)
public @ResponseBody ResultModel<TaskResult> getResponse(@RequestBody String taskQuery) {
	/**
	* 将开发者平台识别到的语义理解的结果(json字符串格式)转换成TaskQuery
	*/
	logger.info("TaskQuery:{}", taskQuery.toString());
	TaskQuery query = MetaFormat.parseToQuery(taskQuery);

    /**
    * 构建服务返回结果
    */
    ResultModel<TaskResult> resultModel = new ResultModel<TaskResult>();
    try {
        TaskResult result = weatherHandle.execute(query);
        resultModel.setReturnCode("0");
        resultModel.setReturnValue(result);
    } catch (Exception e) {

    }

    /**
    * 直接返回ResultModel<TaskResult>对象就ok
    */
	return resultModel;
}

// 天气服务执行,根据NLU理解的结果做相应处理并返回回复语句
@Component
public class WeatherHandleImpl implements WeatherHandle {

    @Override
    public TaskResult execute(TaskQuery taskQuery) {
        logger.info("WeatherHandleImpl execute...");

        //从请求中获取意图参数以及参数值
        Map<String, String> paramMap = taskQuery
                .getSlotEntities()
                .stream()
                .collect(
                        Collectors.toMap(slotItem -> slotItem.getIntentParameterName(),
                                slotItem -> slotItem.getOriginalValue()));
        logger.info("paramMap :" + paramMap.toString());
        //如果意图是询问空气质量,则执行空气质量逻辑
        if ("air_quality".equals(taskQuery.getIntentName())) {
            return aqiQuery(taskQuery, paramMap);
            //如果意图是询问天气情况,则执行天气查询逻辑
        } else if ("weather".equals(taskQuery.getIntentName())) {
            return baseQuery(taskQuery, paramMap);
        } else {
            return reply("请检查意图名称是否正确,或者新增的意图没有在代码里添加对应的处理分支。");
        }
    }

    //空气质量查询方法
    private TaskResult aqiQuery(TaskQuery taskQuery, Map<String, String> paramMap) {
        TaskResult result = new TaskResult();
         //TODO 根据参数获取空气质量信息
        reply = paramMap.get("city") + paramMap.get("date") + "空气质量 优";
        return reply(reply);
    }
    
     //天气查询方法
    private TaskResult baseQuery(TaskQuery taskQuery, Map<String, String> paramMap) {
        TaskResult result = new TaskResult();
         //TODO 根据参数获取空气质量信息
        reply = paramMap.get("city") + paramMap.get("date") + "天气 晴";
        return reply(reply);
    }
    
    private TaskResult reply(String reply) {
        TaskResult taskResult = new TaskResult();
        taskResult.setReply(reply);
        taskResult.setExecuteCode(ExecuteCode.SUCCESS);
        taskResult.setResultType(ResultType.RESULT);
        return taskResult;
    }
}