数智人 aPaas 接口调用方式

最近更新时间:2024-10-16 10:17:51

我的收藏
本文主要提供 生成腾讯云智能数智人 aPaas 平台接口调用URL 的方式,以及常见编程语言 demo,语言类型包括 Golang、Java、C++、Python、JavaScript。

一、必要参数获取

appkey、accesstoken请在数智人平台资产管理页面获取:




二、公共参数

参数
类型
必须
说明
appkey
string
根据各接口文档提供的方式获取到的 appkey。
timestamp
string
请求时间戳,单位:秒。时间戳需要和当前时间的差异不过能超过五分钟,否则会鉴权失败。
requestid
string
只有部分接口(如交互数智人的创建长链接通道)需要该参数。获取方式请参考对应接口文档。
signature
string
请求签名(参考签名方法)。
注意:
针对某些接口,需要 requestid。例如:创建长链接通道接口的 url 会有 appkey、requestid、timestamp 三个参数,注意都要拼接。
参考拼接示例:Demo中的示例二。

三、签名方法

在调用 aPaas 任一接口时,都需在 URL 中以 QueryString 形式携带请求签名(signature)等公共参数。
请求参数签名步骤如下:
1. signature 签名规则如下,这里以下为例说明(示例为伪代码仅供参考):
appkey = example_appkey
accesstoken = example_accesstoken
域名路由 = https://api.example.com/v2/ivh/example_uri
2. 根据对应接口文档,对除 signature 之外的所有需要的参数按字典序进行排序,作为签名原文,用于生成签名。示例中仅使用 appkey 和 timestamp 两个参数(各个接口需要的参数请在相关文档中确认), 排序拼接后的字符串示例为:
appkey=example_appkey&timestamp=1717639699
3. 对签名原文使用 accesstoken 进行 HmacSha256 加密,之后再进行 base64 编码:
hashBytes = HmacSha256("appkey=example_appkey&timestamp=1717639699","example_accesstoken")
signature = Base64Encode(hashBytes)
4. 得到 signature 签名值为:
aCNWYzZdplxWVo+JsqzZc9+J9XrwWWITfX3eQpsLVno=
5. 将 signature 值进行 urlencode(必须进行 URL 编码,否则将导致鉴权失败)后拼接得到最终请求 URL 为:
https://api.example.com/v2/ivh/example_uri?appkey=example_appkey&timestamp=1717639699&signature=aCNWYzZdplxWVo%2BJsqzZc9%2BJ9XrwWWITfX3eQpsLVno%3D

四、签名生成 Demo

用户只需要将访问对应接口需要的除 signature 以外所有公共参数填入 demo 中相应位置,即可生成请求签名并拼接成访问接口的完整 URL 。
Golang
Java
C++
Python
JavaScript
package main import ( "crypto/hmac" "crypto/sha256" "encoding/base64" "fmt" "net/url" "sort" "strconv" "time" ) func GenSignature(signingContent string, accessToken string) string { // 计算 HMAC-SHA256 值 h := hmac.New(sha256.New, []byte(accessToken)) h.Write([]byte(signingContent)) // 将 HMAC-SHA256 值进行 Base64 编码 hashInBase64 := base64.StdEncoding.EncodeToString(h.Sum(nil)) // URL encode encodeSign := url.QueryEscape(hashInBase64) // 拼接签名 signature := "&signature=" + encodeSign return signature } func GenReqURL(parameter map[string]string, accessToken string, baseURL string) string { // 按字典序拼接待计算签名的字符串 signingContent := "" pathKey := make([]string, 0, len(parameter)) for k := range parameter { pathKey = append(pathKey, k) } sort.Strings(pathKey) for _, k := range pathKey { if signingContent != "" { signingContent += "&" } signingContent += k + "=" + parameter[k] } // 计算签名 signature := GenSignature(signingContent, accessToken) // 拼接访问接口的完整URL return baseURL + "?" + signingContent + signature } func main() { baseUrl := "https://api.example.com/v2/ivh/example_uri" accesstoken := "example_accesstoken" wssUrl := "wss://api.example.com/v2/ws/ivh/example_uri" // 示例一(访问需要提供 appkey 和 timestamp 参数的接口): // 用户按需填入生成签名所需的公共参数 parameter := map[string]string{ "appkey": "example_appkey", // 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟 // 示例时间戳: // "timestamp": "1717639699", // 推荐使用下面的语句生成当前时间戳: "timestamp": strconv.FormatInt(time.Now().Unix(), 10), } url1 := GenReqURL(parameter, accesstoken, baseUrl) // 使用示例时间戳输出应当如下: // Example 1:https://api.example.com/v2/ivh/example_uri?appkey=example_appkey&timestamp=1717639699&signature=aCNWYzZdplxWVo%2BJsqzZc9%2BJ9XrwWWITfX3eQpsLVno%3D fmt.Println("Example 1:" + url1) // 示例二(访问需要提供 appkey, requestID 和 timestamp 参数的接口): // 用户按需填入生成签名所需的公共参数 parameter = map[string]string{ "appkey": "example_appkey", "requestid": "example_requestid", // 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟 // 示例时间戳: // "timestamp": "1717639699", // 用户若自己提供时间戳应保证单位为秒且与当前时间相差不得超过五分钟 "timestamp": strconv.FormatInt(time.Now().Unix(), 10), } url2 := GenReqURL(parameter, accesstoken, wssUrl) // 使用示例时间戳输出应当如下: // Example 2:wss://api.example.com/v2/ws/ivh/example_uri?appkey=example_appkey&requestid=example_requestid&timestamp=1717639699&signature=QVenICk0VHtHGYZKXM6IC%2BW1CjZC1joSr%2Fx0gfKKYT4%3D fmt.Println("Example 2:" + url2) }
import java.util.*; import java.util.stream.Collectors; import java.time.Instant; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.io.UnsupportedEncodingException; public class Presigned { public static String GenSignature(String signingContent, String accessToken) { try { // 计算 HMAC-SHA256 值 Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(accessToken.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); sha256_HMAC.init(secret_key); String hashInBase64 = Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(signingContent.getBytes(StandardCharsets.UTF_8))); // URL encode String encodeSign = URLEncoder.encode(hashInBase64, StandardCharsets.UTF_8.toString()); // 拼接签名 String signature = "&signature=" + encodeSign; return signature; } catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) { e.printStackTrace(); return null; } } public static String GenReqURL(Map<String, String> parameter, String accessToken, String baseURL) { // 按字典序拼接待计算签名的字符串 String signingContent = parameter.entrySet().stream() .sorted(Map.Entry.comparingByKey()) .map(entry -> entry.getKey() + "=" + entry.getValue()) .collect(Collectors.joining("&")); // 计算签名 String signature = GenSignature(signingContent, accessToken); // 拼接访问接口的完整URL return baseURL + "?" + signingContent + signature; } public static void main(String[] args) { String baseUrl = "https://api.example.com/v2/ivh/example_uri"; String accesstoken = "example_accesstoken"; String wssUrl = "wss://api.example.com/v2/ws/ivh/example_uri"; // 示例一(访问需要提供 appkey 和 timestamp 参数的接口): // 用户按需填入生成签名所需的公共参数 Map<String, String> parameter = new TreeMap<>(); parameter.put("appkey", "example_appkey"); // 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟 // 示例时间戳: // parameter.put("timestamp", "1717639699"); // 推荐使用下面的语句生成当前时间戳: parameter.put("timestamp", String.valueOf(Instant.now().getEpochSecond())); String url = GenReqURL(parameter, accesstoken, baseUrl); // 使用示例时间戳输出应当如下: // Example 1:https://api.example.com/v2/ivh/example_uri?appkey=example_appkey&timestamp=1717639699&signature=aCNWYzZdplxWVo%2BJsqzZc9%2BJ9XrwWWITfX3eQpsLVno%3D System.out.println("Example 1:" + url); // 示例二(访问需要提供 appkey, requestID 和 timestamp 参数的接口): parameter.clear(); parameter.put("appkey", "example_appkey"); parameter.put("requestid", "example_requestid"); // 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟 // 示例时间戳: // parameter.put("timestamp", "1717639699"); // 推荐使用下面的语句生成当前时间戳: parameter.put("timestamp", String.valueOf(Instant.now().getEpochSecond())); url = GenReqURL(parameter, accesstoken, wssUrl); // 使用示例时间戳输出应当如下: // Example 2:wss://api.example.com/v2/ws/ivh/example_uri?appkey=example_appkey&requestid=example_requestid&timestamp=1717639699&signature=QVenICk0VHtHGYZKXM6IC%2BW1CjZC1joSr%2Fx0gfKKYT4%3D System.out.println("Example 2:" + url); } }

#include<iostream>
#include <map>
#include<string>
#include<vector>
#include<algorithm>
#include <ctime>
#include <iomanip>
#include <sstream>
#include<openssl/hmac.h>
#include<openssl/sha.h>
using namespace std;
static const string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
string url_encode(const string &value) {
ostringstream escaped;
escaped.fill('0');
escaped<< hex;
for (size_t i = 0; i< value.length(); ++i) {
char c = value[i];
if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
escaped << c;
} else {
escaped<< uppercase;
escaped << '%'<< setw(2)<< int((unsigned char) c);
escaped<< nouppercase;
}
}
return escaped.str();
}
string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];
while((i++ < 3))
ret += '=';
}
return ret;
}
string GenSignature(const string& signingContent, const string& accessToken) {
// 计算 HMAC-SHA256 值
unsigned char hash[EVP_MAX_MD_SIZE];
unsigned int hashLength;
HMAC(EVP_sha256(), accessToken.c_str(), accessToken.length(), (unsigned char *) signingContent.c_str(), signingContent.length(), hash, &hashLength);
// 将 HMAC-SHA256 值进行 Base64 编码
string hashInBase64 = base64_encode(hash, hashLength);
// URL encode
string encodeSign = url_encode(hashInBase64);
// 拼接签名
string signature = "&signature=" + encodeSign;
return signature;
}
string GenReqURL(const map<string, string>& parameter, const string& accessToken, const string& baseURL) {
// 按字典序拼接待计算签名的字符串
string signingContent;
vector<string> pathKey;
for (const auto& p : parameter) {
pathKey.push_back(p.first);
}
sort(pathKey.begin(), pathKey.end());
for (const auto& k : pathKey) {
if (!signingContent.empty()) {
signingContent += "&";
}
signingContent += k + "=" + parameter.at(k);
}
// 计算签名
string signature = GenSignature(signingContent, accessToken);
// 拼接访问接口的完整URL
return baseURL + "?" + signingContent + signature;
}
// 编译时需要链接到OpenSSL库, 可以使用下面的命令:
// g++ presigned.cpp -o presigned -lcrypto
int main() {
string baseUrl = "https://api.example.com/v2/ivh/example_uri";
string accesstoken = "example_accesstoken";
string wssUrl = "wss://api.example.com/v2/ws/ivh/example_uri";
// 示例一(访问需要提供 appkey 和 timestamp 参数的接口):
// 用户按需填入生成签名所需的公共参数
map<string, string> parameter1 = {
{"appkey", "example_appkey"},
// 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟
// 示例时间戳:
// {"timestamp" , "1717639699"},
// 推荐使用下面的语句生成当前时间戳:
{"timestamp", to_string(time(NULL))}
};
string url = GenReqURL(parameter1, accesstoken, baseUrl);
// 使用示例时间戳输出应当如下:
// Example 1:https://api.example.com/v2/ivh/example_uri?appkey=example_appkey&timestamp=1717639699&signature=aCNWYzZdplxWVo%2BJsqzZc9%2BJ9XrwWWITfX3eQpsLVno%3D
cout << "Example 1:"<< url<< endl;
// 示例二(访问需要提供 appkey, requestID 和 timestamp 参数的接口):
// 用户按需填入生成签名所需的公共参数
map<string, string> parameter2 = {
{"appkey", "example_appkey"},
{"requestid", "example_requestid"},
// 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟
// 示例时间戳:
// {"timestamp" , "1717639699"},
// 推荐使用下面的语句生成当前时间戳:
{"timestamp", to_string(time(NULL))}
};
url = GenReqURL(parameter2, accesstoken, wssUrl);
// 使用示例时间戳输出应当如下:
// Example 2:wss://api.example.com/v2/ws/ivh/example_uri?appkey=example_appkey&requestid=example_requestid&timestamp=1717639699&signature=QVenICk0VHtHGYZKXM6IC%2BW1CjZC1joSr%2Fx0gfKKYT4%3D
cout << "Example 2:"<< url<< endl;
return 0;
}

import hmac
import hashlib
import time
import base64
from urllib.parse import quote
# 用户可以在函数内部生成时间戳, 只需要传入appkey和accessToken即可获取访问接口所需的公共参数和签名
def GenSignature(signing_content, access_token):
# 计算 HMAC-SHA256 值
h = hmac.new(access_token.encode(), signing_content.encode(), hashlib.sha256)
# 将 HMAC-SHA256 值进行 Base64 编码
hash_in_base64 = base64.b64encode(h.digest()).decode()
# URL encode
encode_sign = quote(hash_in_base64)
# 拼接签名
signature = f"&signature={encode_sign}"
return signature
def GenReqURL(parameter, access_token, base_url):
# 按字典序拼接待计算签名的字符串
signing_content = '&'.join(f'{k}={parameter[k]}' for k in sorted(parameter.keys()))
# 计算签名
signature = GenSignature(signing_content, access_token)
# 拼接访问接口的完整 URL
return f'{base_url}?{signing_content}{signature}'
def main():
base_url = 'https://api.example.com/v2/ivh/example_uri'
access_token = 'example_accesstoken'
wss_url = 'wss://api.example.com/v2/ws/ivh/example_uri'
# 示例一(访问需要提供 appkey 和 timestamp 参数的接口):
# 用户按需填入生成签名所需的公共参数
parameter1 = {
'appkey': 'example_appkey',
# 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟
# 示例时间戳:
# 'timestamp': '1717639699'
# 推荐使用下面的语句生成当前时间戳:
'timestamp': int(time.time()) # 使用当前时间戳(单位:秒)
}
url1 = GenReqURL(parameter1, access_token, base_url)
# 使用示例时间戳输出应当如下:
# Example 1:https://api.example.com/v2/ivh/example_uri?appkey=example_appkey&timestamp=1717639699&signature=aCNWYzZdplxWVo%2BJsqzZc9%2BJ9XrwWWITfX3eQpsLVno%3D
print('Example 1:', url1)
# 示例二(访问需要提供 appkey, requestID 和 timestamp 参数的接口):
# 用户按需填入生成签名所需的公共参数
parameter2 = {
'appkey': 'example_appkey',
'requestid': 'example_requestid',
# 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟
# 示例时间戳:
# 'timestamp': '1717639699'
# 推荐使用下面的语句生成当前时间戳:
'timestamp': int(time.time()) # 使用当前时间戳(单位:秒)
}
url2 = GenReqURL(parameter2, access_token, wss_url)
# 使用示例时间戳输出应当如下:
# Example 2:wss://api.example.com/v2/ws/ivh/example_uri?appkey=example_appkey&requestid=example_requestid&timestamp=1717639699&signature=QVenICk0VHtHGYZKXM6IC%2BW1CjZC1joSr%2Fx0gfKKYT4%3D
print('Example 2:', url2)
if __name__ == '__main__':
main()

const crypto = require('crypto');
// 用户可以在函数内部生成时间戳, 只需要传入appkey和accessToken即可获取访问接口所需的公共参数和签名
function GenSignature(signingContent, accessToken) {
// 计算 HMAC-SHA256 值
const hmac = crypto.createHmac('sha256', accessToken);
hmac.update(signingContent);
// 将 HMAC-SHA256 值进行 Base64 编码
const hashInBase64 = hmac.digest('base64');
// URL encode
const encodeSign = encodeURIComponent(hashInBase64);
// 拼接签名
const signature = `&signature=${encodeSign}`;
return signature;
}
function GenReqURL(parameter, accessToken, baseURL) {
// 按字典序拼接待计算签名的字符串
let signingContent = '';
const pathKey = Object.keys(parameter).sort();
for (const k of pathKey) {
if (signingContent !== '') {
signingContent += '&';
}
signingContent += `${k}=${parameter[k]}`;
}
// 计算签名
const signature = GenSignature(signingContent, accessToken);
// 拼接访问接口的完整URL
return `${baseURL}?${signingContent}${signature}`;
}
function main() {
const baseUrl = 'https://api.example.com/v2/ivh/example_uri';
const accesstoken = 'example_accesstoken';
const wssUrl = 'wss://api.example.com/v2/ws/ivh/example_uri';
// 示例一(访问需要提供 appkey 和 timestamp 参数的接口):
// 用户按需填入生成签名所需的公共参数
const parameter1 = {
appkey: 'example_appkey',
// 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟
// 示例时间戳:
// timestamp: '1717639699',
// 推荐使用下面的语句生成当前时间戳:
timestamp: Math.floor(Date.now() / 1000), // 使用当前时间戳(单位:秒)
};
const url1 = GenReqURL(parameter1, accesstoken, baseUrl);
// 使用示例时间戳输出应当如下:
// Example 1:https://api.example.com/v2/ivh/example_uri?appkey=example_appkey&timestamp=1717639699&signature=aCNWYzZdplxWVo%2BJsqzZc9%2BJ9XrwWWITfX3eQpsLVno%3D
console.log('Example 1:', url1);
// 示例二(访问需要提供 appkey, requestID 和 timestamp 参数的接口):
const parameter2 = {
appkey: 'example_appkey',
requestid: 'example_requestid',
// 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟
// 示例时间戳:
// timestamp: '1717639699',
// 推荐使用下面的语句生成当前时间戳:
timestamp: Math.floor(Date.now() / 1000), // 使用当前时间戳(单位:秒)
};
const url2 = GenReqURL(parameter2, accesstoken, wssUrl);
// 使用示例时间戳输出应当如下:
// Example 2:wss://api.example.com/v2/ws/ivh/example_uri?appkey=example_appkey&requestid=example_requestid&timestamp=1717639699&signature=QVenICk0VHtHGYZKXM6IC%2BW1CjZC1joSr%2Fx0gfKKYT4%3D
console.log('Example 2:', url2);
}
main();


五、接口调用注意事项

发送请求调用数智人相关接口时,请求体都要求有 header 和 payload 参数,请注意不要把这里的 header 理解为请求头,它也是请求体的一个参数。
以下为请求体的正确写法示例:
{
"Header": {

},
"Payload": {
"ReqId": "d7aa08da33dd4a662ad5be508c5b77cf",
"paramKey1": "paramValue1"
"paramKey2": "paramValue2"
}
}
以下为请求体的错误写法示例:
{
"ReqId": "d7aa08da33dd4a662ad5be508c5b77cf",
"paramKey1": "paramValue1"
"paramKey2": "paramValue2"
}