Skip to content

Commit fa09565

Browse files
authored
feat: Implement method to fetch leads by people.
feat: Implement method to fetch leads by people.
2 parents 918d4cf + 7ffdf71 commit fa09565

9 files changed

Lines changed: 227 additions & 180 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package integrations.telex.salesagent.lead.dto;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Data;
5+
import lombok.NoArgsConstructor;
6+
7+
@Data
8+
@AllArgsConstructor
9+
@NoArgsConstructor
10+
public class PeopleLeadDto {
11+
private String fullName;
12+
private String headline;
13+
private String location;
14+
private String profileURL;
15+
private String username;
16+
}
17+
Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,31 @@
11
package integrations.telex.salesagent.lead.dto;
22

3+
import integrations.telex.salesagent.lead.service.LocationMappingService;
34
import lombok.Data;
5+
import lombok.RequiredArgsConstructor;
46

57
@Data
8+
@RequiredArgsConstructor
69
public class PeopleSearchRequest {
7-
private String url;
10+
private String keyword;
11+
private String location;
12+
13+
private transient LocationMappingService locationMappingService;
14+
15+
public String buildLinkedInSearchUrl() {
16+
StringBuilder urlBuilder = new StringBuilder("https://www.linkedin.com/search/results/people/?");
17+
18+
if (location != null && !location.isEmpty()) {
19+
String geoUrn = locationMappingService.getGeoUrnForLocation(location);
20+
if (geoUrn != null) {
21+
urlBuilder.append("geoUrn=%5B%22").append(geoUrn).append("%22%5D&");
22+
} else {
23+
// Handle case where location is not found in the mapping
24+
System.out.println("Location not found in mapping: " + location);
25+
}
26+
}
27+
28+
urlBuilder.append("origin=FACETED_SEARCH");
29+
return urlBuilder.toString();
30+
}
831
}

src/main/java/integrations/telex/salesagent/lead/service/LeadPeopleResearchService.java

Lines changed: 75 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package integrations.telex.salesagent.lead.service;
22

3+
import com.fasterxml.jackson.core.JsonProcessingException;
34
import com.fasterxml.jackson.databind.JsonNode;
45
import com.fasterxml.jackson.databind.ObjectMapper;
6+
import integrations.telex.salesagent.lead.dto.PeopleLeadDto;
57
import integrations.telex.salesagent.lead.dto.PeopleSearchRequest;
6-
import integrations.telex.salesagent.lead.dto.RapidLeadDto;
78
import integrations.telex.salesagent.telex.service.TelexClient;
89
import lombok.RequiredArgsConstructor;
910
import org.springframework.beans.factory.annotation.Value;
@@ -16,6 +17,7 @@
1617
import java.util.HashMap;
1718
import java.util.List;
1819
import java.util.Map;
20+
import java.util.stream.Collectors;
1921

2022
@Slf4j
2123
@Service
@@ -34,65 +36,94 @@ public class LeadPeopleResearchService {
3436
private final ObjectMapper objectMapper;
3537
private final TelexClient telexClient;
3638

37-
public List<RapidLeadDto> queryLeads(String channelID, PeopleSearchRequest request) {
39+
public List<PeopleLeadDto> queryLeads(String channelID, PeopleSearchRequest request) {
3840
try {
39-
// Prepare headers
40-
HttpHeaders headers = new HttpHeaders();
41-
headers.set("X-RapidAPI-Key", rapidApiKey);
42-
headers.set("X-RapidAPI-Host", rapidApiHost);
43-
headers.setContentType(MediaType.APPLICATION_JSON);
44-
45-
// Build the request body (LinkedIn search URL)
46-
Map<String, String> payload = new HashMap<>();
47-
payload.put("url", request.getUrl());
48-
49-
HttpEntity<Map<String, String>> entity = new HttpEntity<>(payload, headers);
50-
51-
// Call RapidAPI
52-
log.info("Searching for people with URL: {}", request.getUrl());
53-
ResponseEntity<String> response = restTemplate.exchange(
54-
rapidApiUrl, HttpMethod.POST, entity, String.class
55-
);
56-
57-
// Process the response
58-
if (response.getStatusCode().is2xxSuccessful()) {
59-
List<RapidLeadDto> leads = formatPeopleResponse(response.getBody());
60-
61-
if (leads.isEmpty()) {
62-
String report = "🔍 No LinkedIn profiles found for the given search URL.";
63-
telexClient.sendInstruction(channelID, report);
64-
} else {
65-
for (RapidLeadDto lead : leads) {
66-
telexClient.processTelexPayload(channelID, lead);
67-
}
68-
}
69-
return leads;
70-
} else {
71-
log.error("API Error: {}", response.getStatusCode());
72-
return new ArrayList<>();
41+
// Build URL with location filter
42+
String searchUrl = request.buildLinkedInSearchUrl();
43+
log.info("Constructed LinkedIn search URL: {}", searchUrl);
44+
45+
// Make API call
46+
List<PeopleLeadDto> leads = fetchLeadsFromApi(searchUrl);
47+
48+
// Apply keyword filtering
49+
if (request.getKeyword() != null && !request.getKeyword().isEmpty()) {
50+
leads = filterByKeyword(leads, request.getKeyword());
51+
log.info("Filtered {} leads by keyword: {}", leads.size(), request.getKeyword());
7352
}
53+
54+
// Process results
55+
processResults(channelID, leads);
56+
57+
return leads;
58+
7459
} catch (Exception e) {
7560
log.error("Error calling RapidAPI: {}", e.getMessage(), e);
61+
}
62+
return new ArrayList<>();
63+
}
64+
65+
private List<PeopleLeadDto> filterByKeyword(List<PeopleLeadDto> leads, String keyword) {
66+
String lowerKeyword = keyword.toLowerCase();
67+
return leads.stream()
68+
.filter(lead ->
69+
(lead.getHeadline() != null &&
70+
lead.getHeadline().toLowerCase().contains(lowerKeyword)) ||
71+
(lead.getFullName() != null &&
72+
lead.getFullName().toLowerCase().contains(lowerKeyword)))
73+
.collect(Collectors.toList());
74+
}
75+
76+
private void processResults(String channelID, List<PeopleLeadDto> leads) throws JsonProcessingException {
77+
if (leads.isEmpty()) {
78+
telexClient.sendInstruction(channelID, "🔍 No matching profiles found.");
79+
} else {
80+
leads.forEach(lead -> {
81+
try {
82+
telexClient.processTelexPayload(channelID, lead);
83+
} catch (JsonProcessingException e) {
84+
throw new RuntimeException(e);
85+
}
86+
});
87+
}
88+
}
89+
90+
private List<PeopleLeadDto> fetchLeadsFromApi(String searchUrl) {
91+
HttpHeaders headers = new HttpHeaders();
92+
headers.set("X-RapidAPI-Key", rapidApiKey);
93+
headers.set("X-RapidAPI-Host", rapidApiHost);
94+
headers.setContentType(MediaType.APPLICATION_JSON);
95+
96+
Map<String, String> payload = new HashMap<>();
97+
payload.put("url", searchUrl);
98+
99+
HttpEntity<Map<String, String>> entity = new HttpEntity<>(payload, headers);
100+
101+
ResponseEntity<String> response = restTemplate.exchange(
102+
rapidApiUrl, HttpMethod.POST, entity, String.class
103+
);
104+
105+
if (!response.getStatusCode().is2xxSuccessful()) {
106+
log.error("API request failed with status: {}", response.getStatusCode());
76107
return new ArrayList<>();
77108
}
109+
110+
return formatPeopleResponse(response.getBody());
78111
}
79112

80-
// Parse API response into Lead objects
81-
private List<RapidLeadDto> formatPeopleResponse(String responseBody) {
82-
List<RapidLeadDto> leads = new ArrayList<>();
113+
private List<PeopleLeadDto> formatPeopleResponse(String responseBody) {
114+
List<PeopleLeadDto> leads = new ArrayList<>();
83115
try {
84116
JsonNode root = objectMapper.readTree(responseBody);
85117
JsonNode items = root.path("data").path("items");
86118

87119
if (items.isArray()) {
88120
for (JsonNode item : items) {
89-
RapidLeadDto lead = new RapidLeadDto(
90-
null,
121+
PeopleLeadDto lead = new PeopleLeadDto(
91122
item.path("fullName").asText(),
123+
item.path("headline").asText(),
124+
item.path("location").asText(),
92125
item.path("profileURL").asText(),
93-
String.format("%s | %s",
94-
item.path("headline").asText(),
95-
item.path("location").asText())
126+
item.path("username").asText()
96127
);
97128
leads.add(lead);
98129
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package integrations.telex.salesagent.lead.service;
2+
3+
import org.springframework.stereotype.Service;
4+
5+
import java.util.Map;
6+
7+
import static java.util.Map.entry;
8+
9+
@Service
10+
public class LocationMappingService {
11+
private static final Map<String, String> LOCATION_TO_GEOURN = Map.of(
12+
"lagos", "104197452",
13+
"atlanta", "103644278",
14+
"new york", "100288700",
15+
"abuja", "101711968",
16+
"port harcourt", "114378074",
17+
"london", "90009496",
18+
"kaduna", "103668447"
19+
);
20+
21+
public String getGeoUrnForLocation(String locationName) {
22+
if (locationName == null) return null;
23+
return LOCATION_TO_GEOURN.get(locationName.toLowerCase());
24+
}
25+
}

src/main/java/integrations/telex/salesagent/lead/service/RapidLeadResearch.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public List<RapidLeadDto> queryLeads(String channelID,CompanySearchRequest reque
6969

7070
// Forward each lead to Telex
7171
for (RapidLeadDto lead : newLeads) {
72-
telexClient.processTelexPayload(channelID, lead);
72+
//telexClient.processTelexPayload(channelID, lead);
7373
log.info("Lead sent to Telex: {}", lead.getName());
7474
}
7575
} else {

src/main/java/integrations/telex/salesagent/telex/service/TelexClient.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import com.fasterxml.jackson.core.JsonProcessingException;
44
import com.fasterxml.jackson.databind.ObjectMapper;
55
import integrations.telex.salesagent.config.AppConfig;
6+
import integrations.telex.salesagent.lead.dto.PeopleLeadDto;
67
import integrations.telex.salesagent.lead.dto.RapidLeadDto;
78
import integrations.telex.salesagent.lead.model.Lead;
9+
import integrations.telex.salesagent.lead.service.LeadPeopleResearchService;
810
import integrations.telex.salesagent.telex.util.FormatTelexMessage;
911
import integrations.telex.salesagent.user.dto.request.TelexPayload;
1012
import lombok.RequiredArgsConstructor;
@@ -20,6 +22,7 @@ public class TelexClient {
2022
private final RestTemplate restTemplate;
2123
private final ObjectMapper objectMapper;
2224
private final FormatTelexMessage formatTelexMessage;
25+
private final LeadPeopleResearchService leadPeopleResearchService;
2326

2427
public void sendToTelexChannel(String channelID, String message) {
2528
try {
@@ -32,7 +35,15 @@ public void sendToTelexChannel(String channelID, String message) {
3235
}
3336
}
3437

35-
public void processTelexPayload(String channelID, RapidLeadDto lead) throws JsonProcessingException {
38+
// public void processTelexPayload(String channelID, RapidLeadDto lead) throws JsonProcessingException {
39+
// String message = formatTelexMessage.formatNewLeadMessage(lead) + "\n\nSales Agent Bot";
40+
//
41+
// TelexPayload telexPayload = new TelexPayload("New Lead Alert", "Sales Agent", "success", message);
42+
//
43+
// sendToTelexChannel(channelID, objectMapper.writeValueAsString(telexPayload));
44+
// }
45+
46+
public void processTelexPayload(String channelID, PeopleLeadDto lead) throws JsonProcessingException {
3647
String message = formatTelexMessage.formatNewLeadMessage(lead) + "\n\nSales Agent Bot";
3748

3849
TelexPayload telexPayload = new TelexPayload("New Lead Alert", "Sales Agent", "success", message);

src/main/java/integrations/telex/salesagent/telex/util/FormatTelexMessage.java

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package integrations.telex.salesagent.telex.util;
22

3+
import integrations.telex.salesagent.lead.dto.PeopleLeadDto;
34
import integrations.telex.salesagent.lead.dto.RapidLeadDto;
45
import org.springframework.stereotype.Component;
56

@@ -15,12 +16,32 @@ public class FormatTelexMessage {
1516
Lead Company Summary : %s
1617
""";
1718

18-
public String formatNewLeadMessage(RapidLeadDto data) {
19-
return String.format(NEW_LEAD,
20-
data.getId(),
21-
data.getName(),
22-
data.getLinkedinUrl(),
23-
data.getTagline()
19+
private static final String NEW_LEAD_PEOPLE = """
20+
New lead has been found:
21+
22+
Lead Name: %s
23+
Lead Headline: %s
24+
Lead Location: %s
25+
Lead Profile URL: %s
26+
Lead Username: %s
27+
""";
28+
29+
// public String formatNewLeadMessage(RapidLeadDto data) {
30+
// return String.format(NEW_LEAD,
31+
// data.getId(),
32+
// data.getName(),
33+
// data.getLinkedinUrl(),
34+
// data.getTagline()
35+
// );
36+
// }
37+
38+
public String formatNewLeadMessage(PeopleLeadDto data) {
39+
return String.format(NEW_LEAD_PEOPLE,
40+
data.getFullName(),
41+
data.getHeadline(),
42+
data.getLocation(),
43+
data.getProfileURL(),
44+
data.getUsername()
2445
);
2546
}
2647
}

src/main/java/integrations/telex/salesagent/user/dto/request/LeadDetails.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010
@Getter
1111
@Setter
1212
public class LeadDetails {
13+
// private String businessType;
14+
// private String locations;
15+
// private String companySizes;
1316
private String businessType;
14-
private String locations;
15-
private String companySizes;
17+
private String location;
18+
private String keyword;
1619
}

0 commit comments

Comments
 (0)