request_utils.py 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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, norm_community
  17. import uuid
  18. SERVE_HOST = os.environ.get("SERVE_HOST", "192.168.100.159")
  19. logger = get_logger()
  20. def nlg_service(uid, bid, node_name, choose_speech):
  21. return ''
  22. def get_voice(content, is_local, silence_duration):
  23. # appid = "1226203350"
  24. # access_token = "mMPNJ4WbSVL6NHQKvn4qllYfwv1G4X5w"
  25. # 企业
  26. appid = "8661018433"
  27. access_token ="KkTVKPD9kY-i27Hr9gXtFQ4zqY7nrhJl"
  28. cluster = "volcano_tts"
  29. voice_type = "BV700_V2_streaming"
  30. host = "openspeech.bytedance.com"
  31. api_url = f"https://{host}/api/v1/tts"
  32. header = {"Authorization": f"Bearer;{access_token}"}
  33. #DEFAULT_FILE_UPLOAD_URL = 'http://10.0.0.28:8080/qiniuyun/upLoadImage'
  34. DEFAULT_FILE_UPLOAD_URL = 'http://192.168.9.54:8080/qiniuyun/upLoadImage'
  35. rid = str(uuid.uuid4())
  36. request_json = {
  37. "app": {
  38. "appid": appid,
  39. "token": "access_token",
  40. "cluster": cluster
  41. },
  42. "user": {
  43. "uid": "388808087185088"
  44. },
  45. "audio": {
  46. "voice_type": voice_type,
  47. #"encoding": "mp3",
  48. "encoding": "wav",
  49. "rate": "16000",
  50. "speed_ratio": 0.9,
  51. "volume_ratio": 1.0,
  52. "pitch_ratio": 1.0,
  53. "emotion": "customer_service",
  54. "language": "zh"
  55. },
  56. "request": {
  57. "reqid": rid,
  58. "text": content,
  59. "text_type": "plain",
  60. "operation": "query",
  61. "with_frontend": 1,
  62. "frontend_type": "unitTson",
  63. "silence_duration":silence_duration
  64. }
  65. }
  66. try:
  67. resp = requests.post(api_url, json.dumps(request_json), headers=header)
  68. rfile =f"{rid}.wav"
  69. path, file=f"/root/aibot/dm/voice/{rfile}", f"../voice/{rfile}"
  70. if "data" in resp.json():
  71. data = resp.json()["data"]
  72. file_to_save = open(file, "wb")
  73. file_to_save.write(base64.b64decode(data))
  74. if is_local:
  75. if os.path.exists(file):
  76. logger.info(f"voice local file ::session_id={rid}, res={file}")
  77. return path
  78. else:
  79. files = {'file': open(file, 'rb')}
  80. response = requests.post(DEFAULT_FILE_UPLOAD_URL, files=files)
  81. if response.ok:
  82. result = json.loads(response.text)
  83. url = result.get('data')
  84. if os.path.exists(file):
  85. os.system(f"rm -fr {file}")
  86. logger.info(f"voice upload_plot::session_id={rid}, res={url}")
  87. return url
  88. except Exception as e:
  89. logger.info(f"voice generate 错误{e}")
  90. @timetic
  91. def voice_service(content, local=False, silence_duration="125"):
  92. encode_b = content.encode("utf-8")
  93. key = base64.b64encode(encode_b)
  94. name = "voice_url"
  95. retry,num =1,1
  96. while num <= retry:
  97. try:
  98. url = r.hget(name, key)
  99. #url=''
  100. if url:
  101. logger.info(f"获取voice url成功:{content}")
  102. return url
  103. else:
  104. url = get_voice(content, local, silence_duration)
  105. r.hset(name, key, url)
  106. r.expire(name, 3600 * 24*7)
  107. return url
  108. except Exception as e:
  109. logger.info(f"get voice url {num}缓存错误{e}")
  110. num +=1
  111. @timetic
  112. def intent_service(node_name, asr, bid, code, uid, sessionid):
  113. param = json.dumps(dict(nodeId=code,
  114. userId=uid,
  115. sessionId=sessionid,
  116. taskId=bid,
  117. query=asr,
  118. nodeName = node_name
  119. ), ensure_ascii=False)
  120. try:
  121. #ip= "10.0.0.24"
  122. res = requests.post(f"http://{SERVE_HOST}: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. # parse water_loc_info
  168. if tools in ["water_loc_info"]:
  169. asr = norm_community(asr)
  170. param = json.dumps(dict(nodeId=code,
  171. userId=uid,
  172. sessionId=session_id,
  173. asrText=asr,
  174. method=tools
  175. ), ensure_ascii=False)
  176. try:
  177. # 192.168.40.21
  178. res = requests.post(f"http://{SERVE_HOST}:8001/bigModel/queryBusinessInfo",
  179. param.encode("UTF-8"),
  180. headers={'Content-Type': 'application/json;charset=utf-8'},
  181. timeout=30)
  182. resp = json.loads(res.text)
  183. logger.info(f"bussiness:{resp}, tools:{tools}, session:{session_id}")
  184. if resp['code'] == "0":
  185. content = resp['data'].get("contents")
  186. title = "NO" if content is None or len(content)==0 else "YES"
  187. businessContent = getContent(content, tools) if title == "YES" else ''
  188. opt = [{"title": title, "isFaq": False, "faqContent": '', "asr": asr, "businessContent": businessContent}]
  189. logger.info(f"code:{code},uid:{uid}, tools:{tools},asr:{asr}, opt:{opt}")
  190. return opt
  191. else:
  192. return [{"title": "NO", "isFaq": False, "faqContent": '', "asr": asr, "businessContent": ''}]
  193. except Exception as e:
  194. logger.info(f"bussion service服务异常:session:{session_id}, tools:{tools},uid:{ uid}:{e}")
  195. return [{"title": "NO", "isFaq": False, "faqContent": '', "asr": asr, "businessContent":''}]
  196. @timetic
  197. def aibot_service(ip ="192.168.100.159",port="40072", nodeId="start", userId='no', sessionId='1', taskId='10001', asrText='是', ext='', recordId=''):
  198. param = json.dumps(dict(nodeId=nodeId,
  199. userId=userId,
  200. sessionId=sessionId,
  201. taskId=taskId,
  202. asrText=asrText,
  203. ext=ext,
  204. recordId=recordId
  205. ), ensure_ascii=False)
  206. try:
  207. res = requests.post(f"http://{ip}:{port}/botservice",
  208. param.encode("UTF-8"),
  209. headers={'Content-Type': 'application/json;charset=utf-8'},
  210. timeout=30)
  211. resp = json.loads(res.text)
  212. if resp['code'] == 0:
  213. content = resp['data']
  214. logger.info(f"aibot: {resp}")
  215. return resp
  216. except Exception as e:
  217. logger.error(f"Ai bot服务异常:{nodeId}, {taskId},{ userId}:{e}")
  218. return
  219. if __name__ == "__main__":
  220. print(voice_service("欢迎致电“佳木斯龙江环保供水服务热线”。我们最新推出智能语音服务,说话就能查询业务, 抢先体验请按1, 传统服务请按2"))
  221. #intent_service("1", "没听清", "2200", "1", "10", "1")
  222. #aibot_service()