Skip to content

Commit d03bbe2

Browse files
authored
add: migrate from proxycurl to enrichlayer (#2288)
1 parent 4e42e6e commit d03bbe2

File tree

14 files changed

+142
-395
lines changed

14 files changed

+142
-395
lines changed

.env.master.dev

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,6 @@ VOILANORBERT_API_KEY = test-api-key
128128
THEDIG_URL = http://127.0.0.1:8083/thedig/
129129
THEDIG_API_KEY = _
130130

131-
#PROXYCURL
132-
PROXYCURL_URL = http://127.0.0.1:8083/proxycurl/
133-
PROXYCURL_API_KEY = _
131+
#ENRICH LAYER
132+
ENRICH_LAYER_URL = https://enrichlayer.com/
133+
ENRICH_LAYER_API_KEY = _

.env.master.prod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,6 @@ VOILANORBERT_API_KEY =
125125
THEDIG_URL =
126126
THEDIG_API_KEY =
127127

128-
#PROXYCURL
129-
PROXYCURL_URL = _
130-
PROXYCURL_API_KEY = _
128+
#ENRICH LAYER
129+
ENRICH_LAYER_URL =
130+
ENRICH_LAYER_API_KEY =

backend/src/config/schema.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,9 @@ const schema = z.object({
110110
THEDIG_URL: z.string().min(1).optional(),
111111
THEDIG_API_KEY: z.string().min(1).optional(),
112112

113-
/* PROXYCURL */
114-
PROXYCURL_URL: z.string().min(1).optional(),
115-
PROXYCURL_API_KEY: z.string().min(1).optional(),
113+
/* ENRICH-LAYER */
114+
ENRICH_LAYER_URL: z.string().min(1).optional(),
115+
ENRICH_LAYER_API_KEY: z.string().min(1).optional(),
116116

117117
NODE_ENV: z.enum(['development', 'production', 'test']).default('production')
118118
});

backend/src/mocks/enrichment/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ export function coloredLog(color: string, text: string) {
1212
export const SERVER_PORT = 8083;
1313
export const VOILANORBERT_USERNAME = 'any_string';
1414
export const VOILANORBERT_API_TOKEN = 'test-api-key';
15-
export const PROXYCURL_API_TOKEN = 'test-api-key';
15+
export const ENRICH_LAYER_API_TOKEN = 'test-api-key';
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { faker } from '@faker-js/faker';
2+
import { Request, Response, Router } from 'express';
3+
4+
const router = Router();
5+
6+
// Helper to randomly return valid or empty data
7+
const maybe = <T>(value: T, probability = 0.7) =>
8+
Math.random() < probability ? value : null;
9+
10+
router.get('/api/v2/profile/resolve/email', (req: Request, res: Response) => {
11+
const { email } = req.query;
12+
// Validation: Ensure email is provided
13+
if (!email) {
14+
return res.status(400).json({
15+
code: '400',
16+
error: 'Email parameter is required for reverse lookup'
17+
});
18+
}
19+
20+
try {
21+
const fakeProfile = {
22+
city: maybe(faker.location.city(), 0.8),
23+
full_name: maybe(faker.person.fullName(), 0.9),
24+
first_name: maybe(faker.person.firstName(), 0.85),
25+
last_name: maybe(faker.person.lastName(), 0.85),
26+
state: maybe(faker.location.state(), 0.6),
27+
country: maybe(faker.location.countryCode('alpha-2'), 0.7),
28+
country_full_name: maybe(faker.location.country(), 0.7),
29+
languages: maybe([faker.lorem.word(), faker.lorem.word()], 0.6),
30+
occupation: maybe(faker.person.jobTitle(), 0.75),
31+
profile_pic_url: maybe(faker.image.avatar(), 0.8),
32+
public_identifier: faker.string.alphanumeric(10),
33+
extra: {
34+
github_profile_id: maybe(faker.internet.userName(), 0.5),
35+
facebook_profile_id: maybe(faker.internet.userName(), 0.5),
36+
twitter_profile_id: maybe(faker.internet.userName(), 0.5),
37+
website: maybe(faker.internet.url(), 0.5)
38+
},
39+
experiences: Array.from({ length: 2 }).map(() => ({
40+
starts_at: {
41+
day: faker.number.int({ min: 1, max: 28 }),
42+
month: faker.number.int({ min: 1, max: 12 }),
43+
year: faker.number.int({ min: 2000, max: 2023 })
44+
},
45+
ends_at: {
46+
day: maybe(faker.number.int({ min: 1, max: 28 }), 0.7),
47+
month: maybe(faker.number.int({ min: 1, max: 12 }), 0.7),
48+
year: maybe(faker.number.int({ min: 2000, max: 2024 }), 0.7)
49+
},
50+
company: maybe(faker.company.name(), 0.9),
51+
company_linkedin_profile_url: maybe(faker.internet.url(), 0.4),
52+
company_facebook_profile_url: maybe(faker.internet.url(), 0.4),
53+
title: maybe(faker.person.jobTitle(), 0.85),
54+
description: maybe(faker.lorem.paragraph(), 0.6),
55+
location: maybe(faker.location.city(), 0.6),
56+
logo_url: maybe(faker.image.avatar(), 0.7)
57+
}))
58+
};
59+
60+
// Respond with the fake data
61+
return res.status(200).json({
62+
email,
63+
profile: fakeProfile,
64+
last_updated: faker.date.recent().toISOString(),
65+
similarity_score: parseFloat(
66+
faker.number.float({ min: 0.5, max: 1 }).toFixed(2)
67+
),
68+
linkedin_profile_url: maybe(faker.internet.url(), 0.7),
69+
facebook_profile_url: maybe(faker.internet.url(), 0.7),
70+
twitter_profile_url: maybe(faker.internet.url(), 0.7)
71+
});
72+
} catch (error) {
73+
console.error(`[EnrichLayer Mock] Error: ${(error as Error).message}`);
74+
return res.status(500).json({
75+
code: '500',
76+
error: 'Internal Server Error'
77+
});
78+
}
79+
});
80+
81+
export default router;

backend/src/mocks/enrichment/endpoints/proxycurl.ts

Lines changed: 0 additions & 84 deletions
This file was deleted.

backend/src/mocks/enrichment/server.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,22 @@ import express, { json, urlencoded } from 'express';
22
import {
33
coloredLog,
44
colors,
5-
PROXYCURL_API_TOKEN,
5+
ENRICH_LAYER_API_TOKEN,
66
SERVER_PORT,
77
VOILANORBERT_API_TOKEN,
88
VOILANORBERT_USERNAME
99
} from './config';
1010

1111
import voilanorbertRoutes from './endpoints/voilanorbert';
12-
import proxycurlRoutes from './endpoints/proxycurl';
12+
import enrichlayerRoutes from './endpoints/enrichlayer';
1313

1414
const app = express();
1515

1616
app.use(json({ limit: '5mb' }));
1717
app.use(urlencoded({ limit: '5mb', extended: true }));
1818

1919
app.use('/voilanorbert', voilanorbertRoutes);
20-
app.use('/proxycurl', proxycurlRoutes);
20+
app.use('/enrichlayer', enrichlayerRoutes);
2121

2222
app.listen(SERVER_PORT, () => {
2323
// eslint-disable-next-line no-console
@@ -31,9 +31,9 @@ app.listen(SERVER_PORT, () => {
3131
${coloredLog(colors.cyan, '- Username:')} ${VOILANORBERT_USERNAME}
3232
${coloredLog(
3333
colors.cyan,
34-
'- Proxycurl:'
35-
)} http://127.0.0.1:${SERVER_PORT}/proxycurl
36-
${coloredLog(colors.cyan, '- Api key:')} ${PROXYCURL_API_TOKEN}
34+
'- EnrichLayer:'
35+
)} http://127.0.0.1:${SERVER_PORT}/enrichlayer
36+
${coloredLog(colors.cyan, '- Api key:')} ${ENRICH_LAYER_API_TOKEN}
3737
`
3838
);
3939
});

backend/src/services/enrichment/proxy-curl/client.ts renamed to backend/src/services/enrichment/enrich-layer/client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export interface ReverseEmailLookupResponse {
6969
twitter_profile_url: string;
7070
}
7171

72-
export default class ProxycurlApi {
72+
export default class EnrichLayerAPI {
7373
private readonly api: AxiosInstance;
7474

7575
private readonly rateLimiter;
@@ -99,7 +99,7 @@ export default class ProxycurlApi {
9999
try {
100100
const res = await this.rateLimiter.throttleRequests(() =>
101101
this.api.get<ReverseEmailLookupResponse>(
102-
'/api/linkedin/profile/resolve/email',
102+
'/api/v2/profile/resolve/email',
103103
{
104104
params: {
105105
email,

backend/src/services/enrichment/proxy-curl/index.ts renamed to backend/src/services/enrichment/enrich-layer/index.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import { Logger } from 'winston';
22
import { Engine, EngineResponse, Person } from '../Engine';
3-
import ProxycurlApi, {
3+
import EnrichLayerAPI, {
44
ProfileExtra,
55
ReverseEmailLookupResponse
66
} from './client';
77
import { undefinedIfEmpty, undefinedIfFalsy } from '../utils';
88

9-
export default class Proxycurl implements Engine {
9+
export default class EnrichLayer implements Engine {
1010
constructor(
11-
private readonly client: ProxycurlApi,
11+
private readonly client: EnrichLayerAPI,
1212
private readonly logger: Logger
1313
) {}
1414

15-
readonly name = 'proxycurl';
15+
readonly name = 'enrichLayer';
1616

1717
readonly isSync = true;
1818

@@ -91,7 +91,7 @@ export default class Proxycurl implements Engine {
9191
response?.linkedin_profile_url,
9292
response?.facebook_profile_url,
9393
response?.twitter_profile_url,
94-
...Proxycurl.getProfileUrls(response?.profile?.extra)
94+
...EnrichLayer.getProfileUrls(response?.profile?.extra)
9595
])
9696
}
9797
]

backend/src/services/enrichment/index.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import ENV from '../../config';
22
import { Engine } from './Engine';
33
import Enricher from './Enricher';
4-
import Proxycurl from './proxy-curl';
5-
import ProxycurlApi from './proxy-curl/client';
64
import Thedig from './thedig';
75
import ThedigApi from './thedig/client';
86
import Voilanorbert from './voilanorbert';
97
import VoilanorbertApi from './voilanorbert/client';
108
import logger from '../../utils/logger';
119
import { TokenBucketRateLimiter } from '../rate-limiter/RateLimiter';
10+
import EnrichLayerAPI from './enrich-layer/client';
11+
import EnrichLayer from './enrich-layer';
1212

1313
let ENGINE_THEDIG: Engine | undefined;
1414
let ENGINE_VOILANORBERT: Engine | undefined;
15-
let ENGINE_PROXY_CURL: Engine | undefined;
15+
let ENGINE_ENRICH_LAYER: Engine | undefined;
1616

1717
if (
1818
ENV.VOILANORBERT_API_KEY &&
@@ -47,12 +47,12 @@ if (ENV.THEDIG_API_KEY && ENV.THEDIG_URL) {
4747
);
4848
}
4949

50-
if (ENV.PROXYCURL_API_KEY && ENV.PROXYCURL_URL) {
51-
ENGINE_PROXY_CURL = new Proxycurl(
52-
new ProxycurlApi(
50+
if (ENV.ENRICH_LAYER_API_KEY && ENV.ENRICH_LAYER_URL) {
51+
ENGINE_ENRICH_LAYER = new EnrichLayer(
52+
new EnrichLayerAPI(
5353
{
54-
url: ENV.PROXYCURL_URL,
55-
apiKey: ENV.PROXYCURL_API_KEY,
54+
url: ENV.ENRICH_LAYER_URL,
55+
apiKey: ENV.ENRICH_LAYER_API_KEY,
5656
rateLimiter: new TokenBucketRateLimiter(295, 60 * 1000)
5757
},
5858
logger
@@ -62,7 +62,7 @@ if (ENV.PROXYCURL_API_KEY && ENV.PROXYCURL_URL) {
6262
}
6363

6464
const EnrichmentService = new Enricher(
65-
[ENGINE_THEDIG, ENGINE_PROXY_CURL, ENGINE_VOILANORBERT].filter(
65+
[ENGINE_THEDIG, ENGINE_ENRICH_LAYER, ENGINE_VOILANORBERT].filter(
6666
(engine): engine is Engine => Boolean(engine)
6767
),
6868
logger

0 commit comments

Comments
 (0)