chore: import upstream snapshot with attribution
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:20:55 +08:00
commit d25d482dc2
13754 changed files with 4996608 additions and 0 deletions
+55
View File
@@ -0,0 +1,55 @@
import type { EnrichCheckCreditsParams, EnrichCheckCreditsResponse } from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const checkCreditsTool: ToolConfig<EnrichCheckCreditsParams, EnrichCheckCreditsResponse> = {
id: 'enrich_check_credits',
name: 'Enrich Check Credits',
description: 'Check your Enrich API credit usage and remaining balance.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
},
request: {
url: 'https://api.enrich.so/v1/api/auth',
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: {
totalCredits: data.total_credits ?? 0,
creditsUsed: data.credits_used ?? 0,
creditsRemaining: data.credits_remaining ?? 0,
},
}
},
outputs: {
totalCredits: {
type: 'number',
description: 'Total credits allocated to the account',
},
creditsUsed: {
type: 'number',
description: 'Credits consumed so far',
},
creditsRemaining: {
type: 'number',
description: 'Available credits remaining',
},
},
}
+143
View File
@@ -0,0 +1,143 @@
import type { EnrichCompanyFundingParams, EnrichCompanyFundingResponse } from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const companyFundingTool: ToolConfig<
EnrichCompanyFundingParams,
EnrichCompanyFundingResponse
> = {
id: 'enrich_company_funding',
name: 'Enrich Company Funding',
description:
'Retrieve company funding history, traffic metrics, and executive information by domain.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
domain: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Company domain (e.g., example.com)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/company-funding-plus')
url.searchParams.append('domain', params.domain.trim())
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const resultData = data.data ?? data
const fundingRounds =
(resultData.fundingRounds ?? resultData.funding_rounds)?.map((round: any) => ({
roundType: round.roundType ?? round.round_type ?? '',
amount: round.amount ?? null,
date: round.date ?? null,
investors: round.investors ?? [],
})) ?? []
const executives = (resultData.executives ?? []).map((exec: any) => ({
name: exec.name ?? exec.fullName ?? '',
title: exec.title ?? '',
}))
return {
success: true,
output: {
legalName: resultData.legalName ?? resultData.legal_name ?? null,
employeeCount: resultData.employeeCount ?? resultData.employee_count ?? null,
headquarters: resultData.headquarters ?? null,
industry: resultData.industry ?? null,
totalFundingRaised:
resultData.totalFundingRaised ?? resultData.total_funding_raised ?? null,
fundingRounds,
monthlyVisits: resultData.monthlyVisits ?? resultData.monthly_visits ?? null,
trafficChange: resultData.trafficChange ?? resultData.traffic_change ?? null,
itSpending: resultData.itSpending ?? resultData.it_spending ?? null,
executives,
},
}
},
outputs: {
legalName: {
type: 'string',
description: 'Legal company name',
optional: true,
},
employeeCount: {
type: 'number',
description: 'Number of employees',
optional: true,
},
headquarters: {
type: 'string',
description: 'Headquarters location',
optional: true,
},
industry: {
type: 'string',
description: 'Industry',
optional: true,
},
totalFundingRaised: {
type: 'number',
description: 'Total funding raised',
optional: true,
},
fundingRounds: {
type: 'array',
description: 'Funding rounds',
items: {
type: 'object',
properties: {
roundType: { type: 'string', description: 'Round type' },
amount: { type: 'number', description: 'Amount raised' },
date: { type: 'string', description: 'Date' },
investors: { type: 'array', description: 'Investors' },
},
},
},
monthlyVisits: {
type: 'number',
description: 'Monthly website visits',
optional: true,
},
trafficChange: {
type: 'number',
description: 'Traffic change percentage',
optional: true,
},
itSpending: {
type: 'number',
description: 'Estimated IT spending in USD',
optional: true,
},
executives: {
type: 'array',
description: 'Executive team',
items: {
type: 'object',
properties: {
name: { type: 'string', description: 'Name' },
title: { type: 'string', description: 'Title' },
},
},
},
},
}
+197
View File
@@ -0,0 +1,197 @@
import type { EnrichCompanyLookupParams, EnrichCompanyLookupResponse } from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const companyLookupTool: ToolConfig<EnrichCompanyLookupParams, EnrichCompanyLookupResponse> =
{
id: 'enrich_company_lookup',
name: 'Enrich Company Lookup',
description:
'Look up comprehensive company information by name or domain including funding, location, and social profiles.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
name: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Company name (e.g., Google)',
},
domain: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Company domain (e.g., google.com)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/company')
if (params.name) {
url.searchParams.append('name', params.name.trim())
}
if (params.domain) {
url.searchParams.append('domain', params.domain.trim())
}
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const fundingRounds =
data.fundingData?.map((round: any) => ({
roundType: round.fundingRound ?? '',
amount: round.moneyRaised?.amount ?? null,
currency: round.moneyRaised?.currency ?? null,
investors: round.investors ?? [],
})) ?? []
return {
success: true,
output: {
name: data.name ?? null,
universalName: data.universal_name ?? null,
companyId: data.company_id ?? null,
description: data.description ?? null,
phone: data.phone ?? null,
linkedInUrl: data.url ?? null,
websiteUrl: data.website ?? null,
followers: data.followers ?? null,
staffCount: data.staffCount ?? null,
foundedDate: data.founded ?? null,
type: data.type ?? null,
industries: data.industries ?? [],
specialties: data.specialities ?? [],
headquarters: {
city: data.headquarter?.city ?? null,
country: data.headquarter?.country ?? null,
postalCode: data.headquarter?.postalCode ?? null,
line1: data.headquarter?.line1 ?? null,
},
logo: data.logo ?? null,
coverImage: data.cover ?? null,
fundingRounds,
},
}
},
outputs: {
name: {
type: 'string',
description: 'Company name',
optional: true,
},
universalName: {
type: 'string',
description: 'Universal company name',
optional: true,
},
companyId: {
type: 'string',
description: 'Company ID',
optional: true,
},
description: {
type: 'string',
description: 'Company description',
optional: true,
},
phone: {
type: 'string',
description: 'Phone number',
optional: true,
},
linkedInUrl: {
type: 'string',
description: 'LinkedIn company URL',
optional: true,
},
websiteUrl: {
type: 'string',
description: 'Company website',
optional: true,
},
followers: {
type: 'number',
description: 'Number of LinkedIn followers',
optional: true,
},
staffCount: {
type: 'number',
description: 'Number of employees',
optional: true,
},
foundedDate: {
type: 'string',
description: 'Date founded',
optional: true,
},
type: {
type: 'string',
description: 'Company type',
optional: true,
},
industries: {
type: 'array',
description: 'Industries',
items: {
type: 'string',
description: 'Industry',
},
},
specialties: {
type: 'array',
description: 'Company specialties',
items: {
type: 'string',
description: 'Specialty',
},
},
headquarters: {
type: 'json',
description: 'Headquarters location',
properties: {
city: { type: 'string', description: 'City' },
country: { type: 'string', description: 'Country' },
postalCode: { type: 'string', description: 'Postal code' },
line1: { type: 'string', description: 'Address line 1' },
},
},
logo: {
type: 'string',
description: 'Company logo URL',
optional: true,
},
coverImage: {
type: 'string',
description: 'Cover image URL',
optional: true,
},
fundingRounds: {
type: 'array',
description: 'Funding history',
items: {
type: 'object',
properties: {
roundType: { type: 'string', description: 'Funding round type' },
amount: { type: 'number', description: 'Amount raised' },
currency: { type: 'string', description: 'Currency' },
investors: { type: 'array', description: 'Investors' },
},
},
},
},
}
+215
View File
@@ -0,0 +1,215 @@
import type { EnrichCompanyRevenueParams, EnrichCompanyRevenueResponse } from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const companyRevenueTool: ToolConfig<
EnrichCompanyRevenueParams,
EnrichCompanyRevenueResponse
> = {
id: 'enrich_company_revenue',
name: 'Enrich Company Revenue',
description:
'Retrieve company revenue data, CEO information, and competitive analysis by domain.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
domain: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Company domain (e.g., clay.io)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/company-revenue-plus')
url.searchParams.append('domain', params.domain.trim())
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const competitors =
data.competitors?.map((comp: any) => ({
name: comp.name ?? '',
revenue: comp.revenue ?? null,
employeeCount: comp.employee_count ?? comp.employeeCount ?? null,
headquarters: comp.headquarters ?? null,
})) ?? []
// Handle socialLinks as array [{type, url}] or object {linkedIn, twitter, facebook}
const socialLinksArray = data.socialLinks ?? data.social_links
let socialLinks = {
linkedIn: null as string | null,
twitter: null as string | null,
facebook: null as string | null,
}
if (Array.isArray(socialLinksArray)) {
for (const link of socialLinksArray) {
const linkType = (link.type ?? '').toLowerCase()
if (linkType === 'linkedin') socialLinks.linkedIn = link.url ?? null
else if (linkType === 'twitter') socialLinks.twitter = link.url ?? null
else if (linkType === 'facebook') socialLinks.facebook = link.url ?? null
}
} else if (socialLinksArray && typeof socialLinksArray === 'object') {
socialLinks = {
linkedIn: socialLinksArray.linkedIn ?? socialLinksArray.linkedin ?? null,
twitter: socialLinksArray.twitter ?? null,
facebook: socialLinksArray.facebook ?? null,
}
}
// Handle fundingRounds as array or number
const fundingRoundsData = data.fundingRounds ?? data.funding_rounds
const fundingRoundsCount = Array.isArray(fundingRoundsData)
? fundingRoundsData.length
: fundingRoundsData
// Handle revenueDetails array for min/max
const revenueDetails = data.revenueDetails ?? data.revenue_details
let revenueMin = data.revenueMin ?? data.revenue_min ?? null
let revenueMax = data.revenueMax ?? data.revenue_max ?? null
if (Array.isArray(revenueDetails) && revenueDetails.length > 0) {
revenueMin = revenueDetails[0]?.rangeBegin ?? revenueDetails[0]?.range_begin ?? revenueMin
revenueMax = revenueDetails[0]?.rangeEnd ?? revenueDetails[0]?.range_end ?? revenueMax
}
return {
success: true,
output: {
companyName: data.companyName ?? data.company_name ?? null,
shortDescription: data.shortDescription ?? data.short_description ?? null,
fullSummary: data.fullSummary ?? data.full_summary ?? null,
revenue: data.revenue ?? null,
revenueMin,
revenueMax,
employeeCount: data.employeeCount ?? data.employee_count ?? null,
founded: data.founded ?? null,
ownership: data.ownership ?? null,
status: data.status ?? null,
website: data.website ?? null,
ceo: {
name: data.ceo?.fullName ?? data.ceo?.name ?? null,
designation: data.ceo?.designation ?? data.ceo?.title ?? null,
rating: data.ceo?.rating ?? null,
},
socialLinks,
totalFunding: data.totalFunding ?? data.total_funding ?? null,
fundingRounds: fundingRoundsCount ?? null,
competitors,
},
}
},
outputs: {
companyName: {
type: 'string',
description: 'Company name',
optional: true,
},
shortDescription: {
type: 'string',
description: 'Short company description',
optional: true,
},
fullSummary: {
type: 'string',
description: 'Full company summary',
optional: true,
},
revenue: {
type: 'string',
description: 'Company revenue',
optional: true,
},
revenueMin: {
type: 'number',
description: 'Minimum revenue estimate',
optional: true,
},
revenueMax: {
type: 'number',
description: 'Maximum revenue estimate',
optional: true,
},
employeeCount: {
type: 'number',
description: 'Number of employees',
optional: true,
},
founded: {
type: 'string',
description: 'Year founded',
optional: true,
},
ownership: {
type: 'string',
description: 'Ownership type',
optional: true,
},
status: {
type: 'string',
description: 'Company status (e.g., Active)',
optional: true,
},
website: {
type: 'string',
description: 'Company website URL',
optional: true,
},
ceo: {
type: 'json',
description: 'CEO information',
properties: {
name: { type: 'string', description: 'CEO name' },
designation: { type: 'string', description: 'CEO designation/title' },
rating: { type: 'number', description: 'CEO rating' },
},
},
socialLinks: {
type: 'json',
description: 'Social media links',
properties: {
linkedIn: { type: 'string', description: 'LinkedIn URL' },
twitter: { type: 'string', description: 'Twitter URL' },
facebook: { type: 'string', description: 'Facebook URL' },
},
},
totalFunding: {
type: 'string',
description: 'Total funding raised',
optional: true,
},
fundingRounds: {
type: 'number',
description: 'Number of funding rounds',
optional: true,
},
competitors: {
type: 'array',
description: 'Competitors',
items: {
type: 'object',
properties: {
name: { type: 'string', description: 'Competitor name' },
revenue: { type: 'string', description: 'Revenue' },
employeeCount: { type: 'number', description: 'Employee count' },
headquarters: { type: 'string', description: 'Headquarters' },
},
},
},
},
}
@@ -0,0 +1,102 @@
import type {
EnrichDisposableEmailCheckParams,
EnrichDisposableEmailCheckResponse,
} from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const disposableEmailCheckTool: ToolConfig<
EnrichDisposableEmailCheckParams,
EnrichDisposableEmailCheckResponse
> = {
id: 'enrich_disposable_email_check',
name: 'Enrich Disposable Email Check',
description:
'Check if an email address is from a disposable or temporary email provider. Returns a score and validation details.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
email: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Email address to check (e.g., john.doe@example.com)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/disposable-email-check')
url.searchParams.append('email', params.email.trim())
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const emailData = data.data ?? {}
return {
success: true,
output: {
email: emailData.email ?? '',
score: emailData.score ?? 0,
testsPassed: emailData.tests_passed ?? '0/0',
passed: emailData.passed ?? false,
reason: emailData.reason ?? null,
mailServerIp: emailData.mail_server_ip ?? null,
mxRecords: emailData.mx_records ?? [],
},
}
},
outputs: {
email: {
type: 'string',
description: 'Email address checked',
},
score: {
type: 'number',
description: 'Validation score (0-100)',
},
testsPassed: {
type: 'string',
description: 'Number of tests passed (e.g., "3/3")',
},
passed: {
type: 'boolean',
description: 'Whether the email passed all validation tests',
},
reason: {
type: 'string',
description: 'Reason for failure if email did not pass',
optional: true,
},
mailServerIp: {
type: 'string',
description: 'Mail server IP address',
optional: true,
},
mxRecords: {
type: 'array',
description: 'MX records for the domain',
items: {
type: 'object',
properties: {
host: { type: 'string', description: 'MX record host' },
pref: { type: 'number', description: 'MX record preference' },
},
},
},
},
}
+67
View File
@@ -0,0 +1,67 @@
import type { EnrichEmailToIpParams, EnrichEmailToIpResponse } from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const emailToIpTool: ToolConfig<EnrichEmailToIpParams, EnrichEmailToIpResponse> = {
id: 'enrich_email_to_ip',
name: 'Enrich Email to IP',
description: 'Discover an IP address associated with an email address.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
email: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Email address to look up (e.g., john.doe@example.com)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/email-to-ip')
url.searchParams.append('email', params.email.trim())
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const ipData = data.data ?? {}
return {
success: true,
output: {
email: ipData.email ?? '',
ip: ipData.ip ?? null,
found: !!ipData.ip,
},
}
},
outputs: {
email: {
type: 'string',
description: 'Email address looked up',
},
ip: {
type: 'string',
description: 'Associated IP address',
optional: true,
},
found: {
type: 'boolean',
description: 'Whether an IP address was found',
},
},
}
@@ -0,0 +1,177 @@
import type {
EnrichEmailToPersonLiteParams,
EnrichEmailToPersonLiteResponse,
} from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const emailToPersonLiteTool: ToolConfig<
EnrichEmailToPersonLiteParams,
EnrichEmailToPersonLiteResponse
> = {
id: 'enrich_email_to_person_lite',
name: 'Enrich Email to Person Lite',
description:
'Retrieve basic LinkedIn profile information from an email address. A lighter version with essential data only.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
email: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Email address to look up (e.g., john.doe@company.com)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/email-to-linkedin-lite')
url.searchParams.append('email', params.email.trim())
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: {
name: data.name ?? null,
firstName: data.first_name ?? data.firstName ?? null,
lastName: data.last_name ?? data.lastName ?? null,
email: data.email ?? null,
title: data.title ?? null,
location: data.location ?? null,
company: data.company ?? null,
companyLocation: data.company_location ?? data.companyLocation ?? null,
companyLinkedIn: data.company_linkedin ?? data.companyLinkedIn ?? null,
profileId: data.profile_id ?? data.profileId ?? null,
schoolName: data.school_name ?? data.schoolName ?? null,
schoolUrl: data.school_url ?? data.schoolUrl ?? null,
linkedInUrl: data.linkedin_url ?? data.linkedInUrl ?? null,
photoUrl: data.photo_url ?? data.photoUrl ?? null,
followerCount: data.follower_count ?? data.followerCount ?? null,
connectionCount: data.connection_count ?? data.connectionCount ?? null,
languages: data.languages ?? [],
projects: data.projects ?? [],
certifications: data.certifications ?? [],
volunteerExperience: data.volunteer_experience ?? data.volunteerExperience ?? [],
},
}
},
outputs: {
name: {
type: 'string',
description: 'Full name',
optional: true,
},
firstName: {
type: 'string',
description: 'First name',
optional: true,
},
lastName: {
type: 'string',
description: 'Last name',
optional: true,
},
email: {
type: 'string',
description: 'Email address',
optional: true,
},
title: {
type: 'string',
description: 'Job title',
optional: true,
},
location: {
type: 'string',
description: 'Location',
optional: true,
},
company: {
type: 'string',
description: 'Current company',
optional: true,
},
companyLocation: {
type: 'string',
description: 'Company location',
optional: true,
},
companyLinkedIn: {
type: 'string',
description: 'Company LinkedIn URL',
optional: true,
},
profileId: {
type: 'string',
description: 'LinkedIn profile ID',
optional: true,
},
schoolName: {
type: 'string',
description: 'School name',
optional: true,
},
schoolUrl: {
type: 'string',
description: 'School URL',
optional: true,
},
linkedInUrl: {
type: 'string',
description: 'LinkedIn profile URL',
optional: true,
},
photoUrl: {
type: 'string',
description: 'Profile photo URL',
optional: true,
},
followerCount: {
type: 'number',
description: 'Number of followers',
optional: true,
},
connectionCount: {
type: 'number',
description: 'Number of connections',
optional: true,
},
languages: {
type: 'array',
description: 'Languages spoken',
items: { type: 'string', description: 'Language' },
},
projects: {
type: 'array',
description: 'Projects',
items: { type: 'string', description: 'Project' },
},
certifications: {
type: 'array',
description: 'Certifications',
items: { type: 'string', description: 'Certification' },
},
volunteerExperience: {
type: 'array',
description: 'Volunteer experience',
items: { type: 'string', description: 'Volunteer role' },
},
},
}
+86
View File
@@ -0,0 +1,86 @@
import type { EnrichEmailToPhoneParams, EnrichEmailToPhoneResponse } from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const emailToPhoneTool: ToolConfig<EnrichEmailToPhoneParams, EnrichEmailToPhoneResponse> = {
id: 'enrich_email_to_phone',
name: 'Enrich Email to Phone',
description: 'Find a phone number associated with an email address.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
email: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Email address to look up (e.g., john.doe@example.com)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/email-to-mobile')
url.searchParams.append('email', params.email.trim())
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
// Handle queued response (202)
if (data.message?.includes('queued')) {
return {
success: true,
output: {
email: null,
mobileNumber: null,
found: false,
status: 'in_progress',
},
}
}
return {
success: true,
output: {
email: data.data?.email ?? null,
mobileNumber: data.data?.mobile_number ?? null,
found: !!data.data?.mobile_number,
status: 'completed',
},
}
},
outputs: {
email: {
type: 'string',
description: 'Email address looked up',
optional: true,
},
mobileNumber: {
type: 'string',
description: 'Found mobile phone number',
optional: true,
},
found: {
type: 'boolean',
description: 'Whether a phone number was found',
},
status: {
type: 'string',
description: 'Request status (in_progress or completed)',
optional: true,
},
},
}
+239
View File
@@ -0,0 +1,239 @@
import type { EnrichEmailToProfileParams, EnrichEmailToProfileResponse } from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const emailToProfileTool: ToolConfig<
EnrichEmailToProfileParams,
EnrichEmailToProfileResponse
> = {
id: 'enrich_email_to_profile',
name: 'Enrich Email to Profile',
description:
'Retrieve detailed LinkedIn profile information using an email address including work history, education, and skills.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
email: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Email address to look up (e.g., john.doe@company.com)',
},
inRealtime: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Set to true to retrieve fresh data, bypassing cached information',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/person')
url.searchParams.append('email', params.email.trim())
if (params.inRealtime !== undefined) {
url.searchParams.append('in_realtime', String(params.inRealtime))
}
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
// API returns positions nested under data.positions.positionHistory
const positionHistory =
data.positions?.positionHistory?.map((pos: any) => ({
title: pos.title ?? '',
company: pos.company?.companyName ?? '',
startDate: pos.startEndDate?.start
? `${pos.startEndDate.start.year}-${pos.startEndDate.start.month ?? 1}`
: null,
endDate: pos.startEndDate?.end
? `${pos.startEndDate.end.year}-${pos.startEndDate.end.month ?? 1}`
: null,
location: pos.company?.companyLocation ?? null,
})) ?? []
// API returns education nested under data.schools.educationHistory
const education =
data.schools?.educationHistory?.map((edu: any) => ({
school: edu.school?.schoolName ?? '',
degree: edu.degreeName ?? null,
fieldOfStudy: edu.fieldOfStudy ?? null,
startDate: edu.startEndDate?.start?.year ? String(edu.startEndDate.start.year) : null,
endDate: edu.startEndDate?.end?.year ? String(edu.startEndDate.end.year) : null,
})) ?? []
const certifications =
data.certifications?.map((cert: any) => ({
name: cert.name ?? '',
authority: cert.authority ?? null,
url: cert.url ?? null,
})) ?? []
return {
success: true,
output: {
displayName: data.displayName ?? null,
firstName: data.firstName ?? null,
lastName: data.lastName ?? null,
headline: data.headline ?? null,
occupation: data.occupation ?? null,
summary: data.summary ?? null,
location: data.location ?? null,
country: data.country ?? null,
linkedInUrl: data.linkedInUrl ?? null,
photoUrl: data.photoUrl ?? null,
connectionCount: data.connectionCount ?? null,
isConnectionCountObfuscated: data.isConnectionCountObfuscated ?? null,
positionHistory,
education,
certifications,
skills: data.skills ?? [],
languages: data.languages ?? [],
locale: data.locale ?? null,
version: data.version ?? null,
},
}
},
outputs: {
displayName: {
type: 'string',
description: 'Full display name',
optional: true,
},
firstName: {
type: 'string',
description: 'First name',
optional: true,
},
lastName: {
type: 'string',
description: 'Last name',
optional: true,
},
headline: {
type: 'string',
description: 'Professional headline',
optional: true,
},
occupation: {
type: 'string',
description: 'Current occupation',
optional: true,
},
summary: {
type: 'string',
description: 'Profile summary',
optional: true,
},
location: {
type: 'string',
description: 'Location',
optional: true,
},
country: {
type: 'string',
description: 'Country',
optional: true,
},
linkedInUrl: {
type: 'string',
description: 'LinkedIn profile URL',
optional: true,
},
photoUrl: {
type: 'string',
description: 'Profile photo URL',
optional: true,
},
connectionCount: {
type: 'number',
description: 'Number of connections',
optional: true,
},
isConnectionCountObfuscated: {
type: 'boolean',
description: 'Whether connection count is obfuscated (500+)',
optional: true,
},
positionHistory: {
type: 'array',
description: 'Work experience history',
items: {
type: 'object',
properties: {
title: { type: 'string', description: 'Job title' },
company: { type: 'string', description: 'Company name' },
startDate: { type: 'string', description: 'Start date' },
endDate: { type: 'string', description: 'End date' },
location: { type: 'string', description: 'Location' },
},
},
},
education: {
type: 'array',
description: 'Education history',
items: {
type: 'object',
properties: {
school: { type: 'string', description: 'School name' },
degree: { type: 'string', description: 'Degree' },
fieldOfStudy: { type: 'string', description: 'Field of study' },
startDate: { type: 'string', description: 'Start date' },
endDate: { type: 'string', description: 'End date' },
},
},
},
certifications: {
type: 'array',
description: 'Professional certifications',
items: {
type: 'object',
properties: {
name: { type: 'string', description: 'Certification name' },
authority: { type: 'string', description: 'Issuing authority' },
url: { type: 'string', description: 'Certification URL' },
},
},
},
skills: {
type: 'array',
description: 'List of skills',
items: {
type: 'string',
description: 'Skill',
},
},
languages: {
type: 'array',
description: 'List of languages',
items: {
type: 'string',
description: 'Language',
},
},
locale: {
type: 'string',
description: 'Profile locale (e.g., en_US)',
optional: true,
},
version: {
type: 'number',
description: 'Profile version number',
optional: true,
},
},
}
+107
View File
@@ -0,0 +1,107 @@
import type { EnrichFindEmailParams, EnrichFindEmailResponse } from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const findEmailTool: ToolConfig<EnrichFindEmailParams, EnrichFindEmailResponse> = {
id: 'enrich_find_email',
name: 'Enrich Find Email',
description: "Find a person's work email address using their full name and company domain.",
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
fullName: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: "Person's full name (e.g., John Doe)",
},
companyDomain: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Company domain (e.g., example.com)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/find-email')
url.searchParams.append('fullName', params.fullName.trim())
url.searchParams.append('companyDomain', params.companyDomain.trim())
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
// Handle queued response (202)
if (data.status === 'in_progress' || data.message?.includes('queued')) {
return {
success: true,
output: {
email: null,
firstName: null,
lastName: null,
domain: null,
found: false,
acceptAll: null,
},
}
}
return {
success: true,
output: {
email: data.email ?? null,
firstName: data.firstName ?? null,
lastName: data.lastName ?? null,
domain: data.domain ?? null,
found: data.found ?? false,
acceptAll: data.acceptAll ?? null,
},
}
},
outputs: {
email: {
type: 'string',
description: 'Found email address',
optional: true,
},
firstName: {
type: 'string',
description: 'First name',
optional: true,
},
lastName: {
type: 'string',
description: 'Last name',
optional: true,
},
domain: {
type: 'string',
description: 'Company domain',
optional: true,
},
found: {
type: 'boolean',
description: 'Whether an email was found',
},
acceptAll: {
type: 'boolean',
description: 'Whether the domain accepts all emails',
optional: true,
},
},
}
+116
View File
@@ -0,0 +1,116 @@
import type { EnrichGetPostDetailsParams, EnrichGetPostDetailsResponse } from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const getPostDetailsTool: ToolConfig<
EnrichGetPostDetailsParams,
EnrichGetPostDetailsResponse
> = {
id: 'enrich_get_post_details',
name: 'Enrich Get Post Details',
description: 'Get detailed information about a LinkedIn post by URL.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
url: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'LinkedIn post URL',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/post-details')
url.searchParams.append('url', params.url.trim())
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
Accept: 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: {
postId: data.PostId ?? null,
author: {
name: data.author?.name ?? null,
headline: data.author?.headline ?? null,
linkedInUrl: data.author?.linkedin_url ?? null,
profileImage: data.author?.profile_image ?? null,
},
timestamp: data.post?.timestamp ?? null,
textContent: data.post?.text_content ?? null,
hashtags: data.post?.hashtags ?? [],
mediaUrls: data.post?.post_media_url ?? [],
reactions: data.engagement?.reactions ?? 0,
commentsCount: data.engagement?.comments_count ?? 0,
},
}
},
outputs: {
postId: {
type: 'string',
description: 'Post ID',
optional: true,
},
author: {
type: 'json',
description: 'Author information',
properties: {
name: { type: 'string', description: 'Author name' },
headline: { type: 'string', description: 'Author headline' },
linkedInUrl: { type: 'string', description: 'Author LinkedIn URL' },
profileImage: { type: 'string', description: 'Author profile image' },
},
},
timestamp: {
type: 'string',
description: 'Post timestamp',
optional: true,
},
textContent: {
type: 'string',
description: 'Post text content',
optional: true,
},
hashtags: {
type: 'array',
description: 'Hashtags',
items: {
type: 'string',
description: 'Hashtag',
},
},
mediaUrls: {
type: 'array',
description: 'Media URLs',
items: {
type: 'string',
description: 'Media URL',
},
},
reactions: {
type: 'number',
description: 'Number of reactions',
},
commentsCount: {
type: 'number',
description: 'Number of comments',
},
},
}
+65
View File
@@ -0,0 +1,65 @@
import { checkCreditsTool } from '@/tools/enrich/check_credits'
import { companyFundingTool } from '@/tools/enrich/company_funding'
import { companyLookupTool } from '@/tools/enrich/company_lookup'
import { companyRevenueTool } from '@/tools/enrich/company_revenue'
import { disposableEmailCheckTool } from '@/tools/enrich/disposable_email_check'
import { emailToIpTool } from '@/tools/enrich/email_to_ip'
import { emailToPersonLiteTool } from '@/tools/enrich/email_to_person_lite'
import { emailToPhoneTool } from '@/tools/enrich/email_to_phone'
import { emailToProfileTool } from '@/tools/enrich/email_to_profile'
import { findEmailTool } from '@/tools/enrich/find_email'
import { getPostDetailsTool } from '@/tools/enrich/get_post_details'
import { ipToCompanyTool } from '@/tools/enrich/ip_to_company'
import { linkedInProfileTool } from '@/tools/enrich/linkedin_profile'
import { linkedInToPersonalEmailTool } from '@/tools/enrich/linkedin_to_personal_email'
import { linkedInToWorkEmailTool } from '@/tools/enrich/linkedin_to_work_email'
import { phoneFinderTool } from '@/tools/enrich/phone_finder'
import { reverseHashLookupTool } from '@/tools/enrich/reverse_hash_lookup'
import { salesPointerPeopleTool } from '@/tools/enrich/sales_pointer_people'
import { searchCompanyTool } from '@/tools/enrich/search_company'
import { searchCompanyActivitiesTool } from '@/tools/enrich/search_company_activities'
import { searchCompanyEmployeesTool } from '@/tools/enrich/search_company_employees'
import { searchJobsTool } from '@/tools/enrich/search_jobs'
import { searchLogoTool } from '@/tools/enrich/search_logo'
import { searchPeopleTool } from '@/tools/enrich/search_people'
import { searchPeopleActivitiesTool } from '@/tools/enrich/search_people_activities'
import { searchPostCommentsTool } from '@/tools/enrich/search_post_comments'
import { searchPostCommentsByUrlTool } from '@/tools/enrich/search_post_comments_by_url'
import { searchPostReactionsTool } from '@/tools/enrich/search_post_reactions'
import { searchPostReactionsByUrlTool } from '@/tools/enrich/search_post_reactions_by_url'
import { searchPostsTool } from '@/tools/enrich/search_posts'
import { searchSimilarCompaniesTool } from '@/tools/enrich/search_similar_companies'
import { verifyEmailTool } from '@/tools/enrich/verify_email'
export const enrichCheckCreditsTool = checkCreditsTool
export const enrichEmailToProfileTool = emailToProfileTool
export const enrichEmailToPersonLiteTool = emailToPersonLiteTool
export const enrichLinkedInProfileTool = linkedInProfileTool
export const enrichFindEmailTool = findEmailTool
export const enrichLinkedInToWorkEmailTool = linkedInToWorkEmailTool
export const enrichLinkedInToPersonalEmailTool = linkedInToPersonalEmailTool
export const enrichPhoneFinderTool = phoneFinderTool
export const enrichEmailToPhoneTool = emailToPhoneTool
export const enrichVerifyEmailTool = verifyEmailTool
export const enrichDisposableEmailCheckTool = disposableEmailCheckTool
export const enrichEmailToIpTool = emailToIpTool
export const enrichIpToCompanyTool = ipToCompanyTool
export const enrichCompanyLookupTool = companyLookupTool
export const enrichCompanyFundingTool = companyFundingTool
export const enrichCompanyRevenueTool = companyRevenueTool
export const enrichSearchPeopleTool = searchPeopleTool
export const enrichSearchCompanyTool = searchCompanyTool
export const enrichSearchCompanyEmployeesTool = searchCompanyEmployeesTool
export const enrichSearchSimilarCompaniesTool = searchSimilarCompaniesTool
export const enrichSalesPointerPeopleTool = salesPointerPeopleTool
export const enrichSearchPostsTool = searchPostsTool
export const enrichGetPostDetailsTool = getPostDetailsTool
export const enrichSearchPostReactionsTool = searchPostReactionsTool
export const enrichSearchPostReactionsByUrlTool = searchPostReactionsByUrlTool
export const enrichSearchPostCommentsTool = searchPostCommentsTool
export const enrichSearchPostCommentsByUrlTool = searchPostCommentsByUrlTool
export const enrichSearchJobsTool = searchJobsTool
export const enrichSearchPeopleActivitiesTool = searchPeopleActivitiesTool
export const enrichSearchCompanyActivitiesTool = searchCompanyActivitiesTool
export const enrichReverseHashLookupTool = reverseHashLookupTool
export const enrichSearchLogoTool = searchLogoTool
+148
View File
@@ -0,0 +1,148 @@
import type { EnrichIpToCompanyParams, EnrichIpToCompanyResponse } from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const ipToCompanyTool: ToolConfig<EnrichIpToCompanyParams, EnrichIpToCompanyResponse> = {
id: 'enrich_ip_to_company',
name: 'Enrich IP to Company',
description: 'Identify a company from an IP address with detailed firmographic information.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
ip: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'IP address to look up (e.g., 86.92.60.221)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/ip-to-company-lookup')
url.searchParams.append('ip', params.ip.trim())
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const companyData = data.data ?? {}
return {
success: true,
output: {
name: companyData.name ?? null,
legalName: companyData.legalName ?? null,
domain: companyData.domain ?? null,
domainAliases: companyData.domainAliases ?? [],
sector: companyData.sector ?? null,
industry: companyData.industry ?? null,
phone: companyData.phone ?? null,
employees: companyData.employees ?? null,
revenue: companyData.revenue ?? null,
location: {
city: companyData.geo?.city ?? null,
state: companyData.geo?.state ?? null,
country: companyData.geo?.country ?? null,
timezone: companyData.timezone ?? null,
},
linkedInUrl: companyData.linkedin?.handle
? `https://linkedin.com/company/${companyData.linkedin.handle}`
: null,
twitterUrl: companyData.twitter?.handle
? `https://twitter.com/${companyData.twitter.handle}`
: null,
facebookUrl: companyData.facebook?.handle
? `https://facebook.com/${companyData.facebook.handle}`
: null,
},
}
},
outputs: {
name: {
type: 'string',
description: 'Company name',
optional: true,
},
legalName: {
type: 'string',
description: 'Legal company name',
optional: true,
},
domain: {
type: 'string',
description: 'Primary domain',
optional: true,
},
domainAliases: {
type: 'array',
description: 'Domain aliases',
items: {
type: 'string',
description: 'Domain alias',
},
},
sector: {
type: 'string',
description: 'Business sector',
optional: true,
},
industry: {
type: 'string',
description: 'Industry',
optional: true,
},
phone: {
type: 'string',
description: 'Phone number',
optional: true,
},
employees: {
type: 'number',
description: 'Number of employees',
optional: true,
},
revenue: {
type: 'string',
description: 'Estimated revenue',
optional: true,
},
location: {
type: 'json',
description: 'Company location',
properties: {
city: { type: 'string', description: 'City' },
state: { type: 'string', description: 'State' },
country: { type: 'string', description: 'Country' },
timezone: { type: 'string', description: 'Timezone' },
},
},
linkedInUrl: {
type: 'string',
description: 'LinkedIn company URL',
optional: true,
},
twitterUrl: {
type: 'string',
description: 'Twitter URL',
optional: true,
},
facebookUrl: {
type: 'string',
description: 'Facebook URL',
optional: true,
},
},
}
+190
View File
@@ -0,0 +1,190 @@
import type {
EnrichLinkedInProfileParams,
EnrichLinkedInProfileResponse,
} from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const linkedInProfileTool: ToolConfig<
EnrichLinkedInProfileParams,
EnrichLinkedInProfileResponse
> = {
id: 'enrich_linkedin_profile',
name: 'Enrich LinkedIn Profile',
description:
'Enrich a LinkedIn profile URL with detailed information including positions, education, and social metrics.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
url: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'LinkedIn profile URL (e.g., linkedin.com/in/williamhgates)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/linkedin-by-url')
url.searchParams.append('url', params.url.trim())
url.searchParams.append('type', 'person')
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const positions =
data.position_groups?.flatMap(
(group: any) =>
group.profile_positions?.map((pos: any) => ({
title: pos.title ?? '',
company: group.company?.name ?? pos.company ?? '',
companyLogo: group.company?.logo ?? null,
startDate: pos.start_date ?? null,
endDate: pos.end_date ?? null,
location: pos.location ?? null,
})) ?? []
) ?? []
const education =
data.education?.map((edu: any) => ({
school: edu.school?.name ?? edu.school_name ?? '',
degree: edu.degree_name ?? edu.degree ?? null,
fieldOfStudy: edu.field_of_study ?? null,
startDate: edu.start_date ?? null,
endDate: edu.end_date ?? null,
})) ?? []
return {
success: true,
output: {
profileId: data.profile_id ?? null,
firstName: data.first_name ?? null,
lastName: data.last_name ?? null,
subTitle: data.sub_title ?? null,
profilePicture: data.profile_picture ?? null,
backgroundImage: data.background_image ?? null,
industry: data.industry ?? null,
location: data.location?.default ?? data.location ?? null,
followersCount: data.followers_count ?? null,
connectionsCount: data.connections_count ?? null,
premium: data.premium ?? false,
influencer: data.influencer ?? false,
positions,
education,
websites: data.websites ?? [],
},
}
},
outputs: {
profileId: {
type: 'string',
description: 'LinkedIn profile ID',
optional: true,
},
firstName: {
type: 'string',
description: 'First name',
optional: true,
},
lastName: {
type: 'string',
description: 'Last name',
optional: true,
},
subTitle: {
type: 'string',
description: 'Profile subtitle/headline',
optional: true,
},
profilePicture: {
type: 'string',
description: 'Profile picture URL',
optional: true,
},
backgroundImage: {
type: 'string',
description: 'Background image URL',
optional: true,
},
industry: {
type: 'string',
description: 'Industry',
optional: true,
},
location: {
type: 'string',
description: 'Location',
optional: true,
},
followersCount: {
type: 'number',
description: 'Number of followers',
optional: true,
},
connectionsCount: {
type: 'number',
description: 'Number of connections',
optional: true,
},
premium: {
type: 'boolean',
description: 'Whether the account is premium',
},
influencer: {
type: 'boolean',
description: 'Whether the account is an influencer',
},
positions: {
type: 'array',
description: 'Work positions',
items: {
type: 'object',
properties: {
title: { type: 'string', description: 'Job title' },
company: { type: 'string', description: 'Company name' },
companyLogo: { type: 'string', description: 'Company logo URL' },
startDate: { type: 'string', description: 'Start date' },
endDate: { type: 'string', description: 'End date' },
location: { type: 'string', description: 'Location' },
},
},
},
education: {
type: 'array',
description: 'Education history',
items: {
type: 'object',
properties: {
school: { type: 'string', description: 'School name' },
degree: { type: 'string', description: 'Degree' },
fieldOfStudy: { type: 'string', description: 'Field of study' },
startDate: { type: 'string', description: 'Start date' },
endDate: { type: 'string', description: 'End date' },
},
},
},
websites: {
type: 'array',
description: 'Personal websites',
items: {
type: 'string',
description: 'Website URL',
},
},
},
}
@@ -0,0 +1,88 @@
import type {
EnrichLinkedInToPersonalEmailParams,
EnrichLinkedInToPersonalEmailResponse,
} from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const linkedInToPersonalEmailTool: ToolConfig<
EnrichLinkedInToPersonalEmailParams,
EnrichLinkedInToPersonalEmailResponse
> = {
id: 'enrich_linkedin_to_personal_email',
name: 'Enrich LinkedIn to Personal Email',
description: 'Find personal email address from a LinkedIn profile URL.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
linkedinProfile: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'LinkedIn profile URL (e.g., linkedin.com/in/username)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/find-personal-email')
url.searchParams.append('profile_url', params.linkedinProfile.trim())
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
accept: 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
// Handle queued response (202)
if (data.status === 'in_progress' || data.message?.includes('queued')) {
return {
success: true,
output: {
email: null,
found: false,
status: 'in_progress',
},
}
}
const resultData = data.data ?? data
return {
success: true,
output: {
email: resultData.email ?? resultData.personal_email ?? null,
found: resultData.found ?? Boolean(resultData.email ?? resultData.personal_email),
status: resultData.status ?? 'completed',
},
}
},
outputs: {
email: {
type: 'string',
description: 'Personal email address',
optional: true,
},
found: {
type: 'boolean',
description: 'Whether an email was found',
},
status: {
type: 'string',
description: 'Request status',
optional: true,
},
},
}
@@ -0,0 +1,85 @@
import type {
EnrichLinkedInToWorkEmailParams,
EnrichLinkedInToWorkEmailResponse,
} from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const linkedInToWorkEmailTool: ToolConfig<
EnrichLinkedInToWorkEmailParams,
EnrichLinkedInToWorkEmailResponse
> = {
id: 'enrich_linkedin_to_work_email',
name: 'Enrich LinkedIn to Work Email',
description: 'Find a work email address from a LinkedIn profile URL.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
linkedinProfile: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'LinkedIn profile URL (e.g., https://www.linkedin.com/in/williamhgates)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v2/api/linkedin-to-email')
url.searchParams.append('linkedin_profile', params.linkedinProfile.trim())
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
// Handle queued response (202)
if (data.status === 'in_progress' || data.message?.includes('queued')) {
return {
success: true,
output: {
email: null,
found: false,
status: 'in_progress',
},
}
}
return {
success: true,
output: {
email: data.email ?? null,
found: data.found ?? false,
status: 'completed',
},
}
},
outputs: {
email: {
type: 'string',
description: 'Found work email address',
optional: true,
},
found: {
type: 'boolean',
description: 'Whether an email was found',
},
status: {
type: 'string',
description: 'Request status (in_progress or completed)',
optional: true,
},
},
}
+86
View File
@@ -0,0 +1,86 @@
import type { EnrichPhoneFinderParams, EnrichPhoneFinderResponse } from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const phoneFinderTool: ToolConfig<EnrichPhoneFinderParams, EnrichPhoneFinderResponse> = {
id: 'enrich_phone_finder',
name: 'Enrich Phone Finder',
description: 'Find a phone number from a LinkedIn profile URL.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
linkedinProfile: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'LinkedIn profile URL (e.g., linkedin.com/in/williamhgates)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/mobile-finder')
url.searchParams.append('linkedin_profile', params.linkedinProfile.trim())
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
// Handle queued response (202)
if (data.message?.includes('queued')) {
return {
success: true,
output: {
profileUrl: null,
mobileNumber: null,
found: false,
status: 'in_progress',
},
}
}
return {
success: true,
output: {
profileUrl: data.data?.profile_url ?? null,
mobileNumber: data.data?.mobile_number ?? null,
found: !!data.data?.mobile_number,
status: 'completed',
},
}
},
outputs: {
profileUrl: {
type: 'string',
description: 'LinkedIn profile URL',
optional: true,
},
mobileNumber: {
type: 'string',
description: 'Found mobile phone number',
optional: true,
},
found: {
type: 'boolean',
description: 'Whether a phone number was found',
},
status: {
type: 'string',
description: 'Request status (in_progress or completed)',
optional: true,
},
},
}
@@ -0,0 +1,79 @@
import type {
EnrichReverseHashLookupParams,
EnrichReverseHashLookupResponse,
} from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const reverseHashLookupTool: ToolConfig<
EnrichReverseHashLookupParams,
EnrichReverseHashLookupResponse
> = {
id: 'enrich_reverse_hash_lookup',
name: 'Enrich Reverse Hash Lookup',
description: 'Convert an MD5 email hash back to the original email address and display name.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
hash: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'MD5 hash value to look up',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/reverse-hash-lookup')
url.searchParams.append('hash', params.hash.trim())
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const resultData = data.data ?? {}
return {
success: true,
output: {
hash: resultData.hash ?? '',
email: resultData.email ?? null,
displayName: resultData.display_name ?? null,
found: !!resultData.email,
},
}
},
outputs: {
hash: {
type: 'string',
description: 'MD5 hash that was looked up',
},
email: {
type: 'string',
description: 'Original email address',
optional: true,
},
displayName: {
type: 'string',
description: 'Display name associated with the email',
optional: true,
},
found: {
type: 'boolean',
description: 'Whether an email was found for the hash',
},
},
}
@@ -0,0 +1,133 @@
import type {
EnrichSalesPointerPeopleParams,
EnrichSalesPointerPeopleResponse,
} from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const salesPointerPeopleTool: ToolConfig<
EnrichSalesPointerPeopleParams,
EnrichSalesPointerPeopleResponse
> = {
id: 'enrich_sales_pointer_people',
name: 'Enrich Sales Pointer People',
description:
'Advanced people search with complex filters for location, company size, seniority, experience, and more.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
page: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Page number (starts at 1)',
},
filters: {
type: 'json',
required: true,
visibility: 'user-or-llm',
description:
'Array of filter objects. Each filter has type (e.g., POSTAL_CODE, COMPANY_HEADCOUNT), values (array with id, text, selectionType: INCLUDED/EXCLUDED), and optional selectedSubFilter',
},
},
request: {
url: 'https://api.enrich.so/v1/api/sales-pointer/people',
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params) => ({
page: params.page,
filters: params.filters,
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const resultData = data.data ?? {}
const profiles =
resultData.data?.map((person: any) => ({
name:
person.fullName ??
person.name ??
(person.firstName && person.lastName ? `${person.firstName} ${person.lastName}` : null),
summary: person.summary ?? person.headline ?? null,
location: person.location ?? person.geoRegion ?? null,
profilePicture:
person.profilePicture ?? person.profile_picture ?? person.profilePictureUrl ?? null,
linkedInUrn: person.linkedInUrn ?? person.linkedin_urn ?? person.urn ?? null,
positions: (person.positions ?? person.experience ?? []).map((pos: any) => ({
title: pos.title ?? '',
company: pos.companyName ?? pos.company ?? '',
})),
education: (person.education ?? []).map((edu: any) => ({
school: edu.schoolName ?? edu.school ?? '',
degree: edu.degreeName ?? edu.degree ?? null,
})),
})) ?? []
return {
success: true,
output: {
data: profiles,
pagination: {
totalCount: resultData.pagination?.total ?? 0,
returnedCount: resultData.pagination?.returned ?? 0,
start: resultData.pagination?.start ?? 0,
limit: resultData.pagination?.limit ?? 0,
},
},
}
},
outputs: {
data: {
type: 'array',
description: 'People results',
items: {
type: 'object',
properties: {
name: { type: 'string', description: 'Full name' },
summary: { type: 'string', description: 'Professional summary' },
location: { type: 'string', description: 'Location' },
profilePicture: { type: 'string', description: 'Profile picture URL' },
linkedInUrn: { type: 'string', description: 'LinkedIn URN' },
positions: {
type: 'array',
description: 'Work positions',
properties: {
title: { type: 'string', description: 'Job title' },
company: { type: 'string', description: 'Company' },
},
},
education: {
type: 'array',
description: 'Education',
properties: {
school: { type: 'string', description: 'School' },
degree: { type: 'string', description: 'Degree' },
},
},
},
},
},
pagination: {
type: 'json',
description: 'Pagination info',
properties: {
totalCount: { type: 'number', description: 'Total results' },
returnedCount: { type: 'number', description: 'Returned count' },
start: { type: 'number', description: 'Start position' },
limit: { type: 'number', description: 'Limit' },
},
},
},
}
+216
View File
@@ -0,0 +1,216 @@
import type { EnrichSearchCompanyParams, EnrichSearchCompanyResponse } from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const searchCompanyTool: ToolConfig<EnrichSearchCompanyParams, EnrichSearchCompanyResponse> =
{
id: 'enrich_search_company',
name: 'Enrich Search Company',
description:
'Search for companies by various criteria including name, industry, location, and size.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
name: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Company name',
},
website: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Company website URL',
},
tagline: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Company tagline',
},
type: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Company type (e.g., Private, Public)',
},
description: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Company description keywords',
},
industries: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Industries to filter by (array)',
},
locationCountry: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Country',
},
locationCity: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'City',
},
postalCode: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Postal code',
},
locationCountryList: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Multiple countries to filter by (array)',
},
locationCityList: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Multiple cities to filter by (array)',
},
specialities: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Company specialties (array)',
},
followers: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Minimum number of followers',
},
staffCount: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum staff count',
},
staffCountMin: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Minimum staff count',
},
staffCountMax: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum staff count',
},
currentPage: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Page number (default: 1)',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Results per page (default: 20)',
},
},
request: {
url: 'https://api.enrich.so/v1/api/search-company',
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, any> = {}
if (params.name) body.name = params.name
if (params.website) body.website = params.website
if (params.tagline) body.tagline = params.tagline
if (params.type) body.type = params.type
if (params.description) body.description = params.description
if (params.industries) body.industries = params.industries
if (params.locationCountry) body.location_country = params.locationCountry
if (params.locationCity) body.location_city = params.locationCity
if (params.postalCode) body.postal_code = params.postalCode
if (params.locationCountryList) body.location_country_list = params.locationCountryList
if (params.locationCityList) body.location_city_list = params.locationCityList
if (params.specialities) body.specialities = params.specialities
if (params.followers !== undefined) body.followers = params.followers
if (params.staffCount !== undefined) body.staff_count = params.staffCount
if (params.staffCountMin !== undefined) body.staff_count_min = params.staffCountMin
if (params.staffCountMax !== undefined) body.staff_count_max = params.staffCountMax
if (params.currentPage) body.current_page = params.currentPage
if (params.pageSize) body.page_size = params.pageSize
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
const resultData = data.data ?? {}
const companies =
resultData.companies?.map((company: any) => ({
companyName: company.company_name ?? '',
tagline: company.tagline ?? null,
webAddress: company.web_address ?? null,
industries: company.industries ?? [],
teamSize: company.team_size ?? null,
linkedInProfile: company.linkedin_profile ?? null,
})) ?? []
return {
success: true,
output: {
currentPage: resultData.current_page ?? 1,
totalPage: resultData.total_page ?? 1,
pageSize: resultData.page_size ?? 20,
companies,
},
}
},
outputs: {
currentPage: {
type: 'number',
description: 'Current page number',
},
totalPage: {
type: 'number',
description: 'Total number of pages',
},
pageSize: {
type: 'number',
description: 'Results per page',
},
companies: {
type: 'array',
description: 'Search results',
items: {
type: 'object',
properties: {
companyName: { type: 'string', description: 'Company name' },
tagline: { type: 'string', description: 'Company tagline' },
webAddress: { type: 'string', description: 'Website URL' },
industries: { type: 'array', description: 'Industries' },
teamSize: { type: 'number', description: 'Team size' },
linkedInProfile: { type: 'string', description: 'LinkedIn URL' },
},
},
},
},
}
@@ -0,0 +1,157 @@
import type {
EnrichSearchCompanyActivitiesParams,
EnrichSearchCompanyActivitiesResponse,
} from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const searchCompanyActivitiesTool: ToolConfig<
EnrichSearchCompanyActivitiesParams,
EnrichSearchCompanyActivitiesResponse
> = {
id: 'enrich_search_company_activities',
name: 'Enrich Search Company Activities',
description: "Get a company's LinkedIn activities (posts, comments, or articles) by company ID.",
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
companyId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'LinkedIn company ID',
},
activityType: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Activity type: posts, comments, or articles',
},
paginationToken: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pagination token for next page of results',
},
offset: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of records to skip (default: 0)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/search-company-activities')
url.searchParams.append('company_id', params.companyId.trim())
url.searchParams.append('activity_type', params.activityType)
if (params.paginationToken) {
url.searchParams.append('pagination_token', params.paginationToken)
}
if (params.offset !== undefined) {
url.searchParams.append('offset', String(params.offset))
}
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const resultData = data.data ?? {}
const activities =
resultData.data?.map((activity: any) => ({
activityId: activity.activity_id ?? null,
commentary: activity.commentary ?? null,
linkedInUrl: activity.li_url ?? null,
timeElapsed: activity.time_elapsed ?? null,
numReactions: activity.num_reactions ?? activity.numReactions ?? null,
author: activity.author
? {
name: activity.author.name ?? null,
// API returns 'id' (integer) for company activities, 'profile_id' for people activities
profileId: String(
activity.author.id ?? activity.author.profile_id ?? activity.author.profileId ?? ''
),
// API returns 'logo_url' for company activities, 'profile_picture' for people activities
profilePicture:
activity.author.logo_url ??
activity.author.profile_picture ??
activity.author.profilePicture ??
null,
}
: null,
reactionBreakdown: {
likes: activity.reaction_breakdown?.likes ?? 0,
empathy: activity.reaction_breakdown?.empathy ?? 0,
other: activity.reaction_breakdown?.other ?? 0,
},
attachments: activity.attachments ?? [],
})) ?? []
return {
success: true,
output: {
paginationToken: resultData.pagination_token ?? null,
activityType: resultData.activity_type ?? '',
activities,
},
}
},
outputs: {
paginationToken: {
type: 'string',
description: 'Token for fetching next page',
optional: true,
},
activityType: {
type: 'string',
description: 'Type of activities returned',
},
activities: {
type: 'array',
description: 'Activities',
items: {
type: 'object',
properties: {
activityId: { type: 'string', description: 'Activity ID' },
commentary: { type: 'string', description: 'Activity text content' },
linkedInUrl: { type: 'string', description: 'Link to activity' },
timeElapsed: { type: 'string', description: 'Time elapsed since activity' },
numReactions: { type: 'number', description: 'Total number of reactions' },
author: {
type: 'object',
description: 'Activity author info',
properties: {
name: { type: 'string', description: 'Author name' },
profileId: { type: 'string', description: 'Profile ID' },
profilePicture: { type: 'string', description: 'Profile picture URL' },
},
},
reactionBreakdown: {
type: 'object',
description: 'Reactions',
properties: {
likes: { type: 'number', description: 'Likes' },
empathy: { type: 'number', description: 'Empathy reactions' },
other: { type: 'number', description: 'Other reactions' },
},
},
attachments: { type: 'array', description: 'Attachments' },
},
},
},
},
}
@@ -0,0 +1,149 @@
import type {
EnrichSearchCompanyEmployeesParams,
EnrichSearchCompanyEmployeesResponse,
} from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const searchCompanyEmployeesTool: ToolConfig<
EnrichSearchCompanyEmployeesParams,
EnrichSearchCompanyEmployeesResponse
> = {
id: 'enrich_search_company_employees',
name: 'Enrich Search Company Employees',
description: 'Search for employees within specific companies by location and job title.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
companyIds: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Array of company IDs to search within',
},
country: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Country filter (e.g., United States)',
},
city: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'City filter (e.g., San Francisco)',
},
state: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'State filter (e.g., California)',
},
jobTitles: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Job titles to filter by (array)',
},
page: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Page number (default: 1)',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Results per page (default: 10)',
},
},
request: {
url: 'https://api.enrich.so/v1/api/search-company-employees',
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, any> = {}
if (params.companyIds) body.companyIds = params.companyIds
if (params.country) body.country = params.country
if (params.city) body.city = params.city
if (params.state) body.state = params.state
if (params.jobTitles) body.jobTitles = params.jobTitles
if (params.page) body.page = params.page
if (params.pageSize) body.page_size = params.pageSize
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
const resultData = data.data ?? {}
const profiles =
resultData.profiles?.map((profile: any) => ({
profileIdentifier: profile.profile_identifier ?? '',
givenName: profile.given_name ?? null,
familyName: profile.family_name ?? null,
currentPosition: profile.current_position ?? null,
profileImage: profile.profile_image ?? null,
externalProfileUrl: profile.external_profile_url ?? null,
city: profile.residence?.city ?? null,
country: profile.residence?.country ?? null,
expertSkills: profile.expert_skills ?? [],
})) ?? []
return {
success: true,
output: {
currentPage: resultData.current_page ?? 1,
totalPage: resultData.total_page ?? 1,
pageSize: resultData.page_size ?? profiles.length,
profiles,
},
}
},
outputs: {
currentPage: {
type: 'number',
description: 'Current page number',
},
totalPage: {
type: 'number',
description: 'Total number of pages',
},
pageSize: {
type: 'number',
description: 'Number of results per page',
},
profiles: {
type: 'array',
description: 'Employee profiles',
items: {
type: 'object',
properties: {
profileIdentifier: { type: 'string', description: 'Profile ID' },
givenName: { type: 'string', description: 'First name' },
familyName: { type: 'string', description: 'Last name' },
currentPosition: { type: 'string', description: 'Current job title' },
profileImage: { type: 'string', description: 'Profile image URL' },
externalProfileUrl: { type: 'string', description: 'LinkedIn URL' },
city: { type: 'string', description: 'City' },
country: { type: 'string', description: 'Country' },
expertSkills: { type: 'array', description: 'Skills' },
},
},
},
},
}
+149
View File
@@ -0,0 +1,149 @@
import type { EnrichSearchJobsParams, EnrichSearchJobsResponse } from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const searchJobsTool: ToolConfig<EnrichSearchJobsParams, EnrichSearchJobsResponse> = {
id: 'enrich_search_jobs',
name: 'Enrich Search Jobs',
description:
'Search LinkedIn job postings by keywords with filters for location, job type, workplace type, experience level, and company.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
keywords: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Search keywords (e.g., "software engineer")',
},
location: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Location filter (e.g., London)',
},
jobTypes: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated job types (e.g., "full time, part time")',
},
workplaceTypes: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated workplace types (e.g., "on site, remote")',
},
experienceLevels: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated experience levels (e.g., "internship, associate")',
},
companyIds: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated LinkedIn company IDs to filter by (e.g., "2048, 3050")',
},
timePosted: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Time filter (e.g., past_24hrs, past_week, past_month)',
},
start: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of records to skip for pagination (default: 0)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/search-jobs')
url.searchParams.append('keywords', params.keywords.trim())
if (params.location) url.searchParams.append('location', params.location.trim())
if (params.jobTypes) url.searchParams.append('jobTypes', params.jobTypes)
if (params.workplaceTypes) url.searchParams.append('workplaceTypes', params.workplaceTypes)
if (params.experienceLevels) {
url.searchParams.append('experienceLevels', params.experienceLevels)
}
if (params.companyIds) url.searchParams.append('companyIds', params.companyIds)
if (params.timePosted) url.searchParams.append('timePosted', params.timePosted)
if (params.start !== undefined) url.searchParams.append('start', String(params.start))
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const rawJobs = data.data ?? data.jobs ?? (Array.isArray(data) ? data : [])
const jobs = rawJobs.map((job: any) => ({
title: job.title ?? null,
companyName: job.company_name ?? job.companyName ?? null,
companyLink: job.company_link ?? job.companyLink ?? null,
companyLogo: job.company_logo_url ?? job.company_logo ?? job.companyLogo ?? null,
location: job.location ?? null,
url: job.url ?? job.job_url ?? job.jobUrl ?? null,
postedDate: job.posted_date ?? job.posting_date ?? job.postedDate ?? null,
postedTimestamp:
job.posted_timestamp ??
job.posting_timestamp ??
job.timestamp ??
job.postedTimestamp ??
null,
hiringStatus: job.hiring_status ?? job.hiringStatus ?? null,
criteria: job.criteria ?? job.employment_criteria ?? job.employmentCriteria ?? null,
}))
return {
success: true,
output: {
count: data.count ?? jobs.length,
jobs,
},
}
},
outputs: {
count: {
type: 'number',
description: 'Number of job postings returned',
},
jobs: {
type: 'array',
description: 'Job postings',
items: {
type: 'object',
properties: {
title: { type: 'string', description: 'Job title' },
companyName: { type: 'string', description: 'Hiring company name' },
companyLink: { type: 'string', description: 'Company LinkedIn URL' },
companyLogo: { type: 'string', description: 'Company logo URL' },
location: { type: 'string', description: 'Job location' },
url: { type: 'string', description: 'Job posting URL' },
postedDate: { type: 'string', description: 'Date the job was posted' },
postedTimestamp: { type: 'string', description: 'Timestamp the job was posted' },
hiringStatus: { type: 'string', description: 'Hiring status' },
criteria: {
type: 'object',
description: 'Employment criteria (seniority, type, function)',
},
},
},
},
},
}
+77
View File
@@ -0,0 +1,77 @@
import type { EnrichSearchLogoParams, EnrichSearchLogoResponse } from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const searchLogoTool: ToolConfig<EnrichSearchLogoParams, EnrichSearchLogoResponse> = {
id: 'enrich_search_logo',
name: 'Enrich Search Logo',
description: 'Get a company logo image URL by domain.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
url: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Company domain (e.g., google.com)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/search-logo')
url.searchParams.append('url', params.url.trim())
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response, params) => {
// Check if response is JSON (error case) or binary (success case)
const contentType = response.headers.get('content-type') ?? ''
if (contentType.includes('application/json')) {
// API returned JSON, likely an error or no logo found
const data = await response.json()
return {
success: true,
output: {
logoUrl: data.logo_url ?? data.logoUrl ?? null,
domain: params?.url ?? '',
},
}
}
// API returns the image directly, construct the URL for access
const logoUrl = `https://api.enrich.so/v1/api/search-logo?url=${encodeURIComponent(params?.url ?? '')}`
return {
success: true,
output: {
logoUrl,
domain: params?.url ?? '',
},
}
},
outputs: {
logoUrl: {
type: 'string',
description: 'URL to fetch the company logo',
optional: true,
},
domain: {
type: 'string',
description: 'Domain that was looked up',
},
},
}
+249
View File
@@ -0,0 +1,249 @@
import type { EnrichSearchPeopleParams, EnrichSearchPeopleResponse } from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const searchPeopleTool: ToolConfig<EnrichSearchPeopleParams, EnrichSearchPeopleResponse> = {
id: 'enrich_search_people',
name: 'Enrich Search People',
description:
'Search for professionals by various criteria including name, title, skills, education, and company.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
firstName: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'First name',
},
lastName: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Last name',
},
summary: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Professional summary keywords',
},
subTitle: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Job title/subtitle',
},
locationCountry: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Country',
},
locationCity: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'City',
},
locationState: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'State/province',
},
influencer: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Filter for influencers only',
},
premium: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Filter for premium accounts only',
},
language: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Primary language',
},
industry: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Industry',
},
currentJobTitles: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Current job titles (array)',
},
pastJobTitles: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Past job titles (array)',
},
skills: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Skills to search for (array)',
},
schoolNames: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'School names (array)',
},
certifications: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Certifications to filter by (array)',
},
degreeNames: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Degree names to filter by (array)',
},
studyFields: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Fields of study to filter by (array)',
},
currentCompanies: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Current company IDs to filter by (array of numbers)',
},
pastCompanies: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Past company IDs to filter by (array of numbers)',
},
currentPage: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Page number (default: 1)',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Results per page (default: 20)',
},
},
request: {
url: 'https://api.enrich.so/v1/api/search-people',
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, any> = {}
if (params.firstName) body.first_name = params.firstName
if (params.lastName) body.last_name = params.lastName
if (params.summary) body.summary = params.summary
if (params.subTitle) body.sub_title = params.subTitle
if (params.locationCountry) body.location_country = params.locationCountry
if (params.locationCity) body.location_city = params.locationCity
if (params.locationState) body.location_state = params.locationState
if (params.influencer !== undefined) body.influencer = params.influencer
if (params.premium !== undefined) body.premium = params.premium
if (params.language) body.language = params.language
if (params.industry) body.industry = params.industry
if (params.currentJobTitles) body.current_job_titles = params.currentJobTitles
if (params.pastJobTitles) body.past_job_titles = params.pastJobTitles
if (params.skills) body.skills = params.skills
if (params.schoolNames) body.school_names = params.schoolNames
if (params.certifications) body.certifications = params.certifications
if (params.degreeNames) body.degree_names = params.degreeNames
if (params.studyFields) body.study_fields = params.studyFields
if (params.currentCompanies) body.current_companies = params.currentCompanies
if (params.pastCompanies) body.past_companies = params.pastCompanies
if (params.currentPage) body.current_page = params.currentPage
if (params.pageSize) body.page_size = params.pageSize
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
const resultData = data.data ?? {}
const profiles =
resultData.profiles?.map((profile: any) => ({
profileIdentifier: profile.profile_identifier ?? '',
givenName: profile.given_name ?? null,
familyName: profile.family_name ?? null,
currentPosition: profile.current_position ?? null,
profileImage: profile.profile_image ?? null,
externalProfileUrl: profile.external_profile_url ?? null,
city: profile.residence?.city ?? null,
country: profile.residence?.country ?? null,
expertSkills: profile.expert_skills ?? [],
})) ?? []
return {
success: true,
output: {
currentPage: resultData.current_page ?? 1,
totalPage: resultData.total_page ?? 1,
pageSize: resultData.page_size ?? 20,
profiles,
},
}
},
outputs: {
currentPage: {
type: 'number',
description: 'Current page number',
},
totalPage: {
type: 'number',
description: 'Total number of pages',
},
pageSize: {
type: 'number',
description: 'Results per page',
},
profiles: {
type: 'array',
description: 'Search results',
items: {
type: 'object',
properties: {
profileIdentifier: { type: 'string', description: 'Profile ID' },
givenName: { type: 'string', description: 'First name' },
familyName: { type: 'string', description: 'Last name' },
currentPosition: { type: 'string', description: 'Current job title' },
profileImage: { type: 'string', description: 'Profile image URL' },
externalProfileUrl: { type: 'string', description: 'LinkedIn URL' },
city: { type: 'string', description: 'City' },
country: { type: 'string', description: 'Country' },
expertSkills: { type: 'array', description: 'Skills' },
},
},
},
},
}
@@ -0,0 +1,141 @@
import type {
EnrichSearchPeopleActivitiesParams,
EnrichSearchPeopleActivitiesResponse,
} from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const searchPeopleActivitiesTool: ToolConfig<
EnrichSearchPeopleActivitiesParams,
EnrichSearchPeopleActivitiesResponse
> = {
id: 'enrich_search_people_activities',
name: 'Enrich Search People Activities',
description: "Get a person's LinkedIn activities (posts, comments, or articles) by profile ID.",
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
profileId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'LinkedIn profile ID',
},
activityType: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Activity type: posts, comments, or articles',
},
paginationToken: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pagination token for next page of results',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/search-people-activities')
url.searchParams.append('profile_id', params.profileId.trim())
url.searchParams.append('activity_type', params.activityType)
if (params.paginationToken) {
url.searchParams.append('pagination_token', params.paginationToken)
}
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const resultData = data.data ?? {}
const activities =
resultData.data?.map((activity: any) => ({
activityId: activity.activity_id ?? activity.activityId ?? null,
commentary: activity.commentary ?? null,
linkedInUrl: activity.li_url ?? activity.linkedInUrl ?? null,
timeElapsed: activity.time_elapsed ?? activity.timeElapsed ?? null,
numReactions: activity.num_reactions ?? activity.numReactions ?? null,
author: activity.author
? {
name: activity.author.name ?? null,
profileId: String(activity.author.profile_id ?? activity.author.profileId ?? ''),
profilePicture:
activity.author.profile_picture ?? activity.author.profilePicture ?? null,
}
: null,
reactionBreakdown: {
likes: activity.reaction_breakdown?.likes ?? activity.reactionBreakdown?.likes ?? 0,
empathy: activity.reaction_breakdown?.empathy ?? activity.reactionBreakdown?.empathy ?? 0,
other: activity.reaction_breakdown?.other ?? activity.reactionBreakdown?.other ?? 0,
},
attachments: activity.attachments ?? [],
})) ?? []
return {
success: true,
output: {
paginationToken: resultData.pagination_token ?? null,
activityType: resultData.activity_type ?? '',
activities,
},
}
},
outputs: {
paginationToken: {
type: 'string',
description: 'Token for fetching next page',
optional: true,
},
activityType: {
type: 'string',
description: 'Type of activities returned',
},
activities: {
type: 'array',
description: 'Activities',
items: {
type: 'object',
properties: {
activityId: { type: 'string', description: 'Activity ID' },
commentary: { type: 'string', description: 'Activity text content' },
linkedInUrl: { type: 'string', description: 'Link to activity' },
timeElapsed: { type: 'string', description: 'Time elapsed since activity' },
numReactions: { type: 'number', description: 'Total number of reactions' },
author: {
type: 'object',
description: 'Activity author info',
properties: {
name: { type: 'string', description: 'Author name' },
profileId: { type: 'string', description: 'Profile ID' },
profilePicture: { type: 'string', description: 'Profile picture URL' },
},
},
reactionBreakdown: {
type: 'object',
description: 'Reactions',
properties: {
likes: { type: 'number', description: 'Likes' },
empathy: { type: 'number', description: 'Empathy reactions' },
other: { type: 'number', description: 'Other reactions' },
},
},
attachments: { type: 'array', description: 'Attachment URLs' },
},
},
},
},
}
@@ -0,0 +1,143 @@
import type {
EnrichSearchPostCommentsParams,
EnrichSearchPostCommentsResponse,
} from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const searchPostCommentsTool: ToolConfig<
EnrichSearchPostCommentsParams,
EnrichSearchPostCommentsResponse
> = {
id: 'enrich_search_post_comments',
name: 'Enrich Search Post Comments',
description: 'Get comments on a LinkedIn post.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
postUrn: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'LinkedIn activity URN (e.g., urn:li:activity:7191163324208705536)',
},
page: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Page number (starts at 1, default: 1)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/search-comments')
url.searchParams.append('post_urn', params.postUrn.trim())
if (params.page !== undefined) {
url.searchParams.append('page', String(params.page))
}
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const resultData = data.data ?? {}
const comments =
resultData.data?.map((comment: any) => ({
activityId: comment.activity_id ?? null,
commentary: comment.commentary ?? null,
linkedInUrl: comment.li_url ?? null,
commenter: {
profileId: comment.commenter?.profile_id ?? null,
firstName: comment.commenter?.first_name ?? null,
lastName: comment.commenter?.last_name ?? null,
subTitle: comment.commenter?.sub_title ?? comment.commenter?.subTitle ?? null,
profilePicture:
comment.commenter?.profile_picture ?? comment.commenter?.profilePicture ?? null,
backgroundImage:
comment.commenter?.background_image ?? comment.commenter?.backgroundImage ?? null,
entityUrn: comment.commenter?.entity_urn ?? comment.commenter?.entityUrn ?? null,
objectUrn: comment.commenter?.object_urn ?? comment.commenter?.objectUrn ?? null,
profileType: comment.commenter?.profile_type ?? comment.commenter?.profileType ?? null,
},
reactionBreakdown: {
likes: comment.reaction_breakdown?.likes ?? 0,
empathy: comment.reaction_breakdown?.empathy ?? 0,
other: comment.reaction_breakdown?.other ?? 0,
},
})) ?? []
return {
success: true,
output: {
page: resultData.page ?? 1,
totalPage: resultData.total_page ?? 1,
count: resultData.num ?? comments.length,
comments,
},
}
},
outputs: {
page: {
type: 'number',
description: 'Current page number',
},
totalPage: {
type: 'number',
description: 'Total number of pages',
},
count: {
type: 'number',
description: 'Number of comments returned',
},
comments: {
type: 'array',
description: 'Comments',
items: {
type: 'object',
properties: {
activityId: { type: 'string', description: 'Comment activity ID' },
commentary: { type: 'string', description: 'Comment text' },
linkedInUrl: { type: 'string', description: 'Link to comment' },
commenter: {
type: 'object',
description: 'Commenter info',
properties: {
profileId: { type: 'string', description: 'Profile ID' },
firstName: { type: 'string', description: 'First name' },
lastName: { type: 'string', description: 'Last name' },
subTitle: { type: 'string', description: 'Subtitle/headline' },
profilePicture: { type: 'string', description: 'Profile picture URL' },
backgroundImage: { type: 'string', description: 'Background image URL' },
entityUrn: { type: 'string', description: 'Entity URN' },
objectUrn: { type: 'string', description: 'Object URN' },
profileType: { type: 'string', description: 'Profile type' },
},
},
reactionBreakdown: {
type: 'object',
description: 'Reactions on the comment',
properties: {
likes: { type: 'number', description: 'Number of likes' },
empathy: { type: 'number', description: 'Number of empathy reactions' },
other: { type: 'number', description: 'Number of other reactions' },
},
},
},
},
},
},
}
@@ -0,0 +1,143 @@
import type {
EnrichSearchPostCommentsByUrlParams,
EnrichSearchPostCommentsResponse,
} from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const searchPostCommentsByUrlTool: ToolConfig<
EnrichSearchPostCommentsByUrlParams,
EnrichSearchPostCommentsResponse
> = {
id: 'enrich_search_post_comments_by_url',
name: 'Enrich Search Post Comments by URL',
description: 'Get comments on a LinkedIn post by its URL.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
postUrl: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'LinkedIn post URL (e.g., https://www.linkedin.com/posts/...)',
},
page: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Page number (starts at 1, default: 1)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/search-comment-by-url')
url.searchParams.append('post_url', params.postUrl.trim())
if (params.page !== undefined) {
url.searchParams.append('page', String(params.page))
}
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const resultData = data.data ?? {}
const comments =
resultData.data?.map((comment: any) => ({
activityId: comment.activity_id ?? null,
commentary: comment.commentary ?? null,
linkedInUrl: comment.li_url ?? null,
commenter: {
profileId: comment.commenter?.profile_id ?? null,
firstName: comment.commenter?.first_name ?? null,
lastName: comment.commenter?.last_name ?? null,
subTitle: comment.commenter?.sub_title ?? comment.commenter?.subTitle ?? null,
profilePicture:
comment.commenter?.profile_picture ?? comment.commenter?.profilePicture ?? null,
backgroundImage:
comment.commenter?.background_image ?? comment.commenter?.backgroundImage ?? null,
entityUrn: comment.commenter?.entity_urn ?? comment.commenter?.entityUrn ?? null,
objectUrn: comment.commenter?.object_urn ?? comment.commenter?.objectUrn ?? null,
profileType: comment.commenter?.profile_type ?? comment.commenter?.profileType ?? null,
},
reactionBreakdown: {
likes: comment.reaction_breakdown?.likes ?? 0,
empathy: comment.reaction_breakdown?.empathy ?? 0,
other: comment.reaction_breakdown?.other ?? 0,
},
})) ?? []
return {
success: true,
output: {
page: resultData.page ?? 1,
totalPage: resultData.total_page ?? 1,
count: resultData.num ?? comments.length,
comments,
},
}
},
outputs: {
page: {
type: 'number',
description: 'Current page number',
},
totalPage: {
type: 'number',
description: 'Total number of pages',
},
count: {
type: 'number',
description: 'Number of comments returned',
},
comments: {
type: 'array',
description: 'Comments',
items: {
type: 'object',
properties: {
activityId: { type: 'string', description: 'Comment activity ID' },
commentary: { type: 'string', description: 'Comment text' },
linkedInUrl: { type: 'string', description: 'Link to comment' },
commenter: {
type: 'object',
description: 'Commenter info',
properties: {
profileId: { type: 'string', description: 'Profile ID' },
firstName: { type: 'string', description: 'First name' },
lastName: { type: 'string', description: 'Last name' },
subTitle: { type: 'string', description: 'Subtitle/headline' },
profilePicture: { type: 'string', description: 'Profile picture URL' },
backgroundImage: { type: 'string', description: 'Background image URL' },
entityUrn: { type: 'string', description: 'Entity URN' },
objectUrn: { type: 'string', description: 'Object URN' },
profileType: { type: 'string', description: 'Profile type' },
},
},
reactionBreakdown: {
type: 'object',
description: 'Reactions on the comment',
properties: {
likes: { type: 'number', description: 'Number of likes' },
empathy: { type: 'number', description: 'Number of empathy reactions' },
other: { type: 'number', description: 'Number of other reactions' },
},
},
},
},
},
},
}
@@ -0,0 +1,121 @@
import type {
EnrichSearchPostReactionsParams,
EnrichSearchPostReactionsResponse,
} from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const searchPostReactionsTool: ToolConfig<
EnrichSearchPostReactionsParams,
EnrichSearchPostReactionsResponse
> = {
id: 'enrich_search_post_reactions',
name: 'Enrich Search Post Reactions',
description: 'Get reactions on a LinkedIn post with filtering by reaction type.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
postUrn: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'LinkedIn activity URN (e.g., urn:li:activity:7231931952839196672)',
},
reactionType: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description:
'Reaction type filter: all, like, love, celebrate, insightful, or funny (default: all)',
},
page: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Page number (starts at 1)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/search-reactions')
url.searchParams.append('post_urn', params.postUrn.trim())
url.searchParams.append('reaction_type', params.reactionType)
url.searchParams.append('page', String(params.page))
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const resultData = data.data ?? {}
const reactions =
resultData.data?.map((reaction: any) => ({
reactionType: reaction.reaction_type ?? '',
reactor: {
name: reaction.reactor?.name ?? null,
subTitle: reaction.reactor?.sub_title ?? null,
profileId: reaction.reactor?.profile_id ?? null,
profilePicture: reaction.reactor?.profile_picture ?? null,
linkedInUrl: reaction.reactor?.li_url ?? null,
},
})) ?? []
return {
success: true,
output: {
page: resultData.page ?? 1,
totalPage: resultData.total_page ?? 1,
count: resultData.num ?? reactions.length,
reactions,
},
}
},
outputs: {
page: {
type: 'number',
description: 'Current page number',
},
totalPage: {
type: 'number',
description: 'Total number of pages',
},
count: {
type: 'number',
description: 'Number of reactions returned',
},
reactions: {
type: 'array',
description: 'Reactions',
items: {
type: 'object',
properties: {
reactionType: { type: 'string', description: 'Type of reaction' },
reactor: {
type: 'object',
description: 'Person who reacted',
properties: {
name: { type: 'string', description: 'Name' },
subTitle: { type: 'string', description: 'Job title' },
profileId: { type: 'string', description: 'Profile ID' },
profilePicture: { type: 'string', description: 'Profile picture URL' },
linkedInUrl: { type: 'string', description: 'LinkedIn URL' },
},
},
},
},
},
},
}
@@ -0,0 +1,121 @@
import type {
EnrichSearchPostReactionsByUrlParams,
EnrichSearchPostReactionsResponse,
} from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const searchPostReactionsByUrlTool: ToolConfig<
EnrichSearchPostReactionsByUrlParams,
EnrichSearchPostReactionsResponse
> = {
id: 'enrich_search_post_reactions_by_url',
name: 'Enrich Search Post Reactions by URL',
description: 'Get reactions on a LinkedIn post by its URL, filtered by reaction type.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
postUrl: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'LinkedIn post URL (e.g., https://www.linkedin.com/posts/...)',
},
reactionType: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description:
'Reaction type filter: all, like, love, celebrate, insightful, or funny (default: all)',
},
page: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Page number (starts at 1)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/search-reaction-by-url')
url.searchParams.append('post_url', params.postUrl.trim())
url.searchParams.append('reaction_type', params.reactionType)
url.searchParams.append('page', String(params.page))
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const resultData = data.data ?? {}
const reactions =
resultData.data?.map((reaction: any) => ({
reactionType: reaction.reaction_type ?? '',
reactor: {
name: reaction.reactor?.name ?? null,
subTitle: reaction.reactor?.sub_title ?? null,
profileId: reaction.reactor?.profile_id ?? null,
profilePicture: reaction.reactor?.profile_picture ?? null,
linkedInUrl: reaction.reactor?.li_url ?? null,
},
})) ?? []
return {
success: true,
output: {
page: resultData.page ?? 1,
totalPage: resultData.total_page ?? 1,
count: resultData.num ?? reactions.length,
reactions,
},
}
},
outputs: {
page: {
type: 'number',
description: 'Current page number',
},
totalPage: {
type: 'number',
description: 'Total number of pages',
},
count: {
type: 'number',
description: 'Number of reactions returned',
},
reactions: {
type: 'array',
description: 'Reactions',
items: {
type: 'object',
properties: {
reactionType: { type: 'string', description: 'Type of reaction' },
reactor: {
type: 'object',
description: 'Person who reacted',
properties: {
name: { type: 'string', description: 'Name' },
subTitle: { type: 'string', description: 'Job title' },
profileId: { type: 'string', description: 'Profile ID' },
profilePicture: { type: 'string', description: 'Profile picture URL' },
linkedInUrl: { type: 'string', description: 'LinkedIn URL' },
},
},
},
},
},
},
}
+120
View File
@@ -0,0 +1,120 @@
import type { EnrichSearchPostsParams, EnrichSearchPostsResponse } from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const searchPostsTool: ToolConfig<EnrichSearchPostsParams, EnrichSearchPostsResponse> = {
id: 'enrich_search_posts',
name: 'Enrich Search Posts',
description: 'Search LinkedIn posts by keywords with date filtering.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
keywords: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Search keywords (e.g., "AI automation")',
},
datePosted: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Time filter (e.g., past_week, past_month)',
},
page: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Page number (default: 1)',
},
},
request: {
url: 'https://api.enrich.so/v1/api/search-posts',
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
Accept: 'application/json',
}),
body: (params) => {
const body: Record<string, any> = {
keywords: params.keywords,
}
if (params.datePosted) body.date_posted = params.datePosted
if (params.page) body.page = params.page
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
const posts =
data.data?.map((post: any) => ({
url: post.url ?? null,
postId: post.post_id ?? null,
author: {
name: post.author?.name ?? null,
headline: post.author?.headline ?? null,
linkedInUrl: post.author?.linkedin_url ?? null,
profileImage: post.author?.profile_image ?? null,
},
timestamp: post.post?.timestamp ?? null,
textContent: post.post?.text_content ?? null,
hashtags: post.post?.hashtags ?? [],
mediaUrls: post.post?.post_media_url ?? [],
reactions: post.engagement?.reactions ?? 0,
commentsCount: post.engagement?.comments_count ?? 0,
})) ?? []
return {
success: true,
output: {
count: data.count ?? posts.length,
posts,
},
}
},
outputs: {
count: {
type: 'number',
description: 'Total number of results',
},
posts: {
type: 'array',
description: 'Search results',
items: {
type: 'object',
properties: {
url: { type: 'string', description: 'Post URL' },
postId: { type: 'string', description: 'Post ID' },
author: {
type: 'object',
description: 'Author information',
properties: {
name: { type: 'string', description: 'Author name' },
headline: { type: 'string', description: 'Author headline' },
linkedInUrl: { type: 'string', description: 'Author LinkedIn URL' },
profileImage: { type: 'string', description: 'Author profile image' },
},
},
timestamp: { type: 'string', description: 'Post timestamp' },
textContent: { type: 'string', description: 'Post text content' },
hashtags: { type: 'array', description: 'Hashtags' },
mediaUrls: { type: 'array', description: 'Media URLs' },
reactions: { type: 'number', description: 'Number of reactions' },
commentsCount: { type: 'number', description: 'Number of comments' },
},
},
},
},
}
@@ -0,0 +1,146 @@
import type {
EnrichSearchSimilarCompaniesParams,
EnrichSearchSimilarCompaniesResponse,
} from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const searchSimilarCompaniesTool: ToolConfig<
EnrichSearchSimilarCompaniesParams,
EnrichSearchSimilarCompaniesResponse
> = {
id: 'enrich_search_similar_companies',
name: 'Enrich Search Similar Companies',
description:
'Find companies similar to a given company by LinkedIn URL with filters for location and size.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
url: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'LinkedIn company URL (e.g., linkedin.com/company/google)',
},
accountLocation: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Filter by locations (array of country names)',
},
employeeSizeType: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Employee size filter type (e.g., RANGE)',
},
employeeSizeRange: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Employee size ranges (array of {start, end} objects)',
},
page: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Page number (default: 1)',
},
num: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of results per page',
},
},
request: {
url: 'https://api.enrich.so/v1/api/similar-companies',
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, any> = {
url: params.url.trim(),
}
if (params.accountLocation) {
body.account = body.account ?? {}
body.account.location = params.accountLocation
}
if (params.employeeSizeType || params.employeeSizeRange) {
body.account = body.account ?? {}
body.account.employeeSize = {
type: params.employeeSizeType ?? 'RANGE',
range: params.employeeSizeRange ?? [],
}
}
if (params.page) body.page = params.page
if (params.num) body.num = params.num
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
const content = data.data?.content ?? []
const companies = content.map((company: any) => ({
url: company.url ?? null,
name: company.name ?? null,
universalName: company.universalName ?? null,
type: company.type ?? null,
description: company.description ?? null,
phone: company.phone ?? null,
website: company.website ?? null,
logo: company.logo ?? null,
foundedYear: company.foundedYear ?? null,
staffTotal: company.staff?.total ?? null,
industries: company.industries ?? [],
relevancyScore: company.relevancy?.score ?? null,
relevancyValue: company.relevancy?.value ?? null,
}))
return {
success: true,
output: {
companies,
},
}
},
outputs: {
companies: {
type: 'array',
description: 'Similar companies',
items: {
type: 'object',
properties: {
url: { type: 'string', description: 'LinkedIn URL' },
name: { type: 'string', description: 'Company name' },
universalName: { type: 'string', description: 'Universal name' },
type: { type: 'string', description: 'Company type' },
description: { type: 'string', description: 'Description' },
phone: { type: 'string', description: 'Phone number' },
website: { type: 'string', description: 'Website URL' },
logo: { type: 'string', description: 'Logo URL' },
foundedYear: { type: 'number', description: 'Year founded' },
staffTotal: { type: 'number', description: 'Total staff' },
industries: { type: 'array', description: 'Industries' },
relevancyScore: { type: 'number', description: 'Relevancy score' },
relevancyValue: { type: 'string', description: 'Relevancy value' },
},
},
},
},
}
+782
View File
@@ -0,0 +1,782 @@
import type { ToolResponse } from '@/tools/types'
/**
* Base params for all Enrich tools
*/
interface EnrichBaseParams {
apiKey: string
}
export interface EnrichCheckCreditsParams extends EnrichBaseParams {}
export interface EnrichCheckCreditsResponse extends ToolResponse {
output: {
totalCredits: number
creditsUsed: number
creditsRemaining: number
}
}
export interface EnrichEmailToProfileParams extends EnrichBaseParams {
email: string
inRealtime?: boolean
}
export interface EnrichEmailToProfileResponse extends ToolResponse {
output: {
displayName: string | null
firstName: string | null
lastName: string | null
headline: string | null
occupation: string | null
summary: string | null
location: string | null
country: string | null
linkedInUrl: string | null
photoUrl: string | null
connectionCount: number | null
isConnectionCountObfuscated: boolean | null
positionHistory: Array<{
title: string
company: string
startDate: string | null
endDate: string | null
location: string | null
}>
education: Array<{
school: string
degree: string | null
fieldOfStudy: string | null
startDate: string | null
endDate: string | null
}>
certifications: Array<{
name: string
authority: string | null
url: string | null
}>
skills: string[]
languages: string[]
locale: string | null
version: number | null
}
}
export interface EnrichEmailToPersonLiteParams extends EnrichBaseParams {
email: string
}
export interface EnrichEmailToPersonLiteResponse extends ToolResponse {
output: {
name: string | null
firstName: string | null
lastName: string | null
email: string | null
title: string | null
location: string | null
company: string | null
companyLocation: string | null
companyLinkedIn: string | null
profileId: string | null
schoolName: string | null
schoolUrl: string | null
linkedInUrl: string | null
photoUrl: string | null
followerCount: number | null
connectionCount: number | null
languages: string[]
projects: string[]
certifications: string[]
volunteerExperience: string[]
}
}
export interface EnrichLinkedInProfileParams extends EnrichBaseParams {
url: string
}
export interface EnrichLinkedInProfileResponse extends ToolResponse {
output: {
profileId: string | null
firstName: string | null
lastName: string | null
subTitle: string | null
profilePicture: string | null
backgroundImage: string | null
industry: string | null
location: string | null
followersCount: number | null
connectionsCount: number | null
premium: boolean
influencer: boolean
positions: Array<{
title: string
company: string
companyLogo: string | null
startDate: string | null
endDate: string | null
location: string | null
}>
education: Array<{
school: string
degree: string | null
fieldOfStudy: string | null
startDate: string | null
endDate: string | null
}>
websites: string[]
}
}
export interface EnrichFindEmailParams extends EnrichBaseParams {
fullName: string
companyDomain: string
}
export interface EnrichFindEmailResponse extends ToolResponse {
output: {
email: string | null
firstName: string | null
lastName: string | null
domain: string | null
found: boolean
acceptAll: boolean | null
}
}
export interface EnrichLinkedInToWorkEmailParams extends EnrichBaseParams {
linkedinProfile: string
}
export interface EnrichLinkedInToWorkEmailResponse extends ToolResponse {
output: {
email: string | null
found: boolean
status: string | null
}
}
export interface EnrichLinkedInToPersonalEmailParams extends EnrichBaseParams {
linkedinProfile: string
}
export interface EnrichLinkedInToPersonalEmailResponse extends ToolResponse {
output: {
email: string | null
found: boolean
status: string | null
}
}
export interface EnrichPhoneFinderParams extends EnrichBaseParams {
linkedinProfile: string
}
export interface EnrichPhoneFinderResponse extends ToolResponse {
output: {
profileUrl: string | null
mobileNumber: string | null
found: boolean
status: string | null
}
}
export interface EnrichEmailToPhoneParams extends EnrichBaseParams {
email: string
}
export interface EnrichEmailToPhoneResponse extends ToolResponse {
output: {
email: string | null
mobileNumber: string | null
found: boolean
status: string | null
}
}
export interface EnrichVerifyEmailParams extends EnrichBaseParams {
email: string
}
export interface EnrichVerifyEmailResponse extends ToolResponse {
output: {
email: string
status: string
result: string
confidenceScore: number
smtpProvider: string | null
mailDisposable: boolean
mailAcceptAll: boolean
free: boolean
}
}
export interface EnrichDisposableEmailCheckParams extends EnrichBaseParams {
email: string
}
export interface EnrichDisposableEmailCheckResponse extends ToolResponse {
output: {
email: string
score: number
testsPassed: string
passed: boolean
reason: string | null
mailServerIp: string | null
mxRecords: Array<{ host: string; pref: number }>
}
}
export interface EnrichEmailToIpParams extends EnrichBaseParams {
email: string
}
export interface EnrichEmailToIpResponse extends ToolResponse {
output: {
email: string
ip: string | null
found: boolean
}
}
export interface EnrichIpToCompanyParams extends EnrichBaseParams {
ip: string
}
export interface EnrichIpToCompanyResponse extends ToolResponse {
output: {
name: string | null
legalName: string | null
domain: string | null
domainAliases: string[]
sector: string | null
industry: string | null
phone: string | null
employees: number | null
revenue: string | null
location: {
city: string | null
state: string | null
country: string | null
timezone: string | null
}
linkedInUrl: string | null
twitterUrl: string | null
facebookUrl: string | null
}
}
export interface EnrichCompanyLookupParams extends EnrichBaseParams {
name?: string
domain?: string
}
export interface EnrichCompanyLookupResponse extends ToolResponse {
output: {
name: string | null
universalName: string | null
companyId: string | null
description: string | null
phone: string | null
linkedInUrl: string | null
websiteUrl: string | null
followers: number | null
staffCount: number | null
foundedDate: string | null
type: string | null
industries: string[]
specialties: string[]
headquarters: {
city: string | null
country: string | null
postalCode: string | null
line1: string | null
}
logo: string | null
coverImage: string | null
fundingRounds: Array<{
roundType: string
amount: number | null
currency: string | null
investors: string[]
}>
}
}
export interface EnrichCompanyFundingParams extends EnrichBaseParams {
domain: string
}
export interface EnrichCompanyFundingResponse extends ToolResponse {
output: {
legalName: string | null
employeeCount: number | null
headquarters: string | null
industry: string | null
totalFundingRaised: number | null
fundingRounds: Array<{
roundType: string
amount: number | null
date: string | null
investors: string[]
}>
monthlyVisits: number | null
trafficChange: number | null
itSpending: number | null
executives: Array<{
name: string
title: string
}>
}
}
export interface EnrichCompanyRevenueParams extends EnrichBaseParams {
domain: string
}
export interface EnrichCompanyRevenueResponse extends ToolResponse {
output: {
companyName: string | null
shortDescription: string | null
fullSummary: string | null
revenue: string | null
revenueMin: number | null
revenueMax: number | null
employeeCount: number | null
founded: string | null
ownership: string | null
status: string | null
website: string | null
ceo: {
name: string | null
designation: string | null
rating: number | null
}
socialLinks: {
linkedIn: string | null
twitter: string | null
facebook: string | null
}
totalFunding: string | null
fundingRounds: number | null
competitors: Array<{
name: string
revenue: string | null
employeeCount: number | null
headquarters: string | null
}>
}
}
export interface EnrichSearchPeopleParams extends EnrichBaseParams {
firstName?: string
lastName?: string
summary?: string
subTitle?: string
locationCountry?: string
locationCity?: string
locationState?: string
influencer?: boolean
premium?: boolean
language?: string
industry?: string
certifications?: string[]
degreeNames?: string[]
studyFields?: string[]
schoolNames?: string[]
currentCompanies?: number[]
pastCompanies?: number[]
currentJobTitles?: string[]
pastJobTitles?: string[]
skills?: string[]
currentPage?: number
pageSize?: number
}
export interface EnrichSearchPeopleResponse extends ToolResponse {
output: {
currentPage: number
totalPage: number
pageSize: number
profiles: Array<{
profileIdentifier: string
givenName: string | null
familyName: string | null
currentPosition: string | null
profileImage: string | null
externalProfileUrl: string | null
city: string | null
country: string | null
expertSkills: string[]
}>
}
}
export interface EnrichSearchCompanyParams extends EnrichBaseParams {
name?: string
website?: string
tagline?: string
type?: string
postalCode?: string
description?: string
industries?: string[]
locationCountry?: string
locationCountryList?: string[]
locationCity?: string
locationCityList?: string[]
specialities?: string[]
followers?: number
staffCount?: number
staffCountMin?: number
staffCountMax?: number
pageSize?: number
currentPage?: number
}
export interface EnrichSearchCompanyResponse extends ToolResponse {
output: {
currentPage: number
totalPage: number
pageSize: number
companies: Array<{
companyName: string
tagline: string | null
webAddress: string | null
industries: string[]
teamSize: number | null
linkedInProfile: string | null
}>
}
}
export interface EnrichSearchCompanyEmployeesParams extends EnrichBaseParams {
companyIds?: number[]
country?: string
city?: string
state?: string
jobTitles?: string[]
page?: number
pageSize?: number
}
export interface EnrichSearchCompanyEmployeesResponse extends ToolResponse {
output: {
currentPage: number
totalPage: number
pageSize: number
profiles: Array<{
profileIdentifier: string
givenName: string | null
familyName: string | null
currentPosition: string | null
profileImage: string | null
externalProfileUrl: string | null
city: string | null
country: string | null
expertSkills: string[]
}>
}
}
export interface EnrichSearchSimilarCompaniesParams extends EnrichBaseParams {
url: string
accountLocation?: string[]
employeeSizeType?: string
employeeSizeRange?: Array<{ start: number; end: number }>
page?: number
num?: number
}
export interface EnrichSearchSimilarCompaniesResponse extends ToolResponse {
output: {
companies: Array<{
url: string | null
name: string | null
universalName: string | null
type: string | null
description: string | null
phone: string | null
website: string | null
logo: string | null
foundedYear: number | null
staffTotal: number | null
industries: string[]
relevancyScore: number | null
relevancyValue: string | null
}>
}
}
export interface EnrichSalesPointerPeopleParams extends EnrichBaseParams {
page: number
filters: Array<{
type: string
values: Array<{
id: string
text: string
selectionType: 'INCLUDED' | 'EXCLUDED'
}>
selectedSubFilter?: number
}>
}
export interface EnrichSalesPointerPeopleResponse extends ToolResponse {
output: {
data: Array<{
name: string | null
summary: string | null
location: string | null
profilePicture: string | null
linkedInUrn: string | null
positions: Array<{
title: string
company: string
}>
education: Array<{
school: string
degree: string | null
}>
}>
pagination: {
totalCount: number
returnedCount: number
start: number
limit: number
}
}
}
export interface EnrichSearchPostsParams extends EnrichBaseParams {
keywords: string
datePosted?: string
page?: number
}
export interface EnrichSearchPostsResponse extends ToolResponse {
output: {
count: number
posts: Array<{
url: string | null
postId: string | null
author: {
name: string | null
headline: string | null
linkedInUrl: string | null
profileImage: string | null
}
timestamp: string | null
textContent: string | null
hashtags: string[]
mediaUrls: string[]
reactions: number
commentsCount: number
}>
}
}
export interface EnrichGetPostDetailsParams extends EnrichBaseParams {
url: string
}
export interface EnrichGetPostDetailsResponse extends ToolResponse {
output: {
postId: string | null
author: {
name: string | null
headline: string | null
linkedInUrl: string | null
profileImage: string | null
}
timestamp: string | null
textContent: string | null
hashtags: string[]
mediaUrls: string[]
reactions: number
commentsCount: number
}
}
export interface EnrichSearchPostReactionsParams extends EnrichBaseParams {
postUrn: string
reactionType: 'all' | 'like' | 'love' | 'celebrate' | 'insightful' | 'funny'
page: number
}
export interface EnrichSearchPostReactionsResponse extends ToolResponse {
output: {
page: number
totalPage: number
count: number
reactions: Array<{
reactionType: string
reactor: {
name: string | null
subTitle: string | null
profileId: string | null
profilePicture: string | null
linkedInUrl: string | null
}
}>
}
}
export interface EnrichSearchPostCommentsParams extends EnrichBaseParams {
postUrn: string
page?: number
}
export interface EnrichSearchPostCommentsResponse extends ToolResponse {
output: {
page: number
totalPage: number
count: number
comments: Array<{
activityId: string | null
commentary: string | null
linkedInUrl: string | null
commenter: {
profileId: string | null
firstName: string | null
lastName: string | null
subTitle: string | null
profilePicture: string | null
backgroundImage: string | null
entityUrn: string | null
objectUrn: string | null
profileType: string | null
}
reactionBreakdown: {
likes: number
empathy: number
other: number
}
}>
}
}
export interface EnrichSearchPeopleActivitiesParams extends EnrichBaseParams {
profileId: string
activityType: 'posts' | 'comments' | 'articles'
paginationToken?: string
}
export interface EnrichSearchPeopleActivitiesResponse extends ToolResponse {
output: {
paginationToken: string | null
activityType: string
activities: Array<{
activityId: string | null
commentary: string | null
linkedInUrl: string | null
timeElapsed: string | null
numReactions: number | null
author: {
name: string | null
profileId: string | null
profilePicture: string | null
} | null
reactionBreakdown: {
likes: number
empathy: number
other: number
}
attachments: string[]
}>
}
}
export interface EnrichSearchCompanyActivitiesParams extends EnrichBaseParams {
companyId: string
activityType: 'posts' | 'comments' | 'articles'
paginationToken?: string
offset?: number
}
export interface EnrichSearchCompanyActivitiesResponse extends ToolResponse {
output: {
paginationToken: string | null
activityType: string
activities: Array<{
activityId: string | null
commentary: string | null
linkedInUrl: string | null
timeElapsed: string | null
numReactions: number | null
author: {
name: string | null
profileId: string | null
profilePicture: string | null
} | null
reactionBreakdown: {
likes: number
empathy: number
other: number
}
attachments: string[]
}>
}
}
export interface EnrichReverseHashLookupParams extends EnrichBaseParams {
hash: string
}
export interface EnrichReverseHashLookupResponse extends ToolResponse {
output: {
hash: string
email: string | null
displayName: string | null
found: boolean
}
}
export interface EnrichSearchLogoParams extends EnrichBaseParams {
url: string
}
export interface EnrichSearchLogoResponse extends ToolResponse {
output: {
logoUrl: string | null
domain: string
}
}
export interface EnrichSearchJobsParams extends EnrichBaseParams {
keywords: string
location?: string
jobTypes?: string
workplaceTypes?: string
experienceLevels?: string
companyIds?: string
timePosted?: string
start?: number
}
export interface EnrichSearchJobsResponse extends ToolResponse {
output: {
count: number
jobs: Array<{
title: string | null
companyName: string | null
companyLink: string | null
companyLogo: string | null
location: string | null
url: string | null
postedDate: string | null
postedTimestamp: string | null
hiringStatus: string | null
criteria: Record<string, unknown> | null
}>
}
}
export interface EnrichSearchPostReactionsByUrlParams extends EnrichBaseParams {
postUrl: string
reactionType: 'all' | 'like' | 'love' | 'celebrate' | 'insightful' | 'funny'
page: number
}
export interface EnrichSearchPostCommentsByUrlParams extends EnrichBaseParams {
postUrl: string
page?: number
}
+92
View File
@@ -0,0 +1,92 @@
import type { EnrichVerifyEmailParams, EnrichVerifyEmailResponse } from '@/tools/enrich/types'
import type { ToolConfig } from '@/tools/types'
export const verifyEmailTool: ToolConfig<EnrichVerifyEmailParams, EnrichVerifyEmailResponse> = {
id: 'enrich_verify_email',
name: 'Enrich Verify Email',
description:
'Verify an email address for deliverability, including catch-all detection and provider identification.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Enrich API key',
},
email: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Email address to verify (e.g., john.doe@example.com)',
},
},
request: {
url: (params) => {
const url = new URL('https://api.enrich.so/v1/api/verify-email')
url.searchParams.append('email', params.email.trim())
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: {
email: data.email ?? '',
status: data.status ?? '',
result: data.result ?? '',
confidenceScore: data.confidenceScore ?? 0,
smtpProvider: data.smtpProvider ?? null,
mailDisposable: data.mailDisposable ?? false,
mailAcceptAll: data.mailAcceptAll ?? false,
free: data.free ?? false,
},
}
},
outputs: {
email: {
type: 'string',
description: 'Email address verified',
},
status: {
type: 'string',
description: 'Verification status',
},
result: {
type: 'string',
description: 'Deliverability result (deliverable, undeliverable, etc.)',
},
confidenceScore: {
type: 'number',
description: 'Confidence score (0-100)',
},
smtpProvider: {
type: 'string',
description: 'Email service provider (e.g., Google, Microsoft)',
optional: true,
},
mailDisposable: {
type: 'boolean',
description: 'Whether the email is from a disposable provider',
},
mailAcceptAll: {
type: 'boolean',
description: 'Whether the domain is a catch-all domain',
},
free: {
type: 'boolean',
description: 'Whether the email uses a free email service',
},
},
}