acd.py 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #!/usr/bin/env python3
  2. # encoding:utf-8
  3. import time
  4. from datetime import datetime
  5. from queue import Queue
  6. from typing import Dict, Any, Optional
  7. import src.core.callcenter.cache as Cache
  8. from src.core.callcenter.agent import AgentOperService
  9. from src.core.callcenter.call import CallService
  10. from src.core.callcenter.api import CallInfo, AgentActionRequest
  11. from apscheduler.schedulers.background import BackgroundScheduler
  12. from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED, FIRST_COMPLETED
  13. from src.core.callcenter.constant import saasId
  14. class AcdService:
  15. def __init__(self, client, logger):
  16. self.client = client
  17. self.logger = logger
  18. self.call_service = CallService(client, logger)
  19. self.agent_service = AgentOperService(client, logger)
  20. self.holdsQueue: Dict[str, Queue] = {}
  21. self.pool = ThreadPoolExecutor(max_workers=4)
  22. # checkIdleScheduler = BackgroundScheduler()
  23. # checkIdleScheduler.add_job(self.try_transfer_agent, 'interval', seconds=2, max_instances=1)
  24. # checkIdleScheduler.start()
  25. def transfer_to_agent(self, call_info: CallInfo, device_id, service_id):
  26. print('debugger::transfer_to_agent, come in ', end="", flush=True)
  27. # 1. hold住并且播放等待音
  28. self.call_service.hold(call_info, device_id)
  29. print('debugger::transfer_to_agent, 1111111 ', end="", flush=True)
  30. # 获得空闲坐席
  31. agent_number = self.agent_service.assign(AgentActionRequest(saas_id=saasId, service_id=service_id))
  32. print('debugger::transfer_to_agent, 222222 %s'%agent_number, end="", flush=True)
  33. if not agent_number:
  34. # 如果没有空闲坐席,播放等待音
  35. self.logger.info("AcdService transferToAgent agentNumber is empty serviceId:%s,called:%s,callId:%s",
  36. service_id, call_info.called, call_info.call_id)
  37. self.add_acd_queue(call_info, service_id)
  38. else:
  39. # 有空闲坐席,直接转接
  40. self.logger.info("AcdService transferToAgent agentNumber not empty %s, serviceId:%s,called:%s,callId:%s",
  41. agent_number, service_id, call_info.called, call_info.call_id)
  42. self.call_service.transfer(call_info, agent_number, service_id)
  43. def try_transfer_agent(self):
  44. self.logger.info("AcdService tryTransferAgent start")
  45. all_task = []
  46. for k, v in self.holdsQueue.items():
  47. all_task.append(self.pool.submit(self.holds_one_queue, k, v))
  48. wait(all_task, timeout=6, return_when=ALL_COMPLETED)
  49. def add_acd_queue(self, call_info: CallInfo, service_id):
  50. call_info_queue = self.holdsQueue.get(service_id)
  51. if not call_info_queue:
  52. call_info_queue = Queue(maxsize=10)
  53. self.holdsQueue[service_id] = call_info_queue
  54. call_info_queue.put_nowait(call_info.call_id)
  55. def holds_one_queue(self, task_service_id, call_info_queue):
  56. tmp_arr = []
  57. while not call_info_queue.empty():
  58. call_id = call_info_queue.get_nowait()
  59. call_info = Cache.get_call_info(call_id)
  60. if not call_info or not call_info.device_list:
  61. continue
  62. agent_number = self.agent_service.assign(AgentActionRequest(saas_id=saasId, service_id=task_service_id))
  63. if not agent_number:
  64. self.logger.info("AcdService tryTransferAgent agentNumber is Empty %s", call_id)
  65. tmp_arr.append(call_id)
  66. continue
  67. self.logger.info(
  68. "AcdService tryTransferAgent agentNumber not Empty %s, serviceId:%s, called:%s, callId:%s",
  69. agent_number, task_service_id, call_info.called, call_id)
  70. self.call_service.transfer(call_info, agent_number, task_service_id)
  71. for call_id in tmp_arr:
  72. call_info_queue.put_nowait(call_id)