model.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. #!/usr/bin/env python3
  2. # encoding:utf-8
  3. import json
  4. from urllib.parse import urlparse
  5. from typing import Dict, Any, Optional
  6. from src.core.callcenter.enumeration import CallType
  7. class MakeCallRequest:
  8. """
  9. 呼叫请求对象
  10. """
  11. def __init__(self, saas_id, call_type: CallType, caller, called, caller_display="", called_display="",
  12. uuid1=None, uuid2=None, follow_data: Dict[str, Any] = {}):
  13. # 租户id
  14. self.saas_id = saas_id
  15. # 呼叫类型
  16. self.call_type: CallType = call_type
  17. # 主叫,如果没有传,则使用坐席号码
  18. self.caller = caller
  19. # 被叫
  20. self.called = called
  21. # 主叫显号,接口没有传就用主技能组配置
  22. self.caller_display = caller_display
  23. # 被叫显号,接口没传就用主技能配置
  24. self.called_display = called_display
  25. # uuid1
  26. self.uuid1 = uuid1
  27. # uuid2
  28. self.uuid2 = uuid2
  29. # 随路数据
  30. self.follow_data = follow_data
  31. def to_json_string(self):
  32. return json.dumps(self.__dict__, ensure_ascii=False)
  33. @classmethod
  34. def from_json(cls, json_string):
  35. data = json.loads(json_string)
  36. return cls(**data)
  37. class AgentRequest:
  38. def __init__(self, saas_id, agent_number, agent_name, out_id, agent_password, agent_type, phone_number, distribute,
  39. agent_state, identity_type):
  40. # 租户隔离
  41. self.saas_id = saas_id
  42. # 坐席工号, 生成返回
  43. self.agent_number = agent_number
  44. # 坐席名称
  45. self.agent_name = agent_name
  46. # 外部展示Id
  47. self.out_id = out_id
  48. # 坐席密码
  49. self.agent_password = agent_password
  50. # 坐席类型 0:普通坐席 ;1:组长:2:主管
  51. self.agent_type = agent_type
  52. # 分机号
  53. self.phone_number = phone_number
  54. # 分配标志 0:不参与排队;1:参与排队
  55. self.distribute = distribute
  56. # 账号状态 0:可用;1:禁用
  57. self.agent_state = agent_state
  58. # 身份状态
  59. self.identity_type = identity_type
  60. class AgentQueryRequest:
  61. def __init__(self, saas_id, agent_number, out_id, agent_type, agent_name):
  62. # 租户隔离
  63. self.saas_id = saas_id
  64. # 坐席工号
  65. self.agent_number = agent_number
  66. # 坐席名称
  67. self.agent_name = agent_name
  68. # 外部展示Id
  69. self.out_id = out_id
  70. # 坐席类型 0:普通坐席 ;1:组长:2:主管
  71. self.agent_type = agent_type
  72. class AgentActionRequest:
  73. """
  74. 坐席操作
  75. """
  76. def __init__(self, saas_id, agent_id, agent_number, out_id, identity_type, scene):
  77. self.saas_id =saas_id
  78. # 坐席工号
  79. self.agent_id = agent_id
  80. # # 坐席工号
  81. self.agent_number = agent_number
  82. # 外部展示Id
  83. self.out_id = out_id,
  84. # 身份状态
  85. self.identity_type = identity_type
  86. # 场景 manual:手动外呼; robot:机器人外呼; monitor:监听
  87. self.scene = scene
  88. def from_json(self, data):
  89. return self(**data)
  90. class AgentMonitor:
  91. def __init__(self, id=None, saas_id=None, agent_num=None, out_id=None,
  92. check_state=1, check_scene=None, check_in_time =None,
  93. check_out_time=None, service_state=0, busy_time=None,
  94. idle_time=None, call_time=None, hang_time=None,
  95. heart_state=None, heart_time=None, session_id = None,
  96. is_delete=0, update_time=None, create_time=None):
  97. self.id = id
  98. # 租户隔离
  99. self.saas_id = saas_id
  100. # 坐席工号
  101. self.agent_num = agent_num
  102. # 使用方id
  103. self.out_id = out_id
  104. # 是否签入 0:是 1: 否 默认未签入
  105. self.check_state = check_state
  106. # 迁入时scene
  107. self.check_scene = check_scene
  108. # 签入时间
  109. self.check_in_time = check_in_time
  110. # 签出时间
  111. self.check_out_time = check_out_time
  112. # 坐席服务状态 0:签出 1:忙碌 2:空闲
  113. self.service_state = service_state
  114. # 置忙时间
  115. self.busy_time = busy_time
  116. # 置闲时间
  117. self.idle_time = idle_time
  118. # 拨通时间
  119. self.call_time = call_time
  120. # 挂断时间
  121. self.hang_time = hang_time
  122. # 心跳状态
  123. self.heart_state = heart_state
  124. # 上次正常心跳时间
  125. self.heart_time = heart_time
  126. #
  127. self.session_id = session_id
  128. # 删除标识
  129. self.is_delete = is_delete
  130. # 更新时间
  131. self.update_time = update_time
  132. # 创建时间
  133. self.create_time = create_time
  134. class HangupCallRequest:
  135. def __init__(self, saas_id, call_id, agent_number):
  136. # saasId(必填)
  137. self.saas_id = saas_id
  138. # 呼叫唯一id(选填)
  139. self.call_id = call_id
  140. # 分机号(必填)
  141. self.agent_number = agent_number
  142. class CheckInCallRequest:
  143. """检查是否在通话中实体"""
  144. def __init__(self, saas_id, agent_number):
  145. self.saas_id = saas_id
  146. self.agent_number = agent_number
  147. class AgentInfo:
  148. def __init__(self, sass_id=None, agent_number=None, realm=None, sip_server=None,
  149. call_id=None, device_id=None, real_device_id=None, line_id=None, fs_user=None, domain=None,
  150. service_time=0, max_ready_time=0, total_ready_time=0, ready_times=0, not_ready_times=0,
  151. total_after_time=0, max_talk_time=0, total_talk_time=0, total_ring_times=0, total_answer_times=0):
  152. self.sass_id = sass_id
  153. self.agent_number = agent_number
  154. self.realm = realm
  155. self.sip_server = sip_server
  156. self.call_id = call_id
  157. self.device_id = device_id
  158. # 机器人外呼时真实fs
  159. self.real_device_id = real_device_id
  160. self.line_id = line_id
  161. self.fs_user = fs_user
  162. self.domain = domain
  163. # 坐席最近的一次服务时间,电话则是振铃时间(秒)
  164. self.service_time = service_time
  165. # 最大空闲时长
  166. self.max_ready_time = max_ready_time
  167. # 累计空闲
  168. self.total_ready_time = total_ready_time
  169. # 空闲次数
  170. self.ready_times = ready_times
  171. # 忙碌次数
  172. self.not_ready_times = not_ready_times
  173. # 累计话后时间长
  174. self.total_after_time = total_after_time
  175. # 最大通话时长
  176. self.max_talk_time = max_talk_time
  177. # 当日累计通话时长
  178. self.total_talk_time = total_talk_time
  179. # 振铃次数
  180. self.total_ring_times = total_ring_times
  181. # 当日累计接听次数
  182. self.total_answer_times = total_answer_times
  183. def get_realm(self):
  184. """
  185. Get the realm by extracting the host from the SIP server if available,
  186. otherwise return the current realm.
  187. """
  188. try:
  189. if self.sip_server:
  190. parsed_uri = urlparse(self.sip_server)
  191. return parsed_uri.hostname if parsed_uri.hostname else self.realm
  192. except Exception as ex:
  193. print(f"Error parsing SIP server URI: {ex}")
  194. return self.realm
  195. def is_fs_user(self):
  196. """
  197. Determine if the agent is a FreeSWITCH user.
  198. Default is True if fs_user is None or True.
  199. """
  200. return self.fs_user is None or self.fs_user is True
  201. def to_json_string(self):
  202. return json.dumps(self.__dict__, ensure_ascii=False)
  203. @classmethod
  204. def from_json(cls, json_string):
  205. data = json.loads(json_string)
  206. return cls(**data)
  207. class CallInfo:
  208. def __init__(self, core_uuid=None, call_id=None, conference=None, saas_id=None, group_id=None,
  209. hidden_customer=0, caller_display=None, caller=None, called_display=None, called=None,
  210. number_location=None, agent_key=None, agent_name=None, login_type=None, ivr_id=None, task_id=None,
  211. media_host=None, cti_host=None, client_host=None, record=None, record2=None, record_time=None,
  212. call_time=None, call_type=None, direction=None, answer_flag=None, wait_time=None, answer_count=0,
  213. hangup_dir=None, sdk_hangup=0, hangup_code=None, answer_time=None, end_time=None, talk_time=None,
  214. frist_queue_time=None, queue_start_time=None, queue_end_time=None, overflow_count=0,
  215. uuid1=None, uuid2=None, cdr_notify_url=None, queue_level=None, device_list=[], device_info_map={},
  216. follow_data={}, process_data={}, next_commands=[], call_details=[]):
  217. self.core_uuid = core_uuid # 通话唯一标识
  218. self.call_id = call_id # 通话唯一标识
  219. self.conference = conference # 会议号
  220. self.saas_id = saas_id # 企业id
  221. self.group_id = group_id # 所在技能组id
  222. self.hidden_customer = hidden_customer # 隐藏客户号码(0:不隐藏;1:隐藏)
  223. self.caller_display = caller_display # 主叫显号
  224. self.caller = caller # 主叫
  225. self.called_display = called_display # 被叫显号
  226. self.called = called # 被叫
  227. self.number_location = number_location # 号码归属地
  228. self.agent_key = agent_key # 坐席
  229. self.agent_name = agent_name # 坐席名称
  230. self.login_type = login_type # 坐席登录类型
  231. self.ivr_id = ivr_id # ivr
  232. self.task_id = task_id # 任务ID
  233. self.media_host = media_host # 媒体
  234. self.cti_host = cti_host # 服务地址
  235. self.client_host = client_host # 客户服务地址
  236. self.record = record # 录音地址
  237. self.record2 = record2 # 第三方存储地址
  238. self.record_time = record_time # 录音开始时间
  239. self.call_time = call_time # 呼叫开始时间
  240. self.call_type = call_type # 呼叫类型 (Enum CallType)
  241. self.direction = direction # 呼叫方向 (Enum Direction)
  242. self.answer_flag = answer_flag # 通话标识
  243. self.wait_time = wait_time # 等待时长
  244. self.answer_count = answer_count # 应答设备数
  245. self.hangup_dir = hangup_dir # 挂机方向 (1主叫挂机, 2:被叫挂机, 3:平台挂机)
  246. self.sdk_hangup = sdk_hangup # sdk挂机标志
  247. self.hangup_code = hangup_code # 挂机原因
  248. self.answer_time = answer_time # 接听时间
  249. self.end_time = end_time # 最后一侧电话挂机时间
  250. self.talk_time = talk_time # 通话时长(秒)
  251. self.frist_queue_time = frist_queue_time # 第一次进队列时间
  252. self.queue_start_time = queue_start_time # 进入技能组时间
  253. self.queue_end_time = queue_end_time # 出技能组时间
  254. self.overflow_count = overflow_count # 溢出次数
  255. self.uuid1 = uuid1 # uuid1
  256. self.uuid2 = uuid2 # uuid2
  257. self.cdr_notify_url = cdr_notify_url # 话单通知地址
  258. self.queue_level = queue_level # 排队等级,默认是进队列时间
  259. self.device_list = device_list # 当前通话的设备
  260. self.device_info_map = device_info_map, # K-V
  261. self.follow_data = follow_data # 呼叫随路数据(作为落单数据)
  262. self.process_data = process_data # 模块流程间数据
  263. self.next_commands = next_commands # 执行下一步命令
  264. self.call_details = call_details # 电话流程
  265. def to_json_string(self):
  266. return json.dumps(self.__dict__, ensure_ascii=False)
  267. @classmethod
  268. def from_json(cls, json_string):
  269. data = json.loads(json_string)
  270. return cls(**data)
  271. # def __repr__(self):
  272. # return (f"CallInfo(core_uuid={self.core_uuid}, call_id={self.call_id}, conference={self.conference}, "
  273. # f"company_id={self.company_id}, group_id={self.group_id}, hidden_customer={self.hidden_customer}, "
  274. # f"caller_display={self.caller_display}, caller={self.caller}, called_display={self.called_display}, "
  275. # f"called={self.called}, number_location={self.number_location}, agent_key={self.agent_key}, "
  276. # f"agent_name={self.agent_name}, login_type={self.login_type}, ivr_id={self.ivr_id}, task_id={self.task_id}, "
  277. # f"media_host={self.media_host}, cti_host={self.cti_host}, client_host={self.client_host}, record={self.record}, "
  278. # f"record2={self.record2}, record_time={self.record_time}, call_time={self.call_time}, call_type={self.call_type}, "
  279. # f"direction={self.direction}, answer_flag={self.answer_flag}, wait_time={self.wait_time}, "
  280. # f"answer_count={self.answer_count}, hangup_dir={self.hangup_dir}, sdk_hangup={self.sdk_hangup}, "
  281. # f"hangup_code={self.hangup_code}, answer_time={self.answer_time}, end_time={self.end_time}, "
  282. # f"talk_time={self.talk_time}, frist_queue_time={self.frist_queue_time}, queue_start_time={self.queue_start_time}, "
  283. # f"queue_end_time={self.queue_end_time}, overflow_count={self.overflow_count}, uuid1={self.uuid1}, uuid2={self.uuid2}, "
  284. # f"cdr_notify_url={self.cdr_notify_url}, queue_level={self.queue_level})")
  285. class DeviceInfo:
  286. def __init__(self, call_id=None, conference=None, device_id=None, agent_key=None, agent_name=None, device_type=None,
  287. cdr_type=None, from_agent=None, caller=None, called=None, display=None, called_location=None,
  288. caller_location=None, call_time=None, ring_start_time=None, ring_end_time=None, answer_time=None,
  289. bridge_time=None, end_time=None, talk_time=None, sip_protocol=None, channel_name=None,
  290. hangup_cause=None, ring_cause=None, sip_status=None, record=None, record_time=None,
  291. record_start_time=None, state=None):
  292. self.call_id = call_id # 通话唯一标识
  293. self.conference = conference # 会议模式
  294. self.device_id = device_id # 设备id
  295. self.agent_key = agent_key # 坐席
  296. self.agent_name = agent_name # 坐席
  297. self.device_type = device_type # 1:坐席,2:客户,3:外线
  298. self.cdr_type = cdr_type # 1:呼入,2:外呼,3:内呼,4:转接,5:咨询,6:监听,7:强插,8:耳语
  299. self.from_agent = from_agent # 咨询或转接来源
  300. self.caller = caller # 主叫
  301. self.called = called # 被叫
  302. self.display = display # 显号
  303. self.called_location = called_location # 被叫归属地
  304. self.caller_location = caller_location # 被叫归属地
  305. self.call_time = call_time # 呼叫开始时间
  306. self.ring_start_time = ring_start_time # 振铃开始时间
  307. self.ring_end_time = ring_end_time # 振铃结束时间
  308. self.answer_time = answer_time # 接通时间
  309. self.bridge_time = bridge_time # 桥接时间
  310. self.end_time = end_time # 结束时间
  311. self.talk_time = talk_time # 通话时长
  312. self.sip_protocol = sip_protocol # 信令协议(tcp/udp)
  313. self.channel_name = channel_name # 呼叫地址
  314. self.hangup_cause = hangup_cause # 挂机原因
  315. self.ring_cause = ring_cause # 回铃音识别
  316. self.sip_status = sip_status # sip状态
  317. self.record = record # 录音地址
  318. self.record_time = record_time # 录音时长
  319. self.record_start_time = record_start_time # 录音开始时间
  320. self.state = state # 当前设备状态
  321. def to_json_string(self):
  322. return json.dumps(self.__dict__, ensure_ascii=False)
  323. @classmethod
  324. def from_json(cls, json_string):
  325. data = json.loads(json_string)
  326. return cls(**data)
  327. # def __repr__(self):
  328. # return (f"DeviceInfo(call_id={self.call_id}, conference={self.conference}, device_id={self.device_id}, "
  329. # f"agent_key={self.agent_key}, agent_name={self.agent_name}, device_type={self.device_type}, "
  330. # f"cdr_type={self.cdr_type}, from_agent={self.from_agent}, caller={self.caller}, called={self.called}, "
  331. # f"display={self.display}, called_location={self.called_location}, caller_location={self.caller_location}, "
  332. # f"call_time={self.call_time}, ring_start_time={self.ring_start_time}, ring_end_time={self.ring_end_time}, "
  333. # f"answer_time={self.answer_time}, bridge_time={self.bridge_time}, end_time={self.end_time}, "
  334. # f"talk_time={self.talk_time}, sip_protocol={self.sip_protocol}, channel_name={self.channel_name}, "
  335. # f"hangup_cause={self.hangup_cause}, ring_cause={self.ring_cause}, sip_status={self.sip_status}, "
  336. # f"record={self.record}, record_time={self.record_time}, record_start_time={self.record_start_time}, "
  337. # f"state={self.state})")
  338. class NextCommand:
  339. def __init__(self, device_id, next_type, next_value):
  340. # 记录执行设备
  341. self.device_id = device_id
  342. # 下一步执行命令
  343. self.next_type = next_type
  344. # 执行参数
  345. self.next_value = next_value
  346. def to_json_string(self):
  347. return json.dumps(self.__dict__, ensure_ascii=False)
  348. @classmethod
  349. def from_json(cls, json_string):
  350. data = json.loads(json_string)
  351. return cls(**data)
  352. class CallDetail:
  353. def __init__(self, id=None, cts=None, start_time=None, end_time=None, call_id=None,
  354. detail_index=None, transfer_type=None, transfer_id=None, reason=None,
  355. month=None, ext1=None, ext2=None, status=None):
  356. self.id = id # PK
  357. self.cts = cts # 创建时间
  358. self.start_time = start_time # 开始时间
  359. self.end_time = end_time # 结束时间
  360. self.call_id = call_id # 通话ID
  361. self.detail_index = detail_index # 顺序
  362. self.transfer_type = transfer_type # 类型
  363. self.transfer_id = transfer_id # 转接ID
  364. self.reason = reason # 出队列原因
  365. self.month = month # 月份
  366. self.ext1 = ext1 # 扩展字段1
  367. self.ext2 = ext2 # 扩展字段2
  368. self.status = status # 状态
  369. def to_json_string(self):
  370. return json.dumps(self.__dict__, ensure_ascii=False)
  371. @classmethod
  372. def from_json(cls, json_string):
  373. data = json.loads(json_string)
  374. return cls(**data)
  375. # def __repr__(self):
  376. # return (f"CallDetail(id={self.id}, cts={self.cts}, start_time={self.start_time}, "
  377. # f"end_time={self.end_time}, call_id={self.call_id}, detail_index={self.detail_index}, "
  378. # f"transfer_type={self.transfer_type}, transfer_id={self.transfer_id}, reason={self.reason}, "
  379. # f"month={self.month}, ext1={self.ext1}, ext2={self.ext2}, status={self.status})")
  380. class RouteGateway:
  381. def __init__(self, id=None, saas_id=None, cts=None, uts=None, name=None, media_host=None,
  382. media_port=None, caller_prefix=None, called_prefix=None,
  383. profile='gateway/gateway-fxo', sip_header1='P-LIBRA-CallId=#{[callId]}',
  384. sip_header2='P-LIBRA-deviceId=#{[deviceId]}', sip_header3=None, status=None):
  385. self.id = id # PK
  386. self.saas_id = saas_id
  387. self.cts = cts # 创建时间
  388. self.uts = uts # 修改时间
  389. self.name = name # 号码
  390. self.media_host = media_host # 媒体地址
  391. self.media_port = media_port # 媒体端口
  392. self.caller_prefix = caller_prefix # 主叫号码前缀
  393. self.called_prefix = called_prefix # 被叫号码前缀
  394. self.profile = profile # 媒体拨号计划文件
  395. self.sip_header1 = sip_header1 # SIP头1
  396. self.sip_header2 = sip_header2 # SIP头2
  397. self.sip_header3 = sip_header3 # SIP头3
  398. self.status = status # 状态
  399. def to_json_string(self):
  400. return json.dumps(self.__dict__, ensure_ascii=False)
  401. @classmethod
  402. def from_json(cls, json_string):
  403. data = json.loads(json_string)
  404. return cls(**data)
  405. # def __repr__(self):
  406. # return (f"RouteGateway(id={self.id}, cts={self.cts}, uts={self.uts}, name={self.name}, "
  407. # f"media_host={self.media_host}, media_port={self.media_port}, caller_prefix={self.caller_prefix}, "
  408. # f"called_prefix={self.called_prefix}, profile={self.profile}, "
  409. # f"sip_header1={self.sip_header1}, sip_header2={self.sip_header2}, "
  410. # f"sip_header3={self.sip_header3}, status={self.status})")
  411. #机器人外呼
  412. class BotChatRequest:
  413. def __init__(self, node_id=None, user_id=None, session_id=None, record_id=None,
  414. task_id=None, asr_text=None, key_input=None, ext:Dict={}):
  415. self.node_id = node_id # 节点id
  416. self.user_id = user_id # 用户id
  417. self.session_id = session_id # 会话id
  418. self.record_id = record_id # 唯一标识
  419. self.task_id = task_id # 机器人任务id
  420. self.event_type = None # 1:电话接通,2:用户语音asr结果上传,3:用户按键输入,4:用户挂断电话,5:读取外呼结果(可在外呼过程中调用,不一定在结束之后),6:用户不说话超时,7:TTS或录音文件播放完毕或被打断,8:ASR错误导致挂断电话,9:TTS错误导致挂断电话,10:其它系统错误导致挂断电话
  421. self.asr_text = asr_text # asr识别的文本
  422. self.ext = ext
  423. def to_json_string(self):
  424. return json.dumps(self.__dict__, ensure_ascii=False)
  425. @classmethod
  426. def from_json(cls, json_string):
  427. data = json.loads(json_string)
  428. return cls(**data)
  429. # def __repr__(self):
  430. # return (f"OutboundRobotRequestParams(node_id={self.node_id}, user_id={self.user_id}, "
  431. # f"session_id={self.session_id}, record_id={self.record_id}, task_id={self.task_id}, "
  432. # f"event_type={self.event_type}, asr_text={self.asr_text}, key_input={self.key_input})")
  433. class ChatAction:
  434. def __init__(self, action_code=None, action_content=None):
  435. self.action_code = action_code # normal:正常通话;hang:挂断;transfer:转人工
  436. self.action_content = action_content # 动作内容
  437. def to_json_string(self):
  438. return json.dumps(self.__dict__, ensure_ascii=False)
  439. @classmethod
  440. def from_json(cls, json_data):
  441. return cls(
  442. action_code=json_data.get("action_code"),
  443. action_content=json_data.get("action_content")
  444. )
  445. class ChatContent:
  446. def __init__(self, content_type=None, content=None, voice_url=None, voice_content=None):
  447. self.content_type = content_type # 播放类型
  448. self.content = content # 播放内容
  449. self.voice_url = voice_url # 语音地址
  450. self.voice_content = voice_content # 语音文本
  451. def to_json_string(self):
  452. return json.dumps(self.__dict__, ensure_ascii=False)
  453. @classmethod
  454. def from_json(cls, json_data):
  455. return cls(
  456. content_type=json_data.get("content_type"),
  457. content=json_data.get("content"),
  458. voice_url=json_data.get("voice_url"),
  459. voice_content=json_data.get("voice_content")
  460. )
  461. class ChatMessage:
  462. def __init__(self, node_id=None, contents=None, interruptable=None, wait_time=None,
  463. action=None, talk_time_out=None,dtmf_type=None):
  464. self.node_id = node_id # 节点id
  465. self.contents = contents if contents is not None else [] # 内容列表
  466. self.interruptable = interruptable # 是否可打断
  467. self.wait_time = wait_time # 用户静默时长
  468. self.action = action # 动作代码
  469. self.talk_time_out = talk_time_out # 用户通话时长
  470. self.dtmf_type = dtmf_type # dtmf类型
  471. def to_json_string(self):
  472. return json.dumps({
  473. "node_id": self.node_id,
  474. "contents": [content.__dict__ for content in self.contents],
  475. "interruptable": self.interruptable,
  476. "wait_time": self.wait_time,
  477. "action": self.action.__dict__ if self.action else None,
  478. "talk_time_out": self.talk_time_out,
  479. "dtmf_type": self.dtmf_type
  480. }, ensure_ascii=False)
  481. @classmethod
  482. def from_json(cls, json_data):
  483. contents = [ChatContent.from_json(item) for item in json_data.get("contents", [])]
  484. action = ChatAction.from_json(json_data.get("action", {})) if json_data.get("action") else None
  485. return cls(
  486. node_id=json_data.get("node_id"),
  487. contents=contents,
  488. interruptable=json_data.get("interruptable"),
  489. wait_time=json_data.get("wait_time"),
  490. action=action,
  491. talk_time_out=json_data.get("talk_time_out"),
  492. dtmf_type=json_data.get("dtmf_type")
  493. )
  494. class ChatResponse:
  495. def __init__(self, data=None, message=None, code=None):
  496. self.data = data if data is not None else ChatMessage()
  497. self.message = message
  498. self.code = code
  499. def to_json_string(self):
  500. return json.dumps({
  501. "data": json.loads(self.data.to_json_string()),
  502. "message": self.message,
  503. "code": self.code
  504. }, ensure_ascii=False)
  505. @classmethod
  506. def from_json(cls, json_string):
  507. data = json.loads(json_string)
  508. response_data = ChatMessage.from_json(data.get("data", {}))
  509. return cls(
  510. data=response_data,
  511. message=data.get("message"),
  512. code=data.get("code")
  513. )