实时音视频 AI 对话服务端回调

这篇用于介绍 AI 服务(AI 实时对话)相关的云 API 接口产生的事件,以 HTTP/HTTPS 请求的形式通知到你的服务器。可以以向腾讯云提供相关的配置信息来开通该服务。你也可以结合TRTC的 房间与媒体回调 使用,实现更多自定义逻辑。

相关产品
实时音视频 产品页,含版本规格、价格与购买入口。

一、配置信息

实时音视频 TRTC 控制台支持自助配置回调信息,配置完成后即可接收事件回调通知。详细操作指引请参见 回调配置。

注意:你需要提前准备以下信息:

二、超时重试

事件回调服务器在发送消息通知后,5秒内没有收到你的服务器的响应,即认为通知失败。首次通知失败后会立即重试,后续失败会以10秒的间隔继续重试,直到消息存续时间超过1分钟,不再重试。

三、事件回调消息格式

事件回调消息以 HTTP/HTTPS POST 请求发送给你的服务器,其中:

·字符编码格式:UTF-8。

·请求:body 格式为 JSON。

·应答:HTTP STATUS CODE = 200,服务端忽略应答包具体内容,为了协议友好,建议客户应答内容携带 JSON: {"code":0}。

·包体示例:下述为“启动AI对话任务成功”事件的包体示例。

{ "EventGroupId": 9, "EventType": 901, "CallbackTs": 1687770730166, "EventInfo": { "EventMsTs": 1622186275757, "TaskId": "hKPD2Q7kBVzu-6ezFiqmcEBJQCykqbZrS9OOTE46uYlb4NvQDIaEXlpOlLXFtGBiado5oP0zfLDZs", "RoomId": "1234", "RoomIdType": 0, "Payload": { "Status": 0 } }}

四、回调消息参数

·事件回调消息的 header 中包含以下字段:

字段名 值
Content-Type application/json
Sign 签名值
SdkAppId sdk application id

·事件回调消息的 body 中包含以下字段:

字段名 类型 含义
EventGroupId Number 事件组 ID,混流转推事件固定为4
EventType Number 回调通知的事件类型
CallbackMsTs Number 事件回调服务器向你的服务器发出回调请求的 Unix 时间戳,单位为毫秒
EventInfo JSON Object 事件信息

五、事件组 ID

字段名 值 含义
EVENT_GROUP_AI_SERVICE 9 AI 服务事件组

六、事件类型

字段名 值 含义
EVENT_TYPE_AI_SERVICE_START 901 AI 任务开始状态回调
EVENT_TYPE_AI_SERVICE_STOP 902 AI 任务结束状态回调
EVENT_TYPE_AI_SERVICE_MSG 903 回调ASR识别的完整一句话或 LLM 返回的完整内容
EVENT_TYPE_AI_START_OF_SPEECH 904 ASR 识别一句话的开始回调
EVENT_TYPE_AI_SPEAKING_FINISHED 905 在一轮对话中,AI 说完话的回调
EVENT_TYPE_AI_METRIC_MESSAGE 906 AI 服务中调用 LLM/TTS 的指标回调
EVENT_TYPE_AI_ERROR_METRIC_CALLBACK 908 AI 服务的调用指标错误回调
EVENT_TYPE_AI_SESSION_STATUS_CALLBACK 909 AI 会话准备就绪回调,表示音视频通道已建立,可以进行对话。
EVENT_TYPE_AI_ROUND_FINISHED 910 一轮对话结束的回调

七、事件类型为(901)时事件信息的定义:

字段名 类型 含义
EventMsTs String 事件发生的 Unix 时间戳,单位为毫秒
TaskId String AI 任务 ID
RoomId String TRTC 的房间 ID
RoomIdType Integer 0:表示数字房间号1:表示字符串房间号
Payload.Status Number 0:启动 AI 任务成功1:启动 AI 任务失败

{ "EventGroupId": 9, "EventType": 901, "CallbackTs": 1687770730166, "EventInfo": { "EventMsTs": 1622186275757, "TaskId": "xx", "RoomId": "1234", "RoomIdType": 0, "Payload": { "Status": 0 } }}

八、事件类型为(902)时事件信息的定义:

字段名 类型 含义
EventMsTs String 事件发生的 Unix 时间戳,单位为毫秒
TaskId String AI 任务 ID
RoomId String TRTC 的房间 ID
RoomIdType Integer 0:表示数字房间号1:表示字符串房间号
Payload.LeaveCode Integer 0:正常调用停止接口后任务退出1:业务自己踢掉转录机器人后任务退出2:业务自己解散房间后任务退出3:TRTC 服务端踢掉机器人4:TRTC 服务端解散房间98:内部异常错误,建议业务进行重试99:代表房间内除了转录机器人没有其他用户流,超过指定时间退出

{ "EventGroupId": 9, "EventType": 902, "CallbackTs": 1687770730166, "EventInfo": { "EventMsTs": 1622186275757, "TaskId": "xx", "RoomId": "1234", "RoomIdType": 0, "Payload": { "LeaveCode": 0 } }}

九、事件类型为(903)时事件信息的定义:

字段名 类型 含义
EventMsTs String 事件发生的 Unix 时间戳,单位为毫秒
TaskId String AI 任务 ID
RoomId String TRTC 的房间 ID
RoomIdType Integer 0:表示数字房间号1:表示字符串房间号
Payload JSON Object 为 JSON 对象,与客户端自定义消息回调格式一致{ "UserId":"", "Text":"", "StartTimeMs":1234, "EndTimeMs":1269, "RoundId":"xxxxxx" // 一轮对话的唯一id }

{ "EventGroupId": 9, "EventType": 903, "CallbackTs": 1687770730166, "EventInfo": { "EventMsTs": 1622186275757, "TaskId": "xx", "RoomId": "1234", "RoomIdType": 0, "Payload": { "UserId":"", "Text":"", "StartTimeMs":1234, "EndTimeMs":1269, "RoundId":"xxxxxx" } }}

十、事件类型为(904)时事件信息的定义:

字段名 类型 含义
EventMsTs String 事件发生的 Unix 时间戳,单位为毫秒
TaskId String AI 任务 ID
RoomId String TRTC 的房间 ID
RoomIdType Integer 0:表示数字房间号1:表示字符串房间号
Payload JSON Object 为 JSON 对象{ "UserId": "xxx", "RoundId": "xxxxx" // 一轮对话的唯一id}

{ "EventGroupId": 9, "EventType": 904, "CallbackTs": 1687770730166, "EventInfo": { "EventMsTs": 1622186275757, "TaskId": "xx", "RoomId": "1234", "RoomIdType": 0, "Payload": { "UserId": "xxx", "RoundId": "xxxxx" } }}

十一、事件类型为(905)时事件信息的定义:

字段名 类型 含义
EventMsTs String 事件发生的 Unix 时间戳,单位为毫秒
TaskId String AI 任务 ID
RoomId String TRTC 的房间 ID
RoomIdType Integer 0:表示数字房间号1:表示字符串房间号
Payload JSON Object 为 JSON 对象{ "UserId": "UserId", // AI机器人的UserId "RoundId": "RoundId", // 当前对话的RoundId "Text": "Text" // 在本轮对话中,AI机器人已经说的文本}

{ "EventGroupId": 9, "EventType": 905, "CallbackTs": 1687770730166, "EventInfo": { "EventMsTs": 1622186275757, "TaskId": "xx", "RoomId": "1234", "RoomIdType": 0, "Payload": { "UserId": "UserId", "RoundId": "RoundId", "Text": "Text" } }}

十二、事件类型为(906)时事件信息的定义:

字段名 类型 含义
EventMsTs String 事件发生的 Unix 时间戳,单位为毫秒
TaskId String AI 任务 ID
RoomId String TRTC 的房间 ID
RoomIdType Integer 0:表示数字房间号1:表示字符串房间号
Payload JSON Object 为 JSON 对象{ "Metric": "llm_network_latency", // 指标名 "Value": 218, // 指标 "Tag": { "RoundId": "070c4908-105", // 对话轮次id }}调用指标名称如下:asr_latencyllm_network_latencyllm_first_tokentts_network_latencytts_first_frame_latencytts_discontinuityinterruption

{ "EventGroupId": 9, "EventType": 906, "CallbackTs": 1687770730166, "EventInfo": { "EventMsTs": 1622186275757, "TaskId": "xx", "RoomId": "1234", "RoomIdType": 0, "Payload": { "Metric": "llm_first_token", "Value": 218, "Tag": { "RoundId": "070c4908-1057-4ced-a949-356bf11848bc" } } }}

十三、事件类型为(908)时事件信息的定义:

字段名 类型 含义
EventMsTs String 事件发生的 Unix 时间戳,单位为毫秒
TaskId String AI 任务 ID
RoomId String TRTC 的房间 ID
RoomIdType Integer 0:表示数字房间号1:表示字符串房间号
Payload JSON Object 为 JSON 对象{ "Metric": "llm_error", // 指标名 "Tag": { "RoundId": "070c4908-1057-4ced-a949-356bf11848bc", "Code": 0, // 服务错误码 "Message": "" // 错误信息的详细描述 }}错误指标名称如下:asr_errorllm_errortts_error

{ "EventGroupId": 9, "EventType": 908, "CallbackTs": 1687770730166, "EventInfo": { "EventMsTs": 1622186275757, "TaskId": "xx", "RoomId": "1234", "RoomIdType": 0, "Payload": { "Metric": "llm_error", "Tag": { "RoundId": "070c4908-1057-4ced-a949-356bf11848bc", "Code": 0, "Message": "" } } }}

十四、事件类型为(909)时事件信息的定义:

字段名 类型 含义
EventMsTs String 事件发生的 Unix 时间戳,单位为毫秒
TaskId String AI 任务 ID
RoomId String TRTC 的房间 ID
RoomIdType Integer 0:表示数字房间号1:表示字符串房间号
Payload JSON Object 为 JSON 对象{"Status": "session_ready" // 表示音视频通道已建立,可以进行对话。}

{ "EventGroupId": 9, "EventType": 909, "CallbackTs": 1687770730166, "EventInfo": { "EventMsTs": 1622186275757, "TaskId": "xx", "RoomId": "1234", "RoomIdType": 0, "Payload": { "Status": "session_ready" } }}

十五、事件类型为(910)时事件信息的定义:

字段名 类型 含义
EventMsTs String 事件发生的 Unix 时间戳,单位为毫秒
TaskId String AI 任务 ID
RoomId String TRTC 的房间 ID
RoomIdType Integer 0:表示数字房间号1:表示字符串房间号
Payload JSON Object 为 JSON 对象{"RoundId": "RoundId", // 本轮对话的RoundId}

{ "EventGroupId": 9, "EventType": 910, "CallbackTs": 1687770730166, "EventInfo": { "EventMsTs": 1622186275757, "TaskId": "xx", "RoomId": "1234", "RoomIdType": 0, "Payload": { "RoundId": "RoundId" } }}

十六、计算签名

签名由 HMAC SHA256 加密算法计算得出,你的事件回调接收服务器收到回调消息后,通过同样的方式计算出签名,相同则说明是腾讯云的实时音视频的事件回调,没有被伪造。签名的计算如下所示:

//签名 Sign 计算公式中 key 为计算签名 Sign 用的加密密钥。Sign = base64(hmacsha256(key, body))

注意:body 为你收到回调请求的原始包体,不要做任何转化,示例如下:

注意:body="{\\n\\t\\"Ebody="{\\"EventGroupId\\":7,\\"EventType\\":701,\\"CallbackMsTs\\":1701937900012,\\"EventInfo\\":{\\"EventMsTs\\":1701937900012,\\"TaskId\\":\\"WMdqEeEgj2ksqnyUsuXC+qLkVypGmwjrgh1JC6ZefVP+rvsidDnZsAw8uWgX0XRGvdSVfAMunise2kcZaefdgHvx3-M2v6fmTjRNgg..\\",\\"Status\\":0}}"ventGroupId\\":\\t1,\\n\\t\\"EventType\\":\\t103,\\n\\t\\"CallbackTs\\":\\t1615554923704,\\n\\t\\"EventInfo\\":\\t{\\n\\t\\t\\"RoomId\\":\\t12345,\\n\\t\\t\\"EventTs\\":\\t1608441737,\\n\\t\\t\\"UserId\\":\\t\\"test\\",\\n\\t\\t\\"UniqueId\\":\\t1615554922656,\\n\\t\\t\\"Role\\":\\t20,\\n\\t\\t\\"Reason\\":\\t1\\n\\t}\\n}"

十七、签名校验示例

JavaPythonPHPGolangimport javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import java.util.Base64;//# 功能:第三方回调sign校验//# 参数://# key:控制台配置的密钥key//# body:腾讯云回调返回的body体//# sign:腾讯云回调返回的签名值sign//# 返回值://# Status:OK 表示校验通过,FAIL 表示校验失败,具体原因参考Info//# Info:成功/失败信息public class checkSign { public static String getResultSign(String key, String body) throws Exception { Mac hmacSha256 = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256"); hmacSha256.init(secret_key); return Base64.getEncoder().encodeToString(hmacSha256.doFinal(body.getBytes())); } public static void main(String[] args) throws Exception { String key = "123654"; String body = "{\\n" + "\\t\\"EventGroupId\\":\\t2,\\n" + "\\t\\"EventType\\":\\t204,\\n" + "\\t\\"CallbackTs\\":\\t1664209748188,\\n" + "\\t\\"EventInfo\\":\\t{\\n" + "\\t\\t\\"RoomId\\":\\t8489,\\n" + "\\t\\t\\"EventTs\\":\\t1664209748,\\n" + "\\t\\t\\"EventMsTs\\":\\t1664209748180,\\n" + "\\t\\t\\"UserId\\":\\t\\"user_85034614\\",\\n" + "\\t\\t\\"Reason\\":\\t0\\n" + "\\t}\\n" + "}"; String Sign = "kkoFeO3Oh2ZHnjtg8tEAQhtXK16/KI05W3BQff8IvGA="; String resultSign = getResultSign(key, body); if (resultSign.equals(Sign)) { System.out.println("{'Status': 'OK', 'Info': '校验通过'}"); } else { System.out.println("{'Status': 'FAIL', 'Info': '校验失败'}"); } }}# -*- coding: utf8 -*-import hmacimport base64from hashlib import sha256# 功能:第三方回调sign校验# 参数:# key:控制台配置的密钥key# body:腾讯云回调返回的body体# sign:腾讯云回调返回的签名值sign# 返回值:# Status:OK 表示校验通过,FAIL 表示校验失败,具体原因参考Info# Info:成功/失败信息def checkSign(key, body, sign): temp_dict = {} computSign = base64.b64encode(hmac.new(key.encode('utf-8'), body.encode('utf-8'), digestmod=sha256).digest()).decode('utf-8') print(computSign) if computSign == sign: temp_dict['Status'] = 'OK' temp_dict['Info'] = '校验通过' return temp_dict else: temp_dict['Status'] = 'FAIL' temp_dict['Info'] = '校验失败' return temp_dictif __name__ == '__main__': key = '123654' body = "{\\n" + "\\t\\"EventGroupId\\":\\t2,\\n" + "\\t\\"EventType\\":\\t204,\\n" + "\\t\\"CallbackTs\\":\\t1664209748188,\\n" + "\\t\\"EventInfo\\":\\t{\\n" + "\\t\\t\\"RoomId\\":\\t8489,\\n" + "\\t\\t\\"EventTs\\":\\t1664209748,\\n" + "\\t\\t\\"EventMsTs\\":\\t1664209748180,\\n" + "\\t\\t\\"UserId\\":\\t\\"user_85034614\\",\\n" + "\\t\\t\\"Reason\\":\\t0\\n" + "\\t}\\n" + "}" sign = 'kkoFeO3Oh2ZHnjtg8tEAQhtXK16/KI05W3BQff8IvGA=' result = checkSign(key, body, sign) print(result)<?phpclass TlsEventSig { private $key = false; private $body = false; public function __construct( $key, $body ) { $this->key = $key; $this->body = $body; } private function __hmacsha256() { $hash = hash_hmac( 'sha256', $this->body, $this->key, true ); return base64_encode( $hash); } public function genEventSig() { return $this->__hmacsha256(); }}$key="789";$data="{\\n\\t\\"EventGroupId\\":\\t1,\\n\\t\\"EventType\\":\\t101,\\n\\t\\"CallbackTs\\":\\t1608086882372,\\n\\t\\"EventInfo\\":\\t{\\n\\t\\t\\"RoomId\\":\\t20222,\\n\\t\\t\\"EventTs\\":\\t1608086882,\\n\\t\\t\\"UserId\\":\\t\\"222222_phone\\"\\n\\t}\\n}";$api = new TlsEventSig($key, $data);echo $api->genEventSig();package mainimport "fmt"import ( "crypto/hmac" "crypto/sha256" "encoding/base64")func main () { var data = "{\\n\\t\\"EventGroupId\\":\\t1,\\n\\t\\"EventType\\":\\t101,\\n\\t\\"CallbackTs\\":\\t1608086882372,\\n\\t\\"EventInfo\\":\\t{\\n\\t\\t\\"RoomId\\":\\t20222,\\n\\t\\t\\"EventTs\\":\\t1608086882,\\n\\t\\t\\"UserId\\":\\t\\"222222_phone\\"\\n\\t}\\n}" var key = "789" //JSRUN引擎2.0,支持多达30种语言在线运行,全仿真在线交互输入输出。 fmt.Println(hmacsha256(data,key))}func hmacsha256(data string, key string) string { h := hmac.New(sha256.New, []byte(key)) h.Write([]byte(data)) return base64.StdEncoding.EncodeToString(h.Sum(nil))}

赞 (0)
上一篇 4天前
下一篇 4天前