|
@@ -11,7 +11,7 @@ import traceback
|
|
|
import pjsua2 as pj
|
|
|
from enum import Enum
|
|
|
|
|
|
-from src.core.datasource import SIP_SERVER
|
|
|
+from src.core.datasource import SIP_SERVER, SERVE_HOST
|
|
|
from src.core.voip.constant import *
|
|
|
|
|
|
import requests
|
|
@@ -86,18 +86,18 @@ class MyAudioMediaPort(pj.AudioMediaPort):
|
|
|
|
|
|
#超时处理
|
|
|
current_time = time.time()
|
|
|
- print(f'onFrameReceived:self.wait_time={self.call.wait_time}, self.call.digit ={self.call.digit},asr_text:{asr_text},play_complete:{play_complete},self.call.inputType:{self.call.inputType}')
|
|
|
+ # print(f'onFrameReceived:self.wait_time={self.call.wait_time}, self.call.digit ={self.call.digit},asr_text:{asr_text},play_complete:{play_complete},self.call.inputType:{self.call.inputType}')
|
|
|
if self.call.wait_time and self.call.wait_time != "0" and play_complete and not asr_text and not self.call.digit :
|
|
|
self.wait_time_check(current_time, self.call.wait_time)
|
|
|
|
|
|
# 如果为超长类型的按键服务 超过30s未输入完成执行超时操作
|
|
|
if self.call.inputType == '1' and play_complete and not asr_text:
|
|
|
- self.wait_time_check(current_time, 15)
|
|
|
+ self.wait_time_check(current_time, 30)
|
|
|
|
|
|
message_queue_size = self.call.message_queue.qsize()
|
|
|
if (message_queue_size > 0 and not self.call.cur_player_file) or (message_queue_size > 0 and play_complete):
|
|
|
print('onFrameReceived:message_queue_size=', message_queue_size, 'play_complete=', play_complete, asr_text)
|
|
|
- self.call.cur_player_file, self.call.wait_time, self.call.inputType,self.call.action, self.call.nodeId = self.get_player_file()
|
|
|
+ self.call.cur_player_file, self.call.wait_time, self.call.inputType,self.call.action, self.call.node_id = self.get_player_file()
|
|
|
self.call.send_bot_speaker(self.call.cur_player_file)
|
|
|
|
|
|
# 重置播放完成标志和超时计时器,确保新的播放从头开始计时
|
|
@@ -126,13 +126,13 @@ class MyAudioMediaPort(pj.AudioMediaPort):
|
|
|
def get_player_file(self):
|
|
|
try:
|
|
|
message = self.call.message_queue.get(block=False)
|
|
|
- player_file = [item.voiceUrl for item in message.contents if item.contentType == 'voice']
|
|
|
+ player_file = [item.voice_url for item in message.contents if item.content_type == 'voice']
|
|
|
# self.call.wait_time = message.waitTime
|
|
|
# self.call.inputType = message.inputType
|
|
|
# self.call.action = message.action
|
|
|
# self.call.nodeId = message.nodeId
|
|
|
- print('get_player_file:', player_file,message.waitTime, message.inputType, message.action, message.nodeId)
|
|
|
- return player_file, message.waitTime, message.inputType, message.action, message.nodeId
|
|
|
+ print('get_player_file:', player_file,message.wait_time, message.inputType, message.action, message.node_id)
|
|
|
+ return player_file, message.wait_time, message.inputType, message.action, message.node_id
|
|
|
except Exception as e:
|
|
|
traceback.print_exc()
|
|
|
|
|
@@ -147,12 +147,10 @@ class MyAudioMediaPort(pj.AudioMediaPort):
|
|
|
# 检查超时时间是否已到
|
|
|
if current_time - self.play_start_time > int(wait_time):
|
|
|
self.play_complete_flag = False # 重置标志位,避免重复超时
|
|
|
- if wait_time == 15:
|
|
|
+ if wait_time == 30:
|
|
|
print("DTMF:超时",self.call.digit)
|
|
|
- # self.call.chat(f"DTMF({self.call.digit})DTMF","1")
|
|
|
self.call.user_asr_text_queue.put(f"DTMF({self.call.digit})DTMF")
|
|
|
else:
|
|
|
- # self.call.chat("6", "ASR408error")
|
|
|
print("DTMF:超时6shehehehehehhehhehehe")
|
|
|
self.call.user_asr_text_queue.put("ASR408error")
|
|
|
|
|
@@ -219,7 +217,7 @@ class MyCall(pj.Call):
|
|
|
self.inputType = None #记录按键类型 1为长按键类型
|
|
|
self.digit = '' # 存储长按键内容
|
|
|
self.action = None
|
|
|
- self.nodeId= 'start'
|
|
|
+ self.node_id= 'start'
|
|
|
|
|
|
self.cur_player_file = None #当前播放的文件
|
|
|
|
|
@@ -227,6 +225,18 @@ class MyCall(pj.Call):
|
|
|
self.asr = TestSt(call_id, message_receiver=self.on_receiver_asr_result) # 创建ASR实例
|
|
|
self.asr.start() # 启动ASR线程
|
|
|
|
|
|
+ self.call_phone = self.get_phone()
|
|
|
+
|
|
|
+ def get_phone(self):
|
|
|
+ import re
|
|
|
+ call_info = self.getInfo()
|
|
|
+ match = re.match(r'"(\d+)" <sip:(\d+)@', call_info.remoteUri)
|
|
|
+ if match:
|
|
|
+ print("Phone Number:", match.group(1))
|
|
|
+ return match.group(1) # 假设显示名称部分是手机号
|
|
|
+ else:
|
|
|
+ return ""
|
|
|
+ print("Failed to parse the phone number from remoteUri.")
|
|
|
def is_play_complete(self): #语音机器人是否播放结束
|
|
|
if self.cur_player_file:
|
|
|
player_id = murmur3_32(self.cur_player_file)
|
|
@@ -250,7 +260,7 @@ class MyCall(pj.Call):
|
|
|
|
|
|
def onCallState(self, prm):
|
|
|
call_info = self.getInfo()
|
|
|
- print("Call state: ", call_info.stateText)
|
|
|
+ print("Call state: ",call_info.state)
|
|
|
|
|
|
# pj.PJSIP_INV_STATE_NULL
|
|
|
# pj.PJSIP_INV_STATE_CALLING
|
|
@@ -329,12 +339,12 @@ class MyCall(pj.Call):
|
|
|
ToTextBotAgent(user_asr_text,self)
|
|
|
|
|
|
def say_end_action(self, action):
|
|
|
- print('handling_release', action.actionCode)
|
|
|
- actionCode = action.actionCode
|
|
|
- if actionCode == 'hang': # 挂断
|
|
|
- actionContent = action.actionContent
|
|
|
- print(f'todo 挂电话:{actionContent}')
|
|
|
- elif actionCode == 'transfer': # 转人工
|
|
|
+ print('handling_release', action.action_code)
|
|
|
+ action_code = action.action_code
|
|
|
+ if action_code == 'hang': # 挂断
|
|
|
+ action_content = action.action_content
|
|
|
+ print(f'todo 挂电话:{action_content}')
|
|
|
+ elif action_code == 'transfer': # 转人工
|
|
|
print('todo 转人工')
|
|
|
|
|
|
class ToTextBotAgent:
|
|
@@ -345,37 +355,43 @@ class ToTextBotAgent:
|
|
|
|
|
|
self.call_agent = call_agent
|
|
|
self.request_data = BotChatRequest(
|
|
|
- nodeId=self.call_agent.nodeId,
|
|
|
- userId="139311",
|
|
|
- sessionId="1",
|
|
|
- recordId="2",
|
|
|
- taskId="ceshi",
|
|
|
- asrText=user_asr_text
|
|
|
+ nodeId=self.call_agent.node_id,
|
|
|
+ userId=self.call_agent.call_phone,
|
|
|
+ sessionId="1334343434",
|
|
|
+ recordId="",
|
|
|
+ taskId="10001",
|
|
|
+ asrText=user_asr_text,
|
|
|
+ ext= None
|
|
|
)
|
|
|
# 发送请求并处理响应
|
|
|
- self.test_request(self.request_data)
|
|
|
+ # self.test_request(self.request_data)
|
|
|
+ self.to_quest(self.request_data)
|
|
|
|
|
|
|
|
|
def to_quest(self, request: BotChatRequest):
|
|
|
# 将实体类转换为JSON字符串
|
|
|
headers = {'Content-Type': 'application/json'}
|
|
|
- request_json = request.to_json_string()
|
|
|
+ request_data = request.to_json_string()
|
|
|
+ url = f"http://{SERVE_HOST}:40072/botservice"
|
|
|
# 发送POST请求
|
|
|
+ print(f"请求数据:{request_data},url:{url}")
|
|
|
try:
|
|
|
- response = requests.post('http://example.com/api', data=request_json, headers=headers) # 使用占位URL
|
|
|
+ response = requests.post(url=url, json=json.loads(request_data), headers=headers, timeout=10) # 使用占位URL
|
|
|
+ print(f"原始响应内容:{response.text}")
|
|
|
if response.status_code == 200:
|
|
|
- # 成功,解析响应JSON
|
|
|
response_data = response.json()
|
|
|
- # return ChatResponse.from_json(json.dumps(response_data)) # 转换为JSON字符串并解析
|
|
|
- parsed_response = ChatMessage.from_json(response_data)
|
|
|
- self.call_agent.message_queue.put(parsed_response)
|
|
|
+ if "data" in response_data and response_data["code"]==0:
|
|
|
+ data = response_data["data"]
|
|
|
+ print(f"响应数据:{data}")
|
|
|
+ parsed_response = ChatMessage.from_json(data)
|
|
|
+ self.call_agent.message_queue.put(parsed_response)
|
|
|
+ else:
|
|
|
+ print("响应中没有 'data' 字段")
|
|
|
else:
|
|
|
# 错误处理
|
|
|
print(f"请求失败,状态码: {response.status_code}, 响应内容: {response.text}")
|
|
|
- return None
|
|
|
except requests.RequestException as e:
|
|
|
- traceback.print_exc()
|
|
|
- return None
|
|
|
+ print(f"请求发生异常: {e}")
|
|
|
|
|
|
# 模拟接口请求返回
|
|
|
def test_request(self, params: BotChatRequest):
|