基本概念
下面这张图描述了开发者接入卡片后的搜索请求数据流:
在开发者作为一个资源方接入一个卡片后,当用户搜索卡片相关的搜索词,开放平台会根据 intent 配置对该搜索词进行语义分析。分析得到的 intent 会发送到资源方的 Webhook URL,开发者根据自己数据和业务逻辑生成符合开放平台要求的资源数据返回给开放平台。开放平台将会用该资源数据结合卡片的配置渲染生成搜索结果中的卡片,并插入到搜索结果页中的适当位置。
出于对搜索速度,结果稳定性和减轻开发者服务器压力考虑,开放平台将会采取一定的缓存策略。也就是说,在一部分情况下用户的搜索请求是通过缓存来满足的。
Webhook API
开放平台发送给 Webhook URL 的请求 JSON object,遵照以下形式。其中的 intent
字段对于每个卡片来说,内容是不同的,即 srcid
决定了 intent
的内部数据结构。
1 | { |
Webhook 返回的响应 JSON object,遵照以下形式。其中的 data
字段对于每个卡片来说,内容是不同的,即请求的 srcid
决定了响应消息中 data
的内部数据结构。
1 | { |
以上内容主要是卡片 API 接口的公共字段。至于每个卡片的 srcid
编号,以及 intent
和 data
字段的数据格式和含义,请参考”开放类目卡片列表 “下对应卡片的接口说明。
Webhook 加密协议
为保护开放平台和开发者双方的数据安全,以上请求和响应消息都不能通过明文发送,需要对消息进行加密。加密算法的具体实现细节请参考”API 加密协议“一节中的说明。
示例
下面我们以景点门票
为例说明各阶段数据的处理过程。
开放平台生成请求 JSON 明文
1 | {"intent":{"scenic_spot":"\u6545\u5bab"},"srcid":"123","surface":"mobile","type":"sp_ala"} |
开放平台根据开发者配置的 PSK 对请求进行加密,生成 JWE 密文
加密参数:
- PSK:
"0123456789abcdef"
- base64url(PSK):
"MDEyMzQ1Njc4OWFiY2RlZg"
- kid:
"0"
会话参数:
- rid:
"1559123682789-315431431"
1 | eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoiMCIsInJpZCI6IjE1NTkxMjM2ODI3ODktMzE1NDMxNDMxIn0.1vDnKkf50N3piN9sLgr87h2maEm61IdJIC39WEhHB5N99P1JjNUMhQ.fnj_JIk0aYbkGKkGaT1QsA.HpabSZGitPw3CTmIuwpDS-XCN1Yxf2N9CLKBtJprC2q5qSMEHicubEV4jjcIYgctp8F1jYFSu3yhvWuxGtA7h4p_Ek07jmQRjZRE7GB9GhX_uE3IdoJavWm0cYEgJ7gF.B7iwwd5Eh4KaLdNID2f4UQ |
开放平台将密文 HTTP POST 到 webhook
我们以 webhook http://localhost:8000
为例,用 curl 模拟发送 POST 请求:
1 | curl -X POST "http://localhost:8000" -H "Content-Type:application/jwt" -d'eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoiMCIsInJpZCI6IjE1NTkxMjM2ODI3ODktMzE1NDMxNDMxIn0.1vDnKkf50N3piN9sLgr87h2maEm61IdJIC39WEhHB5N99P1JjNUMhQ.fnj_JIk0aYbkGKkGaT1QsA.HpabSZGitPw3CTmIuwpDS-XCN1Yxf2N9CLKBtJprC2q5qSMEHicubEV4jjcIYgctp8F1jYFSu3yhvWuxGtA7h4p_Ek07jmQRjZRE7GB9GhX_uE3IdoJavWm0cYEgJ7gF.B7iwwd5Eh4KaLdNID2f4UQ' |
开发者根据 PSK 对请求进行解密,获得 JSON 明文
如果解密失败,开发者需返回 400 HTTP 状态码,并在 HTTP body 中注明解密出错原因。
对 JWE 解密时,除获得解密后的 JSON 明文之外,还可以从 protected header 中获得其它加密参数和会话参数。protected header 将会作为参数用于构造返回消息的 JWE 对象,其中的 rid
可以用来作为会话的唯一标识打印日志,以及在追查问题时提供给开放平台作为参考。
开发者根据 intent 生成返回结果 JSON 明文
1 | {"data":{"item_list":[{"title":"\u6545\u5bab\u535a\u7269\u9662"}],"jump_url":"/path/to/page3"},"msg":"","status":0} |
开发者使用同样的参数对结果进行加密,返回 JWE 密文
可以注意到,JWE 的第一段 protected header 与请求完全一致,这代表结果的加密参数(除 PSK 以外)与请求保持了一致。
1 | eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoiMCIsInJpZCI6IjE1NTkxMjM2ODI3ODktMzE1NDMxNDMxIn0.a4JDrnuVbcn7C00siEKwODneowk5hwpDmqZtzKycHcW2z-NimkzAJQ.0vEJlCWY7pUG400R9-KNCg.S0eNjmJUl9wUbJg_AB-sZw9LOQov27pa7HuoIR7_pdRUkxYZefzDbUzVpgelXtgAKpXSaZdYxwY_RSxCWbfUtfp1gzW_2pqnYhSOLNs8wBV3tReNdlxmjZocz_Tm_ePG2RNv3yo5H6IzJLEuEvBBp5xqtF-kGvsVF-kBLteHqDQ.-6EJe2xKhrlTB60K3m86Qg |
Webhook demo (python)
1 | #!/usr/bin/env python |