interface.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. @Time : 2024/10/11 14:08
  5. @File : interface.py
  6. @Desc :
  7. """
  8. from typing import Union,Optional
  9. from pydantic import BaseModel
  10. from scene import Msg
  11. import json
  12. from util import voice_service
  13. from entity import Error
  14. from config import get_logger
  15. from starlette.responses import JSONResponse
  16. logger = get_logger()
  17. class reqRobot(BaseModel):
  18. """对话请求参数
  19. """
  20. nodeId:Optional[str]="start"
  21. userId:str
  22. sessionId:str
  23. taskId:str
  24. asrText:Optional[str] = None
  25. ext:Optional[str] = None
  26. recordId:Optional[str] = None
  27. class ChatAction:
  28. def __init__(self, action_code=None, action_content=None):
  29. self.action_code = action_code # normal:正常通话;hang:挂断;transfer:转人工
  30. self.action_content = action_content # 动作内容
  31. def to_json_string(self):
  32. return json.dumps(self.__dict__, ensure_ascii=False)
  33. @classmethod
  34. def from_json(cls, json_data):
  35. return cls(
  36. action_code=json_data.get("action_code"),
  37. action_content=json_data.get("action_content")
  38. )
  39. class ChatContent:
  40. def __init__(self, content_type=None, content=None, voice_url=None, voice_content=None):
  41. self.content_type = content_type # 播放类型
  42. self.content = content # 播放内容
  43. self.voice_url = voice_url # 语音地址
  44. self.voice_content = voice_content # 语音文本
  45. def to_json_string(self):
  46. return json.dumps(self.__dict__, ensure_ascii=False)
  47. @classmethod
  48. def from_json(cls, json_data):
  49. return cls(
  50. content_type=json_data.get("content_type"),
  51. content=json_data.get("content"),
  52. voice_url=json_data.get("voice_url"),
  53. voice_content=json_data.get("voice_content")
  54. )
  55. class ChatMessage:
  56. def __init__(self, node_id=None, contents=None, interruptable=None, wait_time=None,
  57. action=None, inputType=None):
  58. self.node_id = node_id # 节点id
  59. self.contents = contents if contents is not None else [] # 内容列表
  60. self.interruptable = interruptable # 是否可打断
  61. self.wait_time = wait_time # 用户静默时长
  62. self.action = action # 动作代码
  63. self.inputType = inputType
  64. def to_json_string(self):
  65. return json.dumps({
  66. "node_id": self.node_id,
  67. "contents": [content.__dict__ for content in self.contents],
  68. # "interruptable": self.interruptable,
  69. "wait_time": self.wait_time,
  70. "action": self.action.__dict__ if self.action else None,
  71. "inputType": self.inputType
  72. }, ensure_ascii=False)
  73. @classmethod
  74. def from_json(cls, json_data):
  75. contents = [ChatContent.from_json(item) for item in json_data.get("contents", [])]
  76. action = ChatAction.from_json(json_data.get("action", {})) if json_data.get("action") else None
  77. return cls(
  78. node_id=json_data.get("node_id"),
  79. contents=contents,
  80. interruptable=json_data.get("interruptable"),
  81. wait_time=json_data.get("wait_time"),
  82. action=action,
  83. inputType = json_data.get("inputType")
  84. )
  85. class ChatResponse:
  86. def __init__(self, data=None, message=None, code=None):
  87. self.data = data if data is not None else ChatMessage()
  88. self.message = message
  89. self.code = code
  90. def to_json_string(self):
  91. return JSONResponse(content={
  92. "data": json.loads(self.data.to_json_string()),
  93. "message": self.message,
  94. "code": self.code
  95. }, media_type="application/json")
  96. @classmethod
  97. def from_json(cls, json_string):
  98. data = json.loads(json_string)
  99. response_data = ChatMessage.from_json(data.get("data", {}))
  100. return cls(
  101. data=response_data,
  102. message=data.get("message"),
  103. code=data.get("code")
  104. )
  105. @staticmethod
  106. def get_content(msg: Msg):
  107. _contents, code, mess = [], 0, ''
  108. if msg.question:
  109. contents = msg.question.split("&")
  110. if len(contents) >= 1 and contents[0]:
  111. for content in contents:
  112. if not content or len(content)==0:
  113. continue
  114. if len(contents) >1 and contents[1] and content ==contents[0]:
  115. voice_url = voice_service(content, True, 1000)
  116. else:
  117. voice_url = voice_service(content, True)
  118. _contents.append(
  119. ChatContent(**{
  120. "content_type": 'voice',
  121. "content": content,
  122. "voice_url": voice_url,
  123. "voice_content": ''
  124. })
  125. )
  126. return _contents, 0, "success"
  127. elif len(contents) == 1 and not contents[0]:
  128. logger.error("话术生成服务异常{}".format(Error.error_nlg.value))
  129. return _contents, Error.error_nlg.value, "话术生成服务异常"
  130. elif len(contents) > 1 and not contents[0]:
  131. logger.error("faq服务异常{}".format(Error.error_faq.value))
  132. return _contents, Error.error_faq.value, "faq服务异常"
  133. return _contents, Error.error_nlg.value, "话术服务异常"
  134. @staticmethod
  135. def get_action(msg: Msg):
  136. action_code = ''
  137. action_content = ''
  138. if msg.action == 'normal':
  139. action_code = msg.action
  140. action_content = '正常通话'
  141. elif msg.action == 'hang':
  142. action_code = msg.action
  143. action_content = '机器人挂断'
  144. elif msg.action == "transfer":
  145. action_code = msg.action
  146. action_content = '转人工'
  147. return ChatAction(action_code, action_content)
  148. @classmethod
  149. def from_msg(cls, msg:Msg):
  150. contents, code, message = cls.get_content(msg)
  151. actions = cls.get_action(msg)
  152. kwargs = {
  153. "node_id": msg.code,
  154. "contents": contents,
  155. # "interruptable": msg.interruptable,
  156. "wait_time": msg.wait_time,
  157. "action": actions,
  158. "inputType": msg.inputType
  159. }
  160. data = ChatMessage(**kwargs)
  161. return cls(
  162. data= data,
  163. message= message,
  164. code = code
  165. )