配合官方文档食用

Docs

https://bytedance.larkoffice.com/docx/CUORdIDWDoM70rxuWbicAthXn1g

配置类

public class AigcConfig
{
    public static string ak = "";
    public static string sk = "";
    public static string APP_ID = "";
    public static string TOKEN = "";
    public static string AppId = "";
    public static string AccessToken = "";
    public static string RoomId = "";
    public static string UserId = "";
    public static string TaskId = "";
    public static string EndPointId = "";

    public static object GetStartVoiceChatRequestBody()
    {
        var requestBody = new
        {
            AppId = APP_ID,
            RoomId = RoomId,
            TaskId = TaskId,
            Config = new
            {
                ASRConfig = new
                {
                    Provider = "volcano",
                    ProviderParams = new
                    {
                        Mode = "smallmodel",
                        AppId = AppId,
                        AccessToken = AccessToken,
                        Cluster = "volcengine_streaming_common",
                    }
                },
                TTSConfig = new
                {
                    Provider = "volcano_bidirection",
                    ProviderParams = new
                    {
                        app = new
                        {
                            appid = AppId,
                            cluster = "volcano_tts",
                            token = AccessToken,
                        },
                        audio = new
                        {
                            voice_type = "zh_male_qingshuangnanda_mars_bigtts",
                            speech_rate = 0,
                            pitch_rate = 0
                        },
                        ResourceId = "volc.service_type.10029"
                    }
                },
                LLMConfig = new
                {
                    Mode = "ArkV3",
                    EndPointId = EndPointId,
                    MaxTokens = 1024,
                    Temperature = 0.1,
                    TopP = 0.3,
                    SystemMessages = new[]
                    {
                        "你是小宁,性格幽默又善解人意。你在表达时需简明扼要,有自己的观点。"
                    },
                    UserMessages = new[]
                    {
                        "user:\"你是谁\"",
                        "assistant:\"我是问答助手\"",
                        "user:\"你能干什么\"",
                        "assistant:\"我能回答问题\""
                    },
                    HistoryLength = 3
                }
            },
            AgentConfig = new
            {
                TargetUserId = new[] { UserId },
                WelcomeMessage = "你好,请问你有什么需要帮助",
                UserId = "BotName001"
            }
        };

        return requestBody;
    }

    public static object GetUpdateVoiceChatRequestBody()
    {
        var requestBody = new
        {
            AppId = APP_ID,
            RoomId = RoomId,
            TaskId = TaskId,
            Command = "interrupt"
        };

        return requestBody;
    }

    public static object GetStopVoiceChatRequestBody()
    {
        var requestBody = new
        {
            AppId = APP_ID,
            RoomId = RoomId,
            TaskId = TaskId
        };
        return requestBody;
    }

}

调用智能体

using System;
using System.Collections.Generic;
using System.Text;
using Cysharp.Threading.Tasks;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Networking;

public static class OpenAPIs
{
    //开启AIGC
    public static async UniTask OpenAIGC()
    {
        string url = "https://rtc.volcengineapi.com?Action=StartVoiceChat&Version=2024-12-01";
        string action = "StartVoiceChat";
        string Payload = JsonConvert.SerializeObject(AigcConfig.GetStartVoiceChatRequestBody());
        await SendRequest(url, action, Payload);
    }

    //更新AIGC
    public static async UniTask UpdateAIGC()
    {
        string url = "https://rtc.volcengineapi.com?Action=UpdateVoiceChat&Version=2024-12-01";
        string action = "UpdateVoiceChat";
        string Payload = JsonConvert.SerializeObject(AigcConfig.GetUpdateVoiceChatRequestBody());
        await SendRequest(url, action, Payload);
    }

    //关闭AIGC
    public static async UniTask StopAIGC()
    {
        string url = "https://rtc.volcengineapi.com?Action=StopVoiceChat&Version=2024-12-01";
        string action = "StopVoiceChat";
        string Payload = JsonConvert.SerializeObject(AigcConfig.GetStopVoiceChatRequestBody());
        await SendRequest(url, action, Payload);
    }

    public static async UniTask SendRequest(string url, string action, string payload)
    {
        var queryString = new Dictionary<string, string>
        {
            { "Version", "2024-12-01" },
            { "Action", action }
        };
        string time = DateTime.UtcNow.ToString("yyyyMMddTHHmmssZ");
        var headers = new Dictionary<string, string>
        {
            { "content-type", "application/json" },
            { "host", "rtc.volcengineapi.com" },
            { "x-content-sha256",  Hash(payload)},
            { "x-date", time},
        };
        string region = "cn-north-1";
        string Authorization = Signer.Sign("POST", queryString, headers, payload, AigcConfig.ak, AigcConfig.sk, region);

        using UnityWebRequest request = new UnityWebRequest(url, "POST");
        request.SetRequestHeader("Host", "rtc.volcengineapi.com");
        request.SetRequestHeader("Content-Type", "application/json");
        request.SetRequestHeader("X-Date", time);
        request.SetRequestHeader("X-Content-Sha256", Hash(payload));
        request.SetRequestHeader("Authorization", Authorization);

        // 添加Payload数据
        byte[] bodyRaw = Encoding.UTF8.GetBytes(payload);
        request.uploadHandler = new UploadHandlerRaw(bodyRaw);
        request.downloadHandler = new DownloadHandlerBuffer();

        await request.SendWebRequest();
        if (request.result == UnityWebRequest.Result.Success)
        {
            Debug.Log("Success: " + request.downloadHandler.text);
        }
        else
        {
            Debug.Log("Error: " + request.error);
        }
    }


    // SHA256 哈希算法
    private static string Hash(string input)
    {
        using (System.Security.Cryptography.SHA256 sha256 = System.Security.Cryptography.SHA256.Create())
        {
            byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(input));
            return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
        }
    }
}

签名类

using System;
using System.Text;
using UnityEngine;
using Newtonsoft.Json;
using UnityEditor.Experimental.GraphView;
using System.Collections.Generic;
using System.Linq;

public class Signer
{
    //Hash 代指 SHA256 算法,HexEncode 代指转 16 进制编码,Hmac 指代 Hmac_SHA256

    /// <summary>
    /// 获取签名
    /// </summary>
    /// <param name="Method"> HTTP 请求方法,GET 或 POST</param>
    /// <param name="QueryString">查询字符串</param>
    /// <param name="Headers">请求头</param>
    /// <param name="RequestPayload">请求体</param>
    /// <param name="ak"> AccessKeyID </param>
    /// <param name="sk"> SecretAccessKey </param>
    /// <returns></returns>
    public static string Sign(string Method,
    Dictionary<string, string> QueryString,
    Dictionary<string, string> Headers,
    string RequestPayload,
    string ak, string sk, string Region)
    {
        string HTTPRequestMethod = Method;
        string CanonicalURI = "/";
        var sortedParams = QueryString.OrderBy(p => p.Key, StringComparer.Ordinal);
        string CanonicalQueryString = string.Join("&", sortedParams.Select(p =>
            $"{Uri.EscapeDataString(p.Key)}={Uri.EscapeDataString(p.Value)}"));
        var sortedHeaders = Headers.OrderBy(h => h.Key, StringComparer.OrdinalIgnoreCase);
        string CanonicalHeaders = string.Join("\n", sortedHeaders.Select(h =>
            $"{h.Key.ToLower()}:{h.Value.Trim()}"));
        string SignedHeaders = string.Join(";", sortedHeaders.Select(h => h.Key.ToLower()));

        string CanonicalRequest =
                HTTPRequestMethod + '\n' +
                CanonicalURI + '\n' +
                CanonicalQueryString + '\n' +
                CanonicalHeaders + '\n' +
                '\n' +
                SignedHeaders + '\n' +
                HexEncode(Hash(RequestPayload));

        string Algorithm = "HMAC-SHA256";
        string RequestDate = Headers["x-date"];
        string CredentialScope = $"{RequestDate.Substring(0, 8)}/{Region}/{Headers["host"].Split(".")[0]}/request";

        string StringToSign =
                Algorithm + '\n' +
                RequestDate + '\n' +
                CredentialScope + '\n' +
                HexEncode(Hash(CanonicalRequest));

        string kSecret = sk;
        string kDate = Hmac(kSecret, RequestDate.Substring(0, 8));
        string kRegion = Hmac(kDate, Region);
        string kService = Hmac(kRegion, Headers["host"].Split(".")[0]);
        string kSigning = Hmac(kService, "request");

        string Signature = Hmac(kSigning, StringToSign);
        string Credential = $"{ak}/{CredentialScope}";
        string Authorization = $"{Algorithm} Credential={Credential}, SignedHeaders={SignedHeaders}, Signature={Signature}";

        return Authorization;
    }
 
    // SHA256 哈希算法
    private static byte[] Hash(string input)
    {
        using (System.Security.Cryptography.SHA256 sha256 = System.Security.Cryptography.SHA256.Create())
        {
            return sha256.ComputeHash(Encoding.UTF8.GetBytes(input));
        }
    }
    // 16 进制编码
    private static string HexEncode(byte[] data)
    {
        return BitConverter.ToString(data).Replace("-", "").ToLower();
    }

    //Hmac_SHA256 哈希算法
    private static string Hmac(string key, string message)
    {
        try
        {
            // 将16进制字符串转换为字节数组
            byte[] keyBytes = new byte[key.Length / 2];
            for (int i = 0; i < keyBytes.Length; i++)
            {
                keyBytes[i] = Convert.ToByte(key.Substring(i * 2, 2), 16);
            }
            using System.Security.Cryptography.HMACSHA256 hmac = new System.Security.Cryptography.HMACSHA256(keyBytes);
            byte[] hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
            return HexEncode(hashBytes);
        }
        catch (System.Exception)
        {
            byte[] keyBytes = Encoding.UTF8.GetBytes(key);
            using System.Security.Cryptography.HMACSHA256 hmac = new System.Security.Cryptography.HMACSHA256(keyBytes);
            byte[] hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
            return HexEncode(hashBytes);
        }
    }
}

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐