DeviceManager.cs 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027
  1. using Hotline.CallCenter.Calls;
  2. using Hotline.CallCenter.Devices;
  3. using Hotline.CallCenter.Tels;
  4. using MapsterMapper;
  5. using Microsoft.Extensions.Options;
  6. using NewRock.Sdk;
  7. using NewRock.Sdk.Accept.Request;
  8. using NewRock.Sdk.Control.Request;
  9. using NewRock.Sdk.Control.Request.Base;
  10. using NewRock.Sdk.Manage.Request;
  11. using NewRock.Sdk.Transfer.Conference.Request;
  12. using NewRock.Sdk.Transfer.Connect.Request;
  13. using NewRock.Sdk.Transfer.Queue.Request;
  14. using NewRock.Sdk.Control.Response;
  15. using System.Text.RegularExpressions;
  16. using XF.Domain.Dependency;
  17. using XF.Domain.Exceptions;
  18. using Group = NewRock.Sdk.Control.Request.Group;
  19. using Hotline.Share.Dtos.CallCenter;
  20. using Hotline.Share.Enums.CallCenter;
  21. using Hotline.Caching.Interfaces;
  22. namespace Hotline.NewRock
  23. {
  24. public class DeviceManager : IDeviceManager, IScopeDependency
  25. {
  26. private readonly INewRockClient _newRockClient;
  27. private readonly ICallRepository _callRepository;
  28. private readonly IOptionsSnapshot<CallCenterConfiguration> _options;
  29. private readonly IMapper _mapper;
  30. private readonly ITelGroupRepository _telGroupRepository;
  31. private readonly IUserCacheManager _userCacheManager;
  32. private readonly ITelRestRepository _telRestRepository;
  33. private readonly ITelCacheManager _telCacheManager;
  34. public DeviceManager(INewRockClient newRockClient, IOptionsSnapshot<CallCenterConfiguration> options, IMapper mapper, ICallRepository callRepository, ITelGroupRepository telGroupRepository,IUserCacheManager userCacheManager, ITelRestRepository telRestRepository, ITelCacheManager telCacheManager)
  35. {
  36. _newRockClient = newRockClient;
  37. _options = options;
  38. _mapper = mapper;
  39. _callRepository = callRepository;
  40. _telGroupRepository = telGroupRepository;
  41. _userCacheManager = userCacheManager;
  42. _telRestRepository = telRestRepository;
  43. _telCacheManager = telCacheManager;
  44. }
  45. #region 查询
  46. public async Task<TelDto> QueryTelAsync(string TelNo, CancellationToken cancellationToken)
  47. {
  48. try
  49. {
  50. var result = await _newRockClient.QueryExt(
  51. new QueryExtRequest() { Attribute = "Query", Ext = new Ext { Id = TelNo } },
  52. _options.Value.DeviceConfigs.ReceiveKey, _options.Value.DeviceConfigs.Expired, cancellationToken);
  53. if (result?.Ext.Outer != null)
  54. {
  55. var telDto = new TelDto();
  56. telDto.CPN = result.Ext.Outer.From;
  57. telDto.CDPN = result.Ext.Outer.To;
  58. telDto.TelStatusInfo = ETelStatusInfo.Out;
  59. telDto.ConversationId = result.Ext.Outer.Id;
  60. if (result.Ext.Outer.State == "talk")
  61. {
  62. telDto.TelStatus = Share.Enums.CallCenter.ETelStatus.Talk;
  63. return telDto;
  64. }
  65. else if (result.Ext.Outer.State == "wait")
  66. {
  67. telDto.TelStatus = Share.Enums.CallCenter.ETelStatus.Wait;
  68. }
  69. return telDto;
  70. }
  71. if (result?.Ext.Visitor != null)
  72. {
  73. var telDto = new TelDto();
  74. telDto.CPN = result.Ext.Visitor.From;
  75. telDto.CDPN = result.Ext.Visitor.To;
  76. telDto.TelStatusInfo = ETelStatusInfo.Into;
  77. telDto.ConversationId = result.Ext.Visitor.Id;
  78. if (result.Ext.Visitor.State == "talk")
  79. {
  80. telDto.TelStatus = Share.Enums.CallCenter.ETelStatus.Talk;
  81. return telDto;
  82. }
  83. else if (result.Ext.Visitor.State == "wait")
  84. {
  85. telDto.TelStatus = Share.Enums.CallCenter.ETelStatus.Wait;
  86. }
  87. return telDto;
  88. }
  89. if (result?.Ext.Ext != null)
  90. {
  91. var telDto = new TelDto();
  92. telDto.CPN = result.Ext.Ext.Id;
  93. telDto.CDPN = result.Ext.Id;
  94. telDto.TelStatusInfo = ETelStatusInfo.Ext;
  95. if (result.Ext.Ext.State == "talk")
  96. {
  97. telDto.TelStatus = Share.Enums.CallCenter.ETelStatus.Talk;
  98. return telDto;
  99. }
  100. else if (result.Ext.Ext.State == "wait")
  101. {
  102. telDto.TelStatus = Share.Enums.CallCenter.ETelStatus.Wait;
  103. }
  104. return telDto;
  105. }
  106. return null;
  107. }
  108. catch
  109. {
  110. return null;
  111. }
  112. }
  113. /// <summary>
  114. /// 查询分机状态
  115. /// </summary>
  116. /// <param name="TelNo"></param>
  117. /// <param name="cancellationToken"></param>
  118. /// <returns></returns>
  119. public async Task<ETelStatus> QueryTelState(string TelNo, CancellationToken cancellationToken)
  120. {
  121. var result = await _newRockClient.QueryExt(
  122. new QueryExtRequest() { Attribute = "Query", Ext = new Ext { Id = TelNo } },
  123. _options.Value.DeviceConfigs.ReceiveKey, _options.Value.DeviceConfigs.Expired, cancellationToken);
  124. switch (result.Ext.State)
  125. {
  126. case "ready":
  127. return ETelStatus.Ready;
  128. case "active":
  129. return ETelStatus.Active;
  130. case "progress":
  131. return ETelStatus.Progress;
  132. case "offline":
  133. return ETelStatus.Offline;
  134. case "offhook":
  135. return ETelStatus.Offhook;
  136. default:
  137. break;
  138. }
  139. return ETelStatus.Offline;
  140. }
  141. /// <summary>
  142. /// 查询所有分机
  143. /// </summary>
  144. /// <param name="cancellationToken"></param>
  145. /// <returns></returns>
  146. public async Task<List<Tel>> QueryTelsAsync(CancellationToken cancellationToken)
  147. {
  148. var result = await _newRockClient.QueryDeviceInfo(
  149. new QueryDeviceInfoRequest { Attribute = "Query", DeviceInfo = string.Empty },
  150. _options.Value.DeviceConfigs.ReceiveKey,
  151. _options.Value.DeviceConfigs.Expired,
  152. cancellationToken);
  153. var exts = result.Devices.Ext;
  154. return _mapper.Map<List<Tel>>(exts);
  155. }
  156. /// <summary>
  157. /// 查询所有分机组
  158. /// </summary>
  159. /// <param name="cancellationToken"></param>
  160. /// <returns></returns>
  161. public async Task<List<TelGroup>> QueryTelGroupsAsync(CancellationToken cancellationToken)
  162. {
  163. var result = await _newRockClient.QueryDeviceInfo(
  164. new QueryDeviceInfoRequest { Attribute = "Query", DeviceInfo = string.Empty },
  165. _options.Value.DeviceConfigs.ReceiveKey,
  166. _options.Value.DeviceConfigs.Expired,
  167. cancellationToken);
  168. var groups = result.Devices.Group;
  169. return _mapper.Map<List<TelGroup>>(groups);
  170. }
  171. /// <summary>
  172. /// 查询语音文件
  173. /// </summary>
  174. /// <param name="cancellationToken"></param>
  175. /// <returns></returns>
  176. public async Task<string> VoiceQueryListAsync(CancellationToken cancellationToken)
  177. {
  178. var result = await _newRockClient.VoiceQueryList(new VoiceQueryListRequest()
  179. {
  180. Attribute = "Query",
  181. VoiceFile = "",
  182. }, _options.Value.DeviceConfigs.ReceiveKey,
  183. _options.Value.DeviceConfigs.Expired,
  184. cancellationToken);
  185. return result?.VoiceFile;
  186. }
  187. public async Task QueryGroupAsync(string groupId, CancellationToken cancellationToken)
  188. {
  189. await _newRockClient.QueryExtGroup(new QueryExtGroupRequest()
  190. { Attribute = "Query", Group = new QueryExtGroup() { Id = groupId } },
  191. _options.Value.DeviceConfigs.ReceiveKey,
  192. _options.Value.DeviceConfigs.Expired,
  193. cancellationToken
  194. );
  195. }
  196. #endregion
  197. #region 配置
  198. /// <summary>
  199. /// 分机休息
  200. /// </summary>
  201. /// <param name="telNo">分机号</param>
  202. /// <param name="cancellationToken"></param>
  203. /// <returns></returns>
  204. public async Task TelRestAsync(string telNo, CancellationToken cancellationToken)
  205. {
  206. var telModel = await _newRockClient.QueryExt(new QueryExtRequest()
  207. {
  208. Attribute = "Query",
  209. Ext = new Ext() { Id = telNo }
  210. }, _options.Value.DeviceConfigs.ReceiveKey,
  211. _options.Value.DeviceConfigs.Expired,
  212. cancellationToken);
  213. if (telModel == null)
  214. throw new UserFriendlyException("未知分机");
  215. await _newRockClient.ConfigExt(
  216. new AssginConfigExtRequest() { Attribute = "Assign", Ext = new ConfigExt() { Lineid = telModel.Ext.LineId, Groups=Enumerable.Select<QueryExtGroup, string>(telModel.Ext.Group, x=>x.Id).ToList(), No_Disturb = "On" } },
  217. _options.Value.DeviceConfigs.ReceiveKey,
  218. _options.Value.DeviceConfigs.Expired,
  219. cancellationToken);
  220. }
  221. /// <summary>
  222. /// 分机结束休息
  223. /// </summary>
  224. /// <param name="telNo">分机号</param>
  225. /// <param name="cancellationToken"></param>
  226. /// <returns></returns>
  227. public async Task TelEndRestAsync(string telNo, CancellationToken cancellationToken)
  228. {
  229. var telModel = await _newRockClient.QueryExt(new QueryExtRequest()
  230. {
  231. Attribute = "Query",
  232. Ext = new Ext() { Id = telNo }
  233. }, _options.Value.DeviceConfigs.ReceiveKey,
  234. _options.Value.DeviceConfigs.Expired,
  235. cancellationToken);
  236. if (telModel == null)
  237. throw new UserFriendlyException("未知分机");
  238. await _newRockClient.ConfigExt(
  239. new AssginConfigExtRequest() { Attribute = "Assign", Ext = new ConfigExt() { Lineid = telModel.Ext.LineId, Groups = Enumerable.Select<QueryExtGroup, string>(telModel.Ext.Group, x => x.Id).ToList(), No_Disturb = "Off" } },
  240. _options.Value.DeviceConfigs.ReceiveKey,
  241. _options.Value.DeviceConfigs.Expired,
  242. cancellationToken);
  243. }
  244. /// <summary>
  245. /// 删除语音文件
  246. /// </summary>
  247. /// <param name="voiceName"></param>
  248. /// <param name="cancellationToken"></param>
  249. /// <returns></returns>
  250. public async Task RemoveVoiceFileAsync(string voiceName, CancellationToken cancellationToken)
  251. {
  252. await _newRockClient.RemoveVoiceFile(new RemoveVoiceFileRequest()
  253. {
  254. Attribute = "Remove",
  255. VoiceFile = voiceName
  256. }, _options.Value.DeviceConfigs.ReceiveKey,
  257. _options.Value.DeviceConfigs.Expired,
  258. cancellationToken);
  259. }
  260. /// <summary>
  261. /// 配置语音菜单
  262. /// </summary>
  263. /// <param name="menuId"></param>
  264. /// <param name="voiceFile"></param>
  265. /// <param name="repeat"></param>
  266. /// <param name="infoLength"></param>
  267. /// <param name="exit"></param>
  268. /// <param name="cancellationToken"></param>
  269. /// <returns></returns>
  270. public async Task AssginConfigMenuAsync(string menuId, string voiceFile, string repeat, string infoLength,
  271. string exit,
  272. CancellationToken cancellationToken)
  273. {
  274. if (!int.TryParse(menuId, out int mId))
  275. throw new UserFriendlyException("请输入数字");
  276. if (mId < 1 || mId > 50)
  277. throw new UserFriendlyException("菜单只允许在1-50范围内");
  278. if (exit!="")
  279. {
  280. Regex r = new Regex(@"^[a-d]|[A-D]|[1-9]|[*]|[#]$");
  281. if (!r.IsMatch(exit))
  282. throw new UserFriendlyException("输入指令不合法,合法值:A-D、1-9、*、#");
  283. }
  284. var resp = await _newRockClient.ConfigMenu(new AssginConfigMenuRequest()
  285. {
  286. Attribute = "Assign",
  287. Menu = new AssginConfigMenuMenu()
  288. {
  289. Id = menuId,
  290. VoiceFile = voiceFile,
  291. InfoLength = infoLength,
  292. Exit = exit,
  293. Repeat = repeat,
  294. }
  295. }, _options.Value.DeviceConfigs.ReceiveKey,
  296. _options.Value.DeviceConfigs.Expired,
  297. cancellationToken);
  298. }
  299. /// <summary>
  300. /// 配置分机组
  301. /// </summary>
  302. /// <param name="groupId"></param>
  303. /// <param name="voiceFile"></param>
  304. /// <param name="distribution"></param>
  305. /// <param name="ext"></param>
  306. /// <param name="cancellationToken"></param>
  307. /// <returns></returns>
  308. public async Task AssginConfigGroupAsync(string groupId, EDistribution distribution, List<string> ext, string? voiceFile = "",CancellationToken cancellationToken=default)
  309. {
  310. if (!int.TryParse(groupId, out int mId))
  311. throw new UserFriendlyException("请输入数字");
  312. if (mId < 1 || mId > 50)
  313. throw new UserFriendlyException("分机组只允许在1-50范围内");
  314. var groupModel = new Group()
  315. {
  316. Id = groupId,
  317. Ext = ext,
  318. };
  319. switch (distribution)
  320. {
  321. case EDistribution.Sequential:
  322. groupModel.Distribution = "sequential";
  323. break;
  324. case EDistribution.Group:
  325. groupModel.Distribution = "group";
  326. break;
  327. case EDistribution.Circular:
  328. groupModel.Distribution = "circular";
  329. break;
  330. default:
  331. break;
  332. }
  333. if (!string.IsNullOrEmpty(voiceFile))
  334. groupModel.Voicefile = voiceFile;
  335. var resp = await _newRockClient.ConfigExtGroup(new AssginConfigGroupRequest()
  336. {
  337. Attribute = "Assign",
  338. Group = groupModel
  339. }, _options.Value.DeviceConfigs.ReceiveKey,
  340. _options.Value.DeviceConfigs.Expired,
  341. cancellationToken);
  342. }
  343. /// <summary>
  344. /// 更新分机组
  345. /// </summary>
  346. /// <param name="groupId"></param>
  347. /// <param name="ext"></param>
  348. /// <param name="cancellationToken"></param>
  349. /// <param name="isAdd"></param>
  350. /// <returns></returns>
  351. public async Task ModifyGroupExtAsync(string groupId, EDistribution distribution, string voicefile = "", string extId = "", bool isAdd = true, CancellationToken cancellationToken = default)
  352. {
  353. if (!int.TryParse(groupId, out int mId))
  354. throw new UserFriendlyException("请输入数字");
  355. if (mId < 1 || mId > 50)
  356. throw new UserFriendlyException("分机组只允许在1-50范围内");
  357. #region 清除分机组设置
  358. await _newRockClient.ConfigExtGroup(new AssginConfigGroupRequest() { Attribute = "Assign", Group = new Group() { Id = groupId } }, _options.Value.DeviceConfigs.ReceiveKey, _options.Value.DeviceConfigs.Expired, cancellationToken);
  359. #endregion
  360. var list = await _telGroupRepository.QueryExtAsync(d => d.No == groupId, d => d.Includes(x => x.Tels));
  361. //检查是否上班
  362. List<string> exts = new List<string>();
  363. foreach (var ext in list[0].Tels)
  364. {
  365. var iswork = await _userCacheManager.IsWorkingByTelAsync(ext.No, cancellationToken);
  366. if (iswork)
  367. {
  368. var tel = _telCacheManager.GetTel(ext.No);
  369. if (tel.TelStatus == ETelStatus.Ready)
  370. {
  371. exts.Add(ext.No);
  372. }
  373. }
  374. }
  375. //查询所有正在休息的分机
  376. List<string> restexts = (await _telRestRepository.QueryAsync(x => x.EndTime == null)).Select(x => x.TelNo).ToList();
  377. if (restexts != null && restexts.Count > 0)
  378. {
  379. foreach (var item in restexts)
  380. {
  381. exts.Remove(item);
  382. }
  383. }
  384. //更新
  385. var groupModel = new Group()
  386. {
  387. Id = groupId,
  388. Voicefile = voicefile
  389. };
  390. switch (distribution)
  391. {
  392. case EDistribution.Sequential:
  393. groupModel.Distribution = "sequential";
  394. break;
  395. case EDistribution.Group:
  396. groupModel.Distribution = "group";
  397. break;
  398. case EDistribution.Circular:
  399. groupModel.Distribution = "circular";
  400. break;
  401. default:
  402. break;
  403. }
  404. groupModel.Ext = exts;
  405. await _newRockClient.ConfigExtGroup(
  406. new AssginConfigGroupRequest() { Attribute = "Assign", Group = groupModel, },
  407. _options.Value.DeviceConfigs.ReceiveKey,
  408. _options.Value.DeviceConfigs.Expired,
  409. cancellationToken
  410. );
  411. }
  412. /// <summary>
  413. /// 上班/下班
  414. /// </summary>
  415. /// <param name="telNo"></param>
  416. /// <param name="staffNo"></param>
  417. /// <param name="cancellationToken"></param>
  418. /// <returns></returns>
  419. public async Task UpdateStaffNoAsync(string telNo, string staffNo,string lineId, CancellationToken cancellationToken)
  420. {
  421. var telModel = await _newRockClient.QueryExt(new QueryExtRequest()
  422. {
  423. Attribute = "Query",
  424. Ext = new Ext() { Id = telNo }
  425. }, _options.Value.DeviceConfigs.ReceiveKey,
  426. _options.Value.DeviceConfigs.Expired,
  427. cancellationToken);
  428. if (telModel == null)
  429. throw new UserFriendlyException("未知分机");
  430. await _newRockClient.ConfigExt(
  431. new AssginConfigExtRequest() { Attribute = "Assign", Ext = new ConfigExt() { Id = telNo,Lineid = lineId, Staffid = staffNo } },
  432. _options.Value.DeviceConfigs.ReceiveKey,
  433. _options.Value.DeviceConfigs.Expired,
  434. cancellationToken);
  435. }
  436. #endregion
  437. #region 通话控制
  438. /// <summary>
  439. /// 保持通话
  440. /// </summary>
  441. /// <param name="telNo">分机号</param>
  442. /// <param name="cancellationToken"></param>
  443. /// <returns></returns>
  444. public async Task HoldAsync(string telNo, CancellationToken cancellationToken)
  445. {
  446. await _newRockClient.HoldOrUnHold(
  447. new HoldSetRequest() { Attribute = "Hold", Ext = new Ext() { Id = telNo } }, _options.Value.DeviceConfigs.ReceiveKey,
  448. _options.Value.DeviceConfigs.Expired,
  449. cancellationToken);
  450. }
  451. /// <summary>
  452. /// 恢复通话(解除hold状态)
  453. /// </summary>
  454. /// <param name="telNo">分机号</param>
  455. /// <param name="cancellationToken"></param>
  456. /// <returns></returns>
  457. public async Task UnHoldAsync(string telNo, CancellationToken cancellationToken)
  458. {
  459. await _newRockClient.HoldOrUnHold(
  460. new HoldSetRequest() { Attribute = "Unhold", Ext = new Ext() { Id = telNo } }, _options.Value.DeviceConfigs.ReceiveKey,
  461. _options.Value.DeviceConfigs.Expired,
  462. cancellationToken);
  463. }
  464. /// <summary>
  465. /// 静音开启
  466. /// </summary>
  467. /// <param name="telNo">分机号</param>
  468. /// <param name="cancellationToken"></param>
  469. /// <returns></returns>
  470. public async Task MuteAsync(string telNo, CancellationToken cancellationToken)
  471. {
  472. await _newRockClient.MuteOrUnMute(
  473. new MuteSetRequest() { Attribute = "Mute", Ext = new Ext() { Id = telNo } }, _options.Value.DeviceConfigs.ReceiveKey,
  474. _options.Value.DeviceConfigs.Expired,
  475. cancellationToken);
  476. }
  477. /// <summary>
  478. /// 解除静音
  479. /// </summary>
  480. /// <param name="telNo">分机号</param>
  481. /// <param name="cancellationToken"></param>
  482. /// <returns></returns>
  483. public async Task UnMuteAsync(string telNo, CancellationToken cancellationToken)
  484. {
  485. await _newRockClient.MuteOrUnMute(
  486. new MuteSetRequest() { Attribute = "Unmute", Ext = new Ext() { Id = telNo } },
  487. _options.Value.DeviceConfigs.ReceiveKey,
  488. _options.Value.DeviceConfigs.Expired,
  489. cancellationToken);
  490. }
  491. /// <summary>
  492. /// 强拆分机
  493. /// </summary>
  494. /// <param name="extId"></param>
  495. /// <param name="cancellationToken"></param>
  496. /// <returns></returns>
  497. public async Task ClearExtAsync(string extId, CancellationToken cancellationToken)
  498. {
  499. await _newRockClient.ClearCall(new ClearCallRequest()
  500. {
  501. Attribute = "Clear",
  502. Ext = new Ext()
  503. {
  504. Id = extId
  505. }
  506. }, _options.Value.DeviceConfigs.ReceiveKey,
  507. _options.Value.DeviceConfigs.Expired,
  508. cancellationToken);
  509. }
  510. /// <summary>
  511. /// 强拆来电
  512. /// </summary>
  513. /// <param name="visitorId"></param>
  514. /// <param name="cancellationToken"></param>
  515. /// <returns></returns>
  516. public async Task ClearVisitorAsync(string visitorId, CancellationToken cancellationToken)
  517. {
  518. await _newRockClient.ClearCall(new ClearCallRequest()
  519. {
  520. Attribute = "Clear",
  521. Visitor = new ClearCallVisitor() { Id = visitorId }
  522. }, _options.Value.DeviceConfigs.ReceiveKey,
  523. _options.Value.DeviceConfigs.Expired,
  524. cancellationToken);
  525. }
  526. /// <summary>
  527. /// 强拆去电
  528. /// </summary>
  529. /// <param name="outerId"></param>
  530. /// <param name="cancellationToken"></param>
  531. /// <returns></returns>
  532. public async Task ClearOuterAsync(string outerId, CancellationToken cancellationToken)
  533. {
  534. await _newRockClient.ClearCall(new ClearCallRequest()
  535. {
  536. Attribute = "Clear",
  537. Outer = new ClearCallOuter() { Id = outerId }
  538. }, _options.Value.DeviceConfigs.ReceiveKey,
  539. _options.Value.DeviceConfigs.Expired,
  540. cancellationToken);
  541. }
  542. /// <summary>
  543. /// 来电受理
  544. /// </summary>
  545. /// <param name="visitorId"></param>
  546. /// <param name="cancellationToken"></param>
  547. /// <returns></returns>
  548. public async Task AcceptVisitorAsync(string visitorId, CancellationToken cancellationToken)
  549. {
  550. await _newRockClient.AcceptVisitor(new AcceptVisitorRequest()
  551. {
  552. Attribute = "Accept",
  553. Visitor = new AcceptVisitorModel() { Id = visitorId }
  554. }, _options.Value.DeviceConfigs.ReceiveKey,
  555. _options.Value.DeviceConfigs.Expired,
  556. cancellationToken);
  557. }
  558. #endregion
  559. #region 连接呼叫
  560. /// <summary>
  561. /// 分机呼分机
  562. /// </summary>
  563. /// <param name="from">主叫分机号</param>
  564. /// <param name="to">被叫分机号</param>
  565. /// <param name="cancellationToken"></param>
  566. /// <returns></returns>
  567. public async Task ExtToExtAsync(string from, string to, CancellationToken cancellationToken)
  568. {
  569. await _newRockClient.ExtensionToExtension(
  570. new ExtensionToExtensionRequest()
  571. {
  572. Attribute = "Connect",
  573. Exts = new List<ExtToExtExt>() { new ExtToExtExt() { Id = from }, new ExtToExtExt() { Id = to } }
  574. }, _options.Value.DeviceConfigs.ReceiveKey,
  575. _options.Value.DeviceConfigs.Expired,
  576. cancellationToken);
  577. }
  578. /// <summary>
  579. /// 分机呼外部电话
  580. /// </summary>
  581. /// <param name="from">分机号</param>
  582. /// <param name="to">外部电话,外地电话加拨0</param>
  583. /// <param name="cancellationToken"></param>
  584. /// <param name="trunkid">指定中继线路(可为空),为空时默认由OM分配</param>
  585. /// <returns></returns>
  586. public async Task ExtToOuterAsync(string from, string to, CancellationToken cancellationToken, string trunkid = "")
  587. {
  588. await _newRockClient.ExtToOuter(
  589. new ExtToOuterRequest()
  590. {
  591. Attribute = "Connect",
  592. Ext = new ExtToOuterExtRequest() { Id = from },
  593. Outer = new ExtToOuterOuterRequest() { To = to },
  594. Trunk = new ExtToOuterTrunkRequest() { Id = trunkid }
  595. },
  596. _options.Value.DeviceConfigs.ReceiveKey,
  597. _options.Value.DeviceConfigs.Expired,
  598. cancellationToken);
  599. }
  600. /// <summary>
  601. /// 来电转分机
  602. /// </summary>
  603. /// <param name="visitorId">来电会话ID</param>
  604. /// <param name="telNo">分机号</param>
  605. /// <param name="cancellationToken"></param>
  606. /// <returns></returns>
  607. public async Task VisitorToExtAsync(string visitorId, string telNo, CancellationToken cancellationToken)
  608. {
  609. await _newRockClient.VisitorToExt(new VisitorToExtRequest()
  610. {
  611. Attribute = "Connect",
  612. Visitor = new VisitorToExtVisitor() { Id = visitorId },
  613. Ext = new VisitorToExtExt() { Id = telNo }
  614. }, _options.Value.DeviceConfigs.ReceiveKey,
  615. _options.Value.DeviceConfigs.Expired,
  616. cancellationToken);
  617. }
  618. /// <summary>
  619. /// 来电转外部电话
  620. /// </summary>
  621. /// <param name="visitorId">来电会话ID</param>
  622. /// <param name="outerPhoneNum">外部电话,外地电话加拨0</param>
  623. /// <param name="cancellationToken"></param>
  624. /// <param name="display">来电号码,用来透传主叫号码,使去电方的来电显示号码为实际来电号码。</param>
  625. /// <returns></returns>
  626. public async Task VisitorToOuterAsync(string visitorId, string outerPhoneNum, CancellationToken cancellationToken,
  627. string display = "")
  628. {
  629. await _newRockClient.VisitorToOuter(new VisitorToOuterRequest()
  630. {
  631. Attribute = "Connect",
  632. Visitor = new VisitorToOuterVisitor() { Id = visitorId },
  633. Outer = new VisitorToOuterOuter() { To = outerPhoneNum, Display = display },
  634. }, _options.Value.DeviceConfigs.ReceiveKey,
  635. _options.Value.DeviceConfigs.Expired,
  636. cancellationToken);
  637. }
  638. /// <summary>
  639. /// 来电转语音菜单
  640. /// </summary>
  641. /// <param name="visitorId">来电会话ID</param>
  642. /// <param name="menuId">菜单ID</param>
  643. /// <param name="cancellationToken"></param>
  644. /// <returns></returns>
  645. public async Task VisitorToMenuAsync(string visitorId, string menuId, CancellationToken cancellationToken)
  646. {
  647. await _newRockClient.VisitorToMenu(new VisitorToMenuRequest()
  648. {
  649. Attribute = "Connect",
  650. Visitor = new VisitorToMenuVisitor() { Id = visitorId },
  651. Menu = new VisitorToMenuMenu() { Id = menuId }
  652. }, _options.Value.DeviceConfigs.ReceiveKey,
  653. _options.Value.DeviceConfigs.Expired,
  654. cancellationToken);
  655. }
  656. /// <summary>
  657. /// 来电转分机组
  658. /// </summary>
  659. /// <param name="visitorId"></param>
  660. /// <param name="groupId"></param>
  661. /// <param name="cancellationToken"></param>
  662. /// <returns></returns>
  663. public async Task VisitorToGroupAsync(string visitorId, string groupId, CancellationToken cancellationToken)
  664. {
  665. await _newRockClient.VisitorToGroupQueue(new VisitorToGroupQueueRequest()
  666. {
  667. Attribute = "Queue",
  668. Visitor = new VisitorToGroupQueueVisitor() { Id = visitorId },
  669. Group = new VisitorToGroupQueueGroup() { Id = groupId }
  670. }, _options.Value.DeviceConfigs.ReceiveKey,
  671. _options.Value.DeviceConfigs.Expired,
  672. cancellationToken);
  673. }
  674. /// <summary>
  675. /// 去电转分机
  676. /// </summary>
  677. /// <param name="outerId">去电会话ID</param>
  678. /// <param name="telNo">分机号</param>
  679. /// <param name="cancellationToken"></param>
  680. /// <returns></returns>
  681. public async Task OuterToExtAsync(string outerId, string telNo, CancellationToken cancellationToken)
  682. {
  683. await _newRockClient.OuterToExt(new OuterToExtRequest()
  684. {
  685. Attribute = "Connect",
  686. Outer = new OuterToExtOuter() { Id = outerId },
  687. Ext = new OuterToExtExt() { Id = telNo }
  688. },
  689. _options.Value.DeviceConfigs.ReceiveKey,
  690. _options.Value.DeviceConfigs.Expired,
  691. cancellationToken);
  692. }
  693. /// <summary>
  694. /// 去电转外部电话
  695. /// </summary>
  696. /// <param name="outerId">去电会话ID</param>
  697. /// <param name="outerPhoneNum">外部电话,外地电话加拨0</param>
  698. /// <param name="cancellationToken"></param>
  699. /// <returns></returns>
  700. public async Task OuterToOuterAsync(string outerId, string outerPhoneNum, CancellationToken cancellationToken)
  701. {
  702. await _newRockClient.OuterToOuter(new OuterToOuterRequest()
  703. {
  704. Attribute = "Connect",
  705. Outer = new List<OuterToOuterOuterModel>()
  706. {
  707. new OuterToOuterOuterModel() { Id = outerId },
  708. new OuterToOuterOuterModel() { To = outerPhoneNum }
  709. },
  710. }, _options.Value.DeviceConfigs.ReceiveKey,
  711. _options.Value.DeviceConfigs.Expired,
  712. cancellationToken);
  713. }
  714. /// <summary>
  715. /// 语音菜单呼叫分机
  716. /// </summary>
  717. /// <param name="menuId">语音菜单ID</param>
  718. /// <param name="telNo">分机号</param>
  719. /// <param name="cancellationToken"></param>
  720. /// <returns></returns>
  721. public async Task MenuToExtAsync(string menuId, string telNo, CancellationToken cancellationToken)
  722. {
  723. await _newRockClient.MenuToExt(new MenuToExtRequest()
  724. {
  725. Attribute = "Connect",
  726. Menu = new MenuToExtMenu() { Id = menuId },
  727. Ext = new MenuToExtExt() { Id = telNo }
  728. }, _options.Value.DeviceConfigs.ReceiveKey,
  729. _options.Value.DeviceConfigs.Expired,
  730. cancellationToken);
  731. }
  732. /// <summary>
  733. /// 语音菜单呼外部电话
  734. /// </summary>
  735. /// <param name="menuId">语音菜单ID</param>
  736. /// <param name="outerPhoneNum">外部电话,外地电话加拨0</param>
  737. /// <param name="cancellationToken"></param>
  738. /// <returns></returns>
  739. public async Task MenuToOuterAsync(string menuId, string outerPhoneNum, CancellationToken cancellationToken)
  740. {
  741. await _newRockClient.MenuToOuter(new MenuToOuterRequest()
  742. {
  743. Attribute = "Connect",
  744. Menu = new MenuToOuterMenu() { Id = menuId },
  745. Outer = new MenuToOuterOuter() { To = outerPhoneNum }
  746. }, _options.Value.DeviceConfigs.ReceiveKey,
  747. _options.Value.DeviceConfigs.Expired,
  748. cancellationToken);
  749. }
  750. /// <summary>
  751. /// 双向呼叫(回拨)
  752. /// </summary>
  753. /// <param name="outerOne">主叫外部电话,外地电话加拨0</param>
  754. /// <param name="outerTwo">被叫外部电话,外地电话加拨0</param>
  755. /// <param name="cancellationToken"></param>
  756. /// <returns></returns>
  757. public async Task TwoWayOuterAsync(string outerOne, string outerTwo, CancellationToken cancellationToken)
  758. {
  759. await _newRockClient.TwoWayOuter(new TwoWayOuterRequest()
  760. {
  761. Attribute = "Connect",
  762. Outer = new List<TwoWayOuterOuter>()
  763. {
  764. new TwoWayOuterOuter(){ To = outerOne},
  765. new TwoWayOuterOuter(){ To = outerTwo}
  766. }
  767. }, _options.Value.DeviceConfigs.ReceiveKey,
  768. _options.Value.DeviceConfigs.Expired,
  769. cancellationToken);
  770. }
  771. /// <summary>
  772. /// 语音插播(分机)
  773. /// </summary>
  774. /// <param name="voiceFileName">语音名称</param>
  775. /// <param name="telNo">分机号</param>
  776. /// <param name="cancellationToken"></param>
  777. /// <returns></returns>
  778. public async Task VoiceNewsFlashExtAsync(string voiceFileName, string telNo, CancellationToken cancellationToken)
  779. {
  780. await _newRockClient.VoiceNewsFlash(new VoiceNewsFlashRequest
  781. {
  782. Attribute = "Connect",
  783. VoiceFile = voiceFileName,
  784. Ext = new VoiceNewsFlashExt() { Id = telNo }
  785. }, _options.Value.DeviceConfigs.ReceiveKey,
  786. _options.Value.DeviceConfigs.Expired,
  787. cancellationToken);
  788. }
  789. /// <summary>
  790. /// 语音插播(来电)
  791. /// </summary>
  792. /// <param name="voiceFileName">语音名称</param>
  793. /// <param name="visitorId">来电会话ID</param>
  794. /// <param name="cancellationToken"></param>
  795. /// <returns></returns>
  796. public async Task VoiceNewsFlashVisitorAsync(string voiceFileName, string visitorId,
  797. CancellationToken cancellationToken)
  798. {
  799. await _newRockClient.VoiceNewsFlash(
  800. new VoiceNewsFlashRequest
  801. {
  802. Attribute = "Connect",
  803. VoiceFile = voiceFileName,
  804. Visitor = new VoiceNewsFlashVisitor() { Id = visitorId }
  805. }, _options.Value.DeviceConfigs.ReceiveKey,
  806. _options.Value.DeviceConfigs.Expired,
  807. cancellationToken);
  808. }
  809. /// <summary>
  810. /// 语音插播(去电)
  811. /// </summary>
  812. /// <param name="voiceFileName">语音名称</param>
  813. /// <param name="outerId">去电会话ID</param>
  814. /// <param name="cancellationToken"></param>
  815. /// <returns></returns>
  816. public async Task VoiceNewsFlashOuterAsync(string voiceFileName, string outerId, CancellationToken cancellationToken)
  817. {
  818. await _newRockClient.VoiceNewsFlash(
  819. new VoiceNewsFlashRequest
  820. {
  821. Attribute = "Connect",
  822. VoiceFile = voiceFileName,
  823. Outer = new VoiceNewsFlashOuter() { Id = outerId }
  824. }, _options.Value.DeviceConfigs.ReceiveKey,
  825. _options.Value.DeviceConfigs.Expired,
  826. cancellationToken);
  827. }
  828. /// <summary>
  829. /// 会议
  830. /// </summary>
  831. /// <param name="telNo">发起方分机号</param>
  832. /// <param name="cancellationToken"></param>
  833. /// <returns></returns>
  834. public async Task ConferenceMeetingAsync(string telNo, CancellationToken cancellationToken)
  835. {
  836. await _newRockClient.ConferenceMeeting(new ConferenceMeetingRequest()
  837. {
  838. Attribute = "Conference",
  839. Ext = new ConferenceMeetingExt() { Id = telNo }
  840. }, _options.Value.DeviceConfigs.ReceiveKey,
  841. _options.Value.DeviceConfigs.Expired,
  842. cancellationToken);
  843. }
  844. /// <summary>
  845. /// 处理IVR响应
  846. /// </summary>
  847. /// <param name="callDetail"></param>
  848. /// <param name="ivrAnswer"></param>
  849. /// <param name="cancellationToken"></param>
  850. /// <returns></returns>
  851. public async Task HandleIvrAnswerAsync(CallDetail callDetail, IvrAnswer ivrAnswer, CancellationToken cancellationToken)
  852. {
  853. if (string.IsNullOrEmpty(ivrAnswer.Content))
  854. throw new UserFriendlyException("无效IVR应答参数");
  855. //获取是来电或去电
  856. var model = await _callRepository.GetAsync(x => x.Id == callDetail.CallId, cancellationToken);
  857. }
  858. #endregion
  859. #region 监听和插播
  860. /// <summary>
  861. /// 监听分机
  862. /// </summary>
  863. /// <param name="firstTelNo">监听方</param>
  864. /// <param name="secondTelNo">被监听方</param>
  865. /// <param name="cancellationToken"></param>
  866. /// <returns></returns>
  867. public async Task MonitorExtAsync(string firstTelNo, string secondTelNo, CancellationToken cancellationToken)
  868. {
  869. await _newRockClient.MonitorExt(new MonitorExtRequest()
  870. {
  871. Attribute = "Monitor",
  872. Exts = new List<Ext>() { new Ext() { Id=firstTelNo },new Ext() { Id=secondTelNo } }
  873. }, _options.Value.DeviceConfigs.ReceiveKey,
  874. _options.Value.DeviceConfigs.Expired,
  875. cancellationToken) ;
  876. }
  877. /// <summary>
  878. /// 从监听到插播状态变换
  879. /// 1. 已知:分机 A 在监听分机 B 与其通话方的通话;
  880. /// 2. 执行分机 A 的从监听到插播状态变换的 API;
  881. /// 3. 执行成功时,分机 A 与分机 B 建立通话,分机 B 的原通话方听保持音。
  882. /// </summary>
  883. /// <param name="telNo"></param>
  884. /// <param name="cancellationToken"></param>
  885. /// <returns></returns>
  886. public async Task MonitorExtToTalkAsync(string telNo, CancellationToken cancellationToken)
  887. {
  888. await _newRockClient.MonitorExtToTalk(new MonitorExtToTalkRequest()
  889. {
  890. Attribute = "Talk",
  891. Ext = new Ext() { Id = telNo }
  892. }, _options.Value.DeviceConfigs.ReceiveKey,
  893. _options.Value.DeviceConfigs.Expired,
  894. cancellationToken) ;
  895. }
  896. /// <summary>
  897. /// 从插播到监听状态变换
  898. /// 1. 已知:分机 A 在插播分机 B 的通话;
  899. /// 2. 执行分机 A 的从插播到监听状态变换的 API;
  900. /// 3. 执行成功时,分机 A 监听分机 B 及其原通话方的通话。
  901. /// </summary>
  902. /// <param name="telNo"></param>
  903. /// <param name="cancellationToken"></param>
  904. /// <returns></returns>
  905. public async Task MonitorExtToListenAsync(string telNo, CancellationToken cancellationToken)
  906. {
  907. await _newRockClient.MonitorExtToListen(new MonitorExtToListenRequest
  908. {
  909. Attribute = "Listen",
  910. Ext = new Ext() { Id = telNo }
  911. }, _options.Value.DeviceConfigs.ReceiveKey,
  912. _options.Value.DeviceConfigs.Expired,
  913. cancellationToken);
  914. }
  915. #endregion
  916. #region 强插
  917. /// <summary>
  918. /// 强插
  919. /// 1. 已知:分机 A 当前空闲,分机 B 正在通话中;
  920. /// 2. 执行分机 A 强插分机 B 的 API;
  921. /// 3. 执行成功时,分机 A 振铃,摘机后即可形成三方通话。
  922. /// </summary>
  923. /// <param name="firstTelNo"></param>
  924. /// <param name="secondTelNo"></param>
  925. /// <param name="cancellationToken"></param>
  926. /// <returns></returns>
  927. public async Task BargeinExtAsync(string firstTelNo,string secondTelNo,CancellationToken cancellationToken)
  928. {
  929. await _newRockClient.BargeinExt(new BargeinExtRequest()
  930. {
  931. Attribute = "Bargein",
  932. Exts = new List<Ext>() { new Ext() { Id = firstTelNo },new Ext() { Id=secondTelNo } }
  933. }, _options.Value.DeviceConfigs.ReceiveKey,
  934. _options.Value.DeviceConfigs.Expired,
  935. cancellationToken);
  936. }
  937. #endregion
  938. }
  939. }