| Line 89... |
Line 89... |
| 89 |
* Assignee used for AI leads only when no active BGC L1 can be resolved from cs.position.
|
89 |
* Assignee used for AI leads only when no active BGC L1 can be resolved from cs.position.
|
| 90 |
* Same auth id the web capture has always routed to, so intake never fails on an empty pool.
|
90 |
* Same auth id the web capture has always routed to, so intake never fails on an empty pool.
|
| 91 |
*/
|
91 |
*/
|
| 92 |
private static final int AI_LEAD_FALLBACK_ASSIGNEE = 53;
|
92 |
private static final int AI_LEAD_FALLBACK_ASSIGNEE = 53;
|
| 93 |
|
93 |
|
| - |
|
94 |
// Ira channels the AI side sends in AiLeadRequest.source, stored on lead.ai_channel.
|
| - |
|
95 |
private static final String IRA_PHONE = "IRA_PHONE";
|
| - |
|
96 |
private static final String IRA_WEB = "IRA_WEB";
|
| - |
|
97 |
|
| - |
|
98 |
// AI leads from the Ira toll-free number all go to Meenakshi Mehta, and she is left out of the
|
| - |
|
99 |
// random pool for every other AI lead.
|
| - |
|
100 |
private static final int IRA_PHONE_LEAD_ASSIGNEE = 84;
|
| - |
|
101 |
|
| 94 |
@Autowired
|
102 |
@Autowired
|
| 95 |
private ResponseSender<?> responseSender;
|
103 |
private ResponseSender<?> responseSender;
|
| 96 |
|
104 |
|
| 97 |
@Value("${ai.lead.intake.token}")
|
105 |
@Value("${ai.lead.intake.token}")
|
| 98 |
private String aiLeadIntakeToken;
|
106 |
private String aiLeadIntakeToken;
|
| Line 813... |
Line 821... |
| 813 |
String recordingUrl = aiLeadRequest.getRecordingUrl();
|
821 |
String recordingUrl = aiLeadRequest.getRecordingUrl();
|
| 814 |
if (recordingUrl != null && !recordingUrl.trim().isEmpty()) {
|
822 |
if (recordingUrl != null && !recordingUrl.trim().isEmpty()) {
|
| 815 |
lead.setRecordingUrl(recordingUrl.trim());
|
823 |
lead.setRecordingUrl(recordingUrl.trim());
|
| 816 |
}
|
824 |
}
|
| 817 |
|
825 |
|
| - |
|
826 |
// Ira channel: IRA_PHONE from the toll-free number, everything else (IRA_WEB, no source, or an
|
| 818 |
// Auto-assign to a randomly picked active BGC L1 so AI leads spread across the lead desk
|
827 |
// unknown value) is a web lead. A missing source is still accepted, as before.
|
| - |
|
828 |
String channel = aiLeadRequest.getSource() == null ? "" : aiLeadRequest.getSource().trim().toUpperCase();
|
| - |
|
829 |
if (!channel.isEmpty() && !IRA_PHONE.equals(channel) && !IRA_WEB.equals(channel)) {
|
| - |
|
830 |
LOGGER.warn("AI lead intake: unknown source '{}' for mobile {}, treating as web", aiLeadRequest.getSource(), mobile);
|
| - |
|
831 |
}
|
| - |
|
832 |
lead.setAiChannel(IRA_PHONE.equals(channel) ? IRA_PHONE : IRA_WEB);
|
| - |
|
833 |
|
| 819 |
lead.setAssignTo(resolveAiLeadAssignee());
|
834 |
lead.setAssignTo(resolveAiLeadAssignee(lead));
|
| 820 |
lead.setAuthId(lead.getAssignTo());
|
835 |
lead.setAuthId(lead.getAssignTo());
|
| 821 |
|
836 |
|
| 822 |
lead.setCreatedTimestamp(LocalDateTime.now());
|
837 |
lead.setCreatedTimestamp(LocalDateTime.now());
|
| 823 |
lead.setUpdatedTimestamp(LocalDateTime.now());
|
838 |
lead.setUpdatedTimestamp(LocalDateTime.now());
|
| 824 |
// Unattended: the AI intake is a bot; a collision is skipped and mailed, not thrown.
|
839 |
// Unattended: the AI intake is a bot; a collision is skipped and mailed, not thrown.
|
| Line 847... |
Line 862... |
| 847 |
ProfitMandiConstants.TICKET_CATEGORY_BGC, EscalationType.L1);
|
862 |
ProfitMandiConstants.TICKET_CATEGORY_BGC, EscalationType.L1);
|
| 848 |
|
863 |
|
| 849 |
List<AuthUser> eligible = bgcL1 == null ? Collections.<AuthUser>emptyList()
|
864 |
List<AuthUser> eligible = bgcL1 == null ? Collections.<AuthUser>emptyList()
|
| 850 |
: bgcL1.stream()
|
865 |
: bgcL1.stream()
|
| 851 |
.filter(x -> Boolean.TRUE.equals(x.isActive()))
|
866 |
.filter(x -> Boolean.TRUE.equals(x.isActive()))
|
| - |
|
867 |
.filter(x -> x.getId() != IRA_PHONE_LEAD_ASSIGNEE)
|
| 852 |
.collect(Collectors.toList());
|
868 |
.collect(Collectors.toList());
|
| 853 |
|
869 |
|
| 854 |
if (eligible.isEmpty()) {
|
870 |
if (eligible.isEmpty()) {
|
| 855 |
LOGGER.warn("AI lead intake: no active BGC L1 in cs.position, falling back to auth id {}",
|
871 |
LOGGER.warn("AI lead intake: no active BGC L1 in cs.position, falling back to auth id {}",
|
| 856 |
AI_LEAD_FALLBACK_ASSIGNEE);
|
872 |
AI_LEAD_FALLBACK_ASSIGNEE);
|
| Line 861... |
Line 877... |
| 861 |
LOGGER.info("AI lead intake: assigned to BGC L1 {} ({}) picked from {} eligible",
|
877 |
LOGGER.info("AI lead intake: assigned to BGC L1 {} ({}) picked from {} eligible",
|
| 862 |
assignee.getId(), assignee.getFullName(), eligible.size());
|
878 |
assignee.getId(), assignee.getFullName(), eligible.size());
|
| 863 |
return assignee.getId();
|
879 |
return assignee.getId();
|
| 864 |
}
|
880 |
}
|
| 865 |
|
881 |
|
| - |
|
882 |
/**
|
| - |
|
883 |
* Ira phone leads go to Meenakshi; every other AI lead to a random active BGC L1. If she is ever
|
| - |
|
884 |
* deactivated, phone leads fall back to the pool rather than stranding with an inactive owner.
|
| - |
|
885 |
*/
|
| - |
|
886 |
private int resolveAiLeadAssignee(Lead lead) {
|
| - |
|
887 |
if (IRA_PHONE.equals(lead.getAiChannel())) {
|
| - |
|
888 |
AuthUser phoneOwner = authRepository.selectById(IRA_PHONE_LEAD_ASSIGNEE);
|
| - |
|
889 |
if (phoneOwner != null && Boolean.TRUE.equals(phoneOwner.isActive())) {
|
| - |
|
890 |
return IRA_PHONE_LEAD_ASSIGNEE;
|
| - |
|
891 |
}
|
| - |
|
892 |
LOGGER.warn("AI lead intake: Ira phone owner {} is inactive, using the BGC L1 pool", IRA_PHONE_LEAD_ASSIGNEE);
|
| - |
|
893 |
}
|
| - |
|
894 |
return resolveAiLeadAssignee();
|
| - |
|
895 |
}
|
| - |
|
896 |
|
| 866 |
@RequestMapping(value = "/getPartnersList", method = RequestMethod.GET)
|
897 |
@RequestMapping(value = "/getPartnersList", method = RequestMethod.GET)
|
| 867 |
@ApiImplicitParams({@ApiImplicitParam(name = "Auth-Token", value = "Auth-Token", required = true, dataType = "string", paramType = "header")})
|
898 |
@ApiImplicitParams({@ApiImplicitParam(name = "Auth-Token", value = "Auth-Token", required = true, dataType = "string", paramType = "header")})
|
| 868 |
public ResponseEntity<?> getPartners(HttpServletRequest request, @RequestParam(name = "gmailId") String gmailId)
|
899 |
public ResponseEntity<?> getPartners(HttpServletRequest request, @RequestParam(name = "gmailId") String gmailId)
|
| 869 |
throws ProfitMandiBusinessException {
|
900 |
throws ProfitMandiBusinessException {
|
| 870 |
|
901 |
|