tencent cloud

文档反馈

数智人aPaas 接口调用方式

最后更新时间:2024-07-18 17:36:34
    本文主要提供 生成腾讯云智能数智人 aPaas 平台接口调用URL 的方式,以及常见编程语言 demo,语言类型包括 Golang、Java、C++、Python、JavaScript。

    一、必要参数获取

    appkey、accesstoken 等必要参数的获取请参考对应接口文档提供的方式。

    二、公共参数

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

    三、签名方法

    在调用 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();
    
    
    联系我们

    联系我们,为您的业务提供专属服务。

    技术支持

    如果你想寻求进一步的帮助,通过工单与我们进行联络。我们提供7x24的工单服务。

    7x24 电话支持