request_utils.py 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. @Time : 2024/10/17 14:36
  5. @File : request_utils.py.py
  6. @Desc :
  7. """
  8. import re
  9. import os
  10. import shutil
  11. import json
  12. from config import get_logger
  13. import requests
  14. import base64
  15. from database import *
  16. from util import timetic
  17. import uuid
  18. logger = get_logger()
  19. def nlg_service(uid, bid, node_name, choose_speech):
  20. return ''
  21. def get_voice(content, is_local, silence_duration):
  22. # appid = "1226203350"
  23. # access_token = "mMPNJ4WbSVL6NHQKvn4qllYfwv1G4X5w"
  24. # 企业
  25. appid = "8661018433"
  26. access_token ="KkTVKPD9kY-i27Hr9gXtFQ4zqY7nrhJl"
  27. cluster = "volcano_tts"
  28. voice_type = "BV700_V2_streaming"
  29. host = "openspeech.bytedance.com"
  30. api_url = f"https://{host}/api/v1/tts"
  31. header = {"Authorization": f"Bearer;{access_token}"}
  32. #DEFAULT_FILE_UPLOAD_URL = 'http://10.0.0.28:8080/qiniuyun/upLoadImage'
  33. DEFAULT_FILE_UPLOAD_URL = 'http://192.168.9.54:8080/qiniuyun/upLoadImage'
  34. rid = str(uuid.uuid4())
  35. request_json = {
  36. "app": {
  37. "appid": appid,
  38. "token": "access_token",
  39. "cluster": cluster
  40. },
  41. "user": {
  42. "uid": "388808087185088"
  43. },
  44. "audio": {
  45. "voice_type": voice_type,
  46. #"encoding": "mp3",
  47. "encoding": "wav",
  48. "rate": "16000",
  49. "speed_ratio": 0.9,
  50. "volume_ratio": 1.0,
  51. "pitch_ratio": 1.0,
  52. "emotion": "customer_service",
  53. "language": "zh"
  54. },
  55. "request": {
  56. "reqid": rid,
  57. "text": content,
  58. "text_type": "plain",
  59. "operation": "query",
  60. "with_frontend": 1,
  61. "frontend_type": "unitTson",
  62. "silence_duration":silence_duration
  63. }
  64. }
  65. try:
  66. resp = requests.post(api_url, json.dumps(request_json), headers=header)
  67. rfile =f"{rid}.wav"
  68. path, file=f"/root/aibot/dm/voice/{rfile}", f"../voice/{rfile}"
  69. if "data" in resp.json():
  70. data = resp.json()["data"]
  71. file_to_save = open(file, "wb")
  72. file_to_save.write(base64.b64decode(data))
  73. if is_local:
  74. if os.path.exists(file):
  75. logger.info(f"voice local file ::session_id={rid}, res={file}")
  76. return path
  77. else:
  78. files = {'file': open(file, 'rb')}
  79. response = requests.post(DEFAULT_FILE_UPLOAD_URL, files=files)
  80. if response.ok:
  81. result = json.loads(response.text)
  82. url = result.get('data')
  83. if os.path.exists(file):
  84. os.system(f"rm -fr {file}")
  85. logger.info(f"voice upload_plot::session_id={rid}, res={url}")
  86. return url
  87. except Exception as e:
  88. logger.info(f"voice generate 错误{e}")
  89. @timetic
  90. def voice_service(content, local=False, silence_duration="125"):
  91. encode_b = content.encode("utf-8")
  92. key = base64.b64encode(encode_b)
  93. name = "voice_url"
  94. retry,num =1,1
  95. while num <= retry:
  96. try:
  97. url = r.hget(name, key)
  98. #url=''
  99. if url:
  100. logger.info(f"获取voice url成功:{content}")
  101. return url
  102. else:
  103. url = get_voice(content, local, silence_duration)
  104. r.hset(name, key, url)
  105. r.expire(name, 3600 * 24*7)
  106. return url
  107. except Exception as e:
  108. logger.info(f"get voice url {num}缓存错误{e}")
  109. num +=1
  110. @timetic
  111. def intent_service(node_name, asr, bid, code, uid, sessionid):
  112. param = json.dumps(dict(nodeId=code,
  113. userId=uid,
  114. sessionId=sessionid,
  115. taskId=bid,
  116. query=asr,
  117. nodeName = node_name
  118. ), ensure_ascii=False)
  119. try:
  120. ip = "192.168.100.159"
  121. #ip= "10.0.0.24"
  122. res = requests.post(f"http://{ip}:50072/intention",
  123. param.encode("UTF-8"),
  124. headers={'Content-Type': 'application/json;charset=utf-8'},
  125. timeout=8)
  126. content = json.loads(res.text)
  127. logger.info(f"intent service:{content}")
  128. return [content]
  129. except Exception as e:
  130. logger.error(f"intent服务异常:query:{asr},uid:{uid},session:{sessionid}:{e}")
  131. return []
  132. @timetic
  133. def business_service(session_id, uid, code, tools, asr):
  134. def getContent(contents, tools):
  135. if tools in ["water_info", "water_loc_info"]:
  136. mess = '您查询的小区'
  137. neighbourhoodName = [item.get('neighbourhoodName') for item in contents]
  138. reason = [item.get('reason') for item in contents]
  139. timeBegin = ["于"+item.get('timeBegin') + "停水" for item in contents]
  140. timeEnd = [item.get('timeEnd') for item in contents]
  141. conclusions = [f"预计{time}恢复供水" if time is not None else "暂未确定恢复时间" for time in timeEnd]
  142. nums = len(neighbourhoodName)
  143. mess +=";".join([",".join(i) for i in zip(neighbourhoodName, reason, timeBegin, conclusions)])
  144. mess +=",解决轻按1,未解决请按2"
  145. elif tools in ["fee_info", "fee_user_info"]:
  146. mess = "您账户截止"
  147. statisticsTime = [content.get("statisticsTime") for content in contents]
  148. waterFees = [round(float(content.get("waterFees")), 2) for content in contents]
  149. meterAmount = [round(float(content.get("meterAmount")),2) for content in contents]
  150. mess = mess + statisticsTime[0] + "您的抄表表数为"+str(meterAmount[0]) +"欠费金额为" + str(waterFees[0])+ "元。如需详细查询缴费和水量情况可以登陆佳木斯供水公众号,如需人工查询请拨打8247777,解决轻按1, 未解决请按2."
  151. elif tools in ["user_info", "user_phone_info"]:
  152. neighbour, cardNo = [content.get("neighbourhoodName") for content in contents], [content.get("userNo") for content in contents]
  153. nums = len(neighbour)
  154. mess = f"根据您的手机号查询到{nums}个小区," + ";".join(map(lambda x: ",".join(x), zip(neighbour, ["户号是"]* nums, cardNo)))+ "。解决轻按1, 未解决请安2."
  155. else:
  156. mess = ''
  157. return mess
  158. pattern = r'DTMF(.*?)DTMF'
  159. matches = re.findall(pattern, asr, re.DOTALL)
  160. if matches:
  161. asr = re.sub("[()]", "", matches[-1])
  162. else:
  163. asr = asr.split("###")[-1]
  164. asr = asr.strip(r""""$%&'()*+,,-./:;<=>?@[\]^_`{|}~。??!""")
  165. if tools in ["water_loc_info", "fee_user_info", "user_phone_info"] and len(asr)==0:
  166. return [{"title": "NO", "isFaq": False, "faqContent": '', "asr": asr, "businessContent": ''}]
  167. param = json.dumps(dict(nodeId=code,
  168. userId=uid,
  169. sessionId=session_id,
  170. asrText=asr,
  171. method=tools
  172. ), ensure_ascii=False)
  173. try:
  174. # 192.168.40.21
  175. res = requests.post("http://192.168.100.159:8001/bigModel/queryBusinessInfo",
  176. param.encode("UTF-8"),
  177. headers={'Content-Type': 'application/json;charset=utf-8'},
  178. timeout=30)
  179. resp = json.loads(res.text)
  180. logger.info(f"bussiness:{resp}, tools:{tools}, session:{session_id}")
  181. if resp['code'] == "0":
  182. content = resp['data'].get("contents")
  183. title = "NO" if content is None or len(content)==0 else "YES"
  184. businessContent = getContent(content, tools) if title == "YES" else ''
  185. opt = [{"title": title, "isFaq": False, "faqContent": '', "asr": asr, "businessContent": businessContent}]
  186. logger.info(f"code:{code},uid:{uid}, tools:{tools},asr:{asr}, opt:{opt}")
  187. return opt
  188. else:
  189. return [{"title": "NO", "isFaq": False, "faqContent": '', "asr": asr, "businessContent": ''}]
  190. except Exception as e:
  191. logger.info(f"bussion service服务异常:session:{session_id}, tools:{tools},uid:{ uid}:{e}")
  192. return [{"title": "NO", "isFaq": False, "faqContent": '', "asr": asr, "businessContent":''}]
  193. @timetic
  194. def aibot_service(ip ="192.168.100.159",port="40072", nodeId="start", userId='no', sessionId='1', taskId='10001', asrText='是', ext='', recordId=''):
  195. param = json.dumps(dict(nodeId=nodeId,
  196. userId=userId,
  197. sessionId=sessionId,
  198. taskId=taskId,
  199. asrText=asrText,
  200. ext=ext,
  201. recordId=recordId
  202. ), ensure_ascii=False)
  203. try:
  204. res = requests.post(f"http://{ip}:{port}/botservice",
  205. param.encode("UTF-8"),
  206. headers={'Content-Type': 'application/json;charset=utf-8'},
  207. timeout=30)
  208. resp = json.loads(res.text)
  209. if resp['code'] == 0:
  210. content = resp['data']
  211. logger.info(f"aibot: {resp}")
  212. return resp
  213. except Exception as e:
  214. logger.error(f"Ai bot服务异常:{nodeId}, {taskId},{ userId}:{e}")
  215. return
  216. if __name__ == "__main__":
  217. print(voice_service("欢迎致电“佳木斯龙江环保供水服务热线”。我们最新推出智能语音服务,说话就能查询业务, 抢先体验请按1, 传统服务请按2"))
  218. #intent_service("1", "没听清", "2200", "1", "10", "1")
  219. #aibot_service()