orangeslice 2.1.4 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/careers.d.ts +47 -0
- package/dist/careers.js +11 -0
- package/dist/cli.js +0 -0
- package/dist/expansion.js +21 -10
- package/dist/index.d.ts +14 -0
- package/dist/index.js +20 -2
- package/dist/ocean.d.ts +166 -0
- package/dist/ocean.js +23 -0
- package/docs/data-enrichement/index.md +10 -2
- package/docs/integrations/gmail/createDraft.md +54 -0
- package/docs/integrations/gmail/fetchEmails.md +50 -0
- package/docs/integrations/gmail/fetchMessageByMessageId.md +36 -0
- package/docs/integrations/gmail/fetchMessageByThreadId.md +37 -0
- package/docs/integrations/gmail/getProfile.md +37 -0
- package/docs/integrations/gmail/index.md +19 -2
- package/docs/integrations/gmail/listLabels.md +34 -0
- package/docs/integrations/gmail/replyToThread.md +51 -0
- package/docs/integrations/hubspot/createWebhookFlow.md +137 -0
- package/docs/integrations/hubspot/index.md +8 -2
- package/docs/integrations/hubspot/updateFlow.md +13 -14
- package/docs/integrations/hubspot/updateWebhookFlow.md +52 -0
- package/docs/integrations/index.md +64 -2
- package/docs/integrations/salesforce/index.md +4 -0
- package/docs/integrations/salesforce/request.md +58 -0
- package/docs/services/ai/generateObject.ts +7 -3
- package/docs/services/ai/generateText.ts +7 -3
- package/docs/services/builtWith/index.md +2 -2
- package/docs/services/company/findCareersPage.md +137 -0
- package/docs/services/company/findCareersPage.ts +37 -0
- package/docs/services/company/linkedin/enrich.md +47 -2
- package/docs/services/company/scrapeCareersPage.md +150 -0
- package/docs/services/index.md +1 -1
- package/docs/services/person/linkedin/findUrl.md +2 -2
- package/docs/services/web/search.md +29 -14
- package/docs/triggers-runtime.md +26 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -90,8 +90,10 @@ const startups = await services.crunchbase.search({
|
|
|
90
90
|
## Service map
|
|
91
91
|
|
|
92
92
|
- `services.company.linkedin.search/enrich`
|
|
93
|
+
- `services.company.findCareersPage/scrapeCareersPage`
|
|
93
94
|
- `services.crunchbase.search` (returns rows array directly)
|
|
94
95
|
- `services.company.getEmployeesFromLinkedin` (database-only B2B path)
|
|
96
|
+
- `services.ocean.search.companies/people`
|
|
95
97
|
- `services.person.linkedin.search/enrich`
|
|
96
98
|
- `services.web.search/batchSearch`
|
|
97
99
|
- `services.ai.generateObject`
|
|
@@ -106,7 +108,7 @@ const startups = await services.crunchbase.search({
|
|
|
106
108
|
|
|
107
109
|
All service calls go through `post()` in `src/api.ts`.
|
|
108
110
|
|
|
109
|
-
-
|
|
111
|
+
- Execute paths: `https://enrichly-production.up.railway.app/execute/*` and `https://enrichly-production.up.railway.app/ctx/*`
|
|
110
112
|
- Pending responses (`pending: true` / `202`) poll batch-service result endpoints.
|
|
111
113
|
- Polling timeout supports long-running workflows (up to 10 minutes).
|
|
112
114
|
- This package now exposes only batch-backed services.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export interface FindCareersPageParams {
|
|
2
|
+
website?: string;
|
|
3
|
+
url?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface FindCareersPageResult {
|
|
6
|
+
inputUrl: string;
|
|
7
|
+
normalizedWebsiteUrl: string;
|
|
8
|
+
careerPageUrl: string | null;
|
|
9
|
+
pageType: "ats" | "official" | "not_found";
|
|
10
|
+
atsProvider: string | null;
|
|
11
|
+
detectionMethod: "input-ats" | "homepage-ats-link" | "homepage-careers-link" | "deterministic-candidate" | "candidate-ats-link" | "embedded-ats" | "candidate-redirect" | "ats-unverified" | "not-found";
|
|
12
|
+
checkedUrls: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface ScrapeCareersPageParams {
|
|
15
|
+
careersPageUrl?: string;
|
|
16
|
+
url?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ScrapeCareersPageJob {
|
|
19
|
+
id: string;
|
|
20
|
+
title: string;
|
|
21
|
+
url: string;
|
|
22
|
+
applyUrl: string | null;
|
|
23
|
+
location: string | null;
|
|
24
|
+
locations: string[];
|
|
25
|
+
department: string | null;
|
|
26
|
+
team: string | null;
|
|
27
|
+
employmentType: string | null;
|
|
28
|
+
workplaceType: string | null;
|
|
29
|
+
postedAt: string | null;
|
|
30
|
+
postedText: string | null;
|
|
31
|
+
requisitionId: string | null;
|
|
32
|
+
}
|
|
33
|
+
export interface ScrapeCareersPageResult {
|
|
34
|
+
status: "success" | "unsupported_url" | "unsupported_provider";
|
|
35
|
+
inputUrl: string;
|
|
36
|
+
normalizedBoardUrl: string | null;
|
|
37
|
+
atsProvider: string | null;
|
|
38
|
+
companyName: string | null;
|
|
39
|
+
source: "api" | "html" | null;
|
|
40
|
+
totalJobs: number;
|
|
41
|
+
jobs: ScrapeCareersPageJob[];
|
|
42
|
+
checkedUrls: string[];
|
|
43
|
+
supportedProviders: string[];
|
|
44
|
+
message: string | null;
|
|
45
|
+
}
|
|
46
|
+
export declare function findCareersPage(params: FindCareersPageParams): Promise<FindCareersPageResult>;
|
|
47
|
+
export declare function scrapeCareersPage(params: ScrapeCareersPageParams): Promise<ScrapeCareersPageResult>;
|
package/dist/careers.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findCareersPage = findCareersPage;
|
|
4
|
+
exports.scrapeCareersPage = scrapeCareersPage;
|
|
5
|
+
const api_1 = require("./api");
|
|
6
|
+
async function findCareersPage(params) {
|
|
7
|
+
return (0, api_1.post)("/execute/find-careers-page", { ...params });
|
|
8
|
+
}
|
|
9
|
+
async function scrapeCareersPage(params) {
|
|
10
|
+
return (0, api_1.post)("/execute/scrape-careers-page", { ...params });
|
|
11
|
+
}
|
package/dist/cli.js
CHANGED
|
File without changes
|
package/dist/expansion.js
CHANGED
|
@@ -71,17 +71,28 @@ async function companyLinkedinEnrich(params) {
|
|
|
71
71
|
if (!shorthand && !url && !domain) {
|
|
72
72
|
throw new Error("[orangeslice] company.linkedin.enrich: provide shorthand, url, or domain");
|
|
73
73
|
}
|
|
74
|
-
const where = [];
|
|
75
|
-
if (shorthand)
|
|
76
|
-
where.push(`slug = ${sqlString(shorthand)}`);
|
|
77
|
-
if (url)
|
|
78
|
-
where.push(`linkedin_url = ${sqlString(url)}`);
|
|
79
|
-
if (domain)
|
|
80
|
-
where.push(`lower(website) LIKE ${sqlString(`%${domain}%`)}`);
|
|
81
74
|
const fields = extended
|
|
82
|
-
? "
|
|
83
|
-
: "name, slug, website, description, employee_count, follower_count, founded_year, locality, region, country_iso, country_name, type, size, ticker, specialties, linkedin_url, created_at, updated_at";
|
|
84
|
-
|
|
75
|
+
? "lkd.*"
|
|
76
|
+
: "lkd.name, lkd.slug, lkd.website, lkd.description, lkd.employee_count, lkd.follower_count, lkd.founded_year, lkd.locality, lkd.region, lkd.country_iso, lkd.country_name, lkd.type, lkd.size, lkd.ticker, lkd.specialties, lkd.linkedin_url, lkd.created_at, lkd.updated_at";
|
|
77
|
+
let sql;
|
|
78
|
+
if (domain) {
|
|
79
|
+
const bare = domain.replace(/^www\./, "");
|
|
80
|
+
sql = `SELECT ${fields}
|
|
81
|
+
FROM linkedin_company lc
|
|
82
|
+
JOIN lkd_company lkd ON lkd.linkedin_company_id = lc.id
|
|
83
|
+
WHERE lc.domain IN (${sqlString(bare)}, ${sqlString("www." + bare)})
|
|
84
|
+
ORDER BY CASE WHEN lc.website ~ ${sqlString("^https?://(www\\.)?" + bare.replace(/\./g, "\\.") + "(/([a-z]{2}(-[a-z]{2})?)?)?(\\?.*)?/?$")} THEN 0 ELSE 1 END,
|
|
85
|
+
lc.employee_count DESC NULLS LAST
|
|
86
|
+
LIMIT 1`;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
const where = [];
|
|
90
|
+
if (shorthand)
|
|
91
|
+
where.push(`lkd.slug = ${sqlString(shorthand)}`);
|
|
92
|
+
if (url)
|
|
93
|
+
where.push(`lkd.linkedin_url = ${sqlString(url)}`);
|
|
94
|
+
sql = `SELECT ${fields} FROM lkd_company lkd WHERE ${where.join(" OR ")} LIMIT 1`;
|
|
95
|
+
}
|
|
85
96
|
const data = await (0, api_1.post)("/execute/sql", { sql });
|
|
86
97
|
return data.rows?.[0] ?? null;
|
|
87
98
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
export { configure } from "./api";
|
|
2
2
|
export type { OrangesliceConfig } from "./api";
|
|
3
|
+
export { findCareersPage, scrapeCareersPage } from "./careers";
|
|
4
|
+
export type { FindCareersPageParams, FindCareersPageResult, ScrapeCareersPageParams, ScrapeCareersPageResult, ScrapeCareersPageJob } from "./careers";
|
|
3
5
|
export { ctx } from "./ctx";
|
|
4
6
|
export type { Spreadsheet, SpreadsheetListItem, SqlResult, SqlQueryResult, SqlActionResult, RowsAddResult } from "./ctx";
|
|
5
7
|
export { linkedinSearch } from "./b2b";
|
|
6
8
|
export type { LinkedInSearchParams, LinkedInSearchResponse } from "./b2b";
|
|
7
9
|
export { crunchbaseSearch } from "./crunchbase";
|
|
8
10
|
export type { CrunchbaseSearchParams } from "./crunchbase";
|
|
11
|
+
export { executeOcean, oceanSearchCompanies, oceanSearchPeople, OCEAN_OPERATION_IDS } from "./ocean";
|
|
12
|
+
export type { OceanOperationId, OceanCompaniesFilters, OceanPeopleFilters, OceanCompaniesSearchParams, OceanCompaniesSearchResponse, OceanCompanyResult, OceanCompanyMatch, OceanPeopleSearchParams, OceanPeopleSearchResponse, OceanPersonResult } from "./ocean";
|
|
9
13
|
export { webSearch, webBatchSearch } from "./serp";
|
|
10
14
|
export type { WebSearchQuery, WebSearchResult, WebSearchResponse, BatchWebSearchParams } from "./serp";
|
|
11
15
|
export { generateObject } from "./generateObject";
|
|
@@ -25,11 +29,13 @@ export type { PersonLinkedinFindUrlParams, CompanyLinkedinFindUrlParams, PersonC
|
|
|
25
29
|
import { runApifyActor } from "./apify";
|
|
26
30
|
import { linkedinSearch } from "./b2b";
|
|
27
31
|
import { browserExecute } from "./browser";
|
|
32
|
+
import { findCareersPage, scrapeCareersPage } from "./careers";
|
|
28
33
|
import { crunchbaseSearch } from "./crunchbase";
|
|
29
34
|
import { personLinkedinEnrich, personLinkedinFindUrl, personContactGet, companyLinkedinEnrich, companyLinkedinFindUrl, companyGetEmployeesFromLinkedin, geoParseAddress, builtWithLookupDomain, builtWithRelationships, builtWithSearchByTech } from "./expansion";
|
|
30
35
|
import { scrapeWebsite } from "./firecrawl";
|
|
31
36
|
import { generateObject } from "./generateObject";
|
|
32
37
|
import { googleMapsScrape } from "./googleMaps";
|
|
38
|
+
import { oceanSearchCompanies, oceanSearchPeople } from "./ocean";
|
|
33
39
|
import { webBatchSearch, webSearch } from "./serp";
|
|
34
40
|
export declare const services: {
|
|
35
41
|
crunchbase: {
|
|
@@ -42,6 +48,8 @@ export declare const services: {
|
|
|
42
48
|
search: typeof linkedinSearch;
|
|
43
49
|
};
|
|
44
50
|
getEmployeesFromLinkedin: typeof companyGetEmployeesFromLinkedin;
|
|
51
|
+
findCareersPage: typeof findCareersPage;
|
|
52
|
+
scrapeCareersPage: typeof scrapeCareersPage;
|
|
45
53
|
};
|
|
46
54
|
person: {
|
|
47
55
|
linkedin: {
|
|
@@ -75,6 +83,12 @@ export declare const services: {
|
|
|
75
83
|
googleMaps: {
|
|
76
84
|
scrape: typeof googleMapsScrape;
|
|
77
85
|
};
|
|
86
|
+
ocean: {
|
|
87
|
+
search: {
|
|
88
|
+
companies: typeof oceanSearchCompanies;
|
|
89
|
+
people: typeof oceanSearchPeople;
|
|
90
|
+
};
|
|
91
|
+
};
|
|
78
92
|
builtWith: {
|
|
79
93
|
lookupDomain: typeof builtWithLookupDomain;
|
|
80
94
|
relationships: typeof builtWithRelationships;
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.services = exports.builtWithSearchByTech = exports.builtWithRelationships = exports.builtWithLookupDomain = exports.geoParseAddress = exports.companyGetEmployeesFromLinkedin = exports.companyLinkedinFindUrl = exports.companyLinkedinEnrich = exports.personContactGet = exports.personLinkedinFindUrl = exports.personLinkedinEnrich = exports.PREDICT_LEADS_OPERATION_IDS = exports.predictLeads = exports.executePredictLeads = exports.googleMapsScrape = exports.runApifyActor = exports.browserExecute = exports.scrapeWebsite = exports.generateObject = exports.webBatchSearch = exports.webSearch = exports.crunchbaseSearch = exports.linkedinSearch = exports.ctx = exports.configure = void 0;
|
|
3
|
+
exports.services = exports.builtWithSearchByTech = exports.builtWithRelationships = exports.builtWithLookupDomain = exports.geoParseAddress = exports.companyGetEmployeesFromLinkedin = exports.companyLinkedinFindUrl = exports.companyLinkedinEnrich = exports.personContactGet = exports.personLinkedinFindUrl = exports.personLinkedinEnrich = exports.PREDICT_LEADS_OPERATION_IDS = exports.predictLeads = exports.executePredictLeads = exports.googleMapsScrape = exports.runApifyActor = exports.browserExecute = exports.scrapeWebsite = exports.generateObject = exports.webBatchSearch = exports.webSearch = exports.OCEAN_OPERATION_IDS = exports.oceanSearchPeople = exports.oceanSearchCompanies = exports.executeOcean = exports.crunchbaseSearch = exports.linkedinSearch = exports.ctx = exports.scrapeCareersPage = exports.findCareersPage = exports.configure = void 0;
|
|
4
4
|
var api_1 = require("./api");
|
|
5
5
|
Object.defineProperty(exports, "configure", { enumerable: true, get: function () { return api_1.configure; } });
|
|
6
|
+
var careers_1 = require("./careers");
|
|
7
|
+
Object.defineProperty(exports, "findCareersPage", { enumerable: true, get: function () { return careers_1.findCareersPage; } });
|
|
8
|
+
Object.defineProperty(exports, "scrapeCareersPage", { enumerable: true, get: function () { return careers_1.scrapeCareersPage; } });
|
|
6
9
|
var ctx_1 = require("./ctx");
|
|
7
10
|
Object.defineProperty(exports, "ctx", { enumerable: true, get: function () { return ctx_1.ctx; } });
|
|
8
11
|
var b2b_1 = require("./b2b");
|
|
9
12
|
Object.defineProperty(exports, "linkedinSearch", { enumerable: true, get: function () { return b2b_1.linkedinSearch; } });
|
|
10
13
|
var crunchbase_1 = require("./crunchbase");
|
|
11
14
|
Object.defineProperty(exports, "crunchbaseSearch", { enumerable: true, get: function () { return crunchbase_1.crunchbaseSearch; } });
|
|
15
|
+
var ocean_1 = require("./ocean");
|
|
16
|
+
Object.defineProperty(exports, "executeOcean", { enumerable: true, get: function () { return ocean_1.executeOcean; } });
|
|
17
|
+
Object.defineProperty(exports, "oceanSearchCompanies", { enumerable: true, get: function () { return ocean_1.oceanSearchCompanies; } });
|
|
18
|
+
Object.defineProperty(exports, "oceanSearchPeople", { enumerable: true, get: function () { return ocean_1.oceanSearchPeople; } });
|
|
19
|
+
Object.defineProperty(exports, "OCEAN_OPERATION_IDS", { enumerable: true, get: function () { return ocean_1.OCEAN_OPERATION_IDS; } });
|
|
12
20
|
var serp_1 = require("./serp");
|
|
13
21
|
Object.defineProperty(exports, "webSearch", { enumerable: true, get: function () { return serp_1.webSearch; } });
|
|
14
22
|
Object.defineProperty(exports, "webBatchSearch", { enumerable: true, get: function () { return serp_1.webBatchSearch; } });
|
|
@@ -40,11 +48,13 @@ Object.defineProperty(exports, "builtWithSearchByTech", { enumerable: true, get:
|
|
|
40
48
|
const apify_2 = require("./apify");
|
|
41
49
|
const b2b_2 = require("./b2b");
|
|
42
50
|
const browser_2 = require("./browser");
|
|
51
|
+
const careers_2 = require("./careers");
|
|
43
52
|
const crunchbase_2 = require("./crunchbase");
|
|
44
53
|
const expansion_2 = require("./expansion");
|
|
45
54
|
const firecrawl_2 = require("./firecrawl");
|
|
46
55
|
const generateObject_2 = require("./generateObject");
|
|
47
56
|
const googleMaps_2 = require("./googleMaps");
|
|
57
|
+
const ocean_2 = require("./ocean");
|
|
48
58
|
const predictLeads_2 = require("./predictLeads");
|
|
49
59
|
const serp_2 = require("./serp");
|
|
50
60
|
exports.services = {
|
|
@@ -57,7 +67,9 @@ exports.services = {
|
|
|
57
67
|
enrich: expansion_2.companyLinkedinEnrich,
|
|
58
68
|
search: b2b_2.linkedinSearch
|
|
59
69
|
},
|
|
60
|
-
getEmployeesFromLinkedin: expansion_2.companyGetEmployeesFromLinkedin
|
|
70
|
+
getEmployeesFromLinkedin: expansion_2.companyGetEmployeesFromLinkedin,
|
|
71
|
+
findCareersPage: careers_2.findCareersPage,
|
|
72
|
+
scrapeCareersPage: careers_2.scrapeCareersPage
|
|
61
73
|
},
|
|
62
74
|
person: {
|
|
63
75
|
linkedin: {
|
|
@@ -91,6 +103,12 @@ exports.services = {
|
|
|
91
103
|
googleMaps: {
|
|
92
104
|
scrape: googleMaps_2.googleMapsScrape
|
|
93
105
|
},
|
|
106
|
+
ocean: {
|
|
107
|
+
search: {
|
|
108
|
+
companies: ocean_2.oceanSearchCompanies,
|
|
109
|
+
people: ocean_2.oceanSearchPeople
|
|
110
|
+
}
|
|
111
|
+
},
|
|
94
112
|
builtWith: {
|
|
95
113
|
lookupDomain: expansion_2.builtWithLookupDomain,
|
|
96
114
|
relationships: expansion_2.builtWithRelationships,
|
package/dist/ocean.d.ts
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
export declare const OCEAN_OPERATION_IDS: {
|
|
2
|
+
readonly searchCompanies: "search-companies";
|
|
3
|
+
readonly searchPeople: "search-people";
|
|
4
|
+
};
|
|
5
|
+
export type OceanOperationId = (typeof OCEAN_OPERATION_IDS)[keyof typeof OCEAN_OPERATION_IDS];
|
|
6
|
+
export interface OceanCompaniesFilters {
|
|
7
|
+
lookalikeDomains?: string[];
|
|
8
|
+
minScore?: number;
|
|
9
|
+
companySizes?: Array<"0-1" | "2-10" | "11-50" | "51-200" | "201-500" | "501-1000" | "1001-5000" | "5001-10000" | "10001+">;
|
|
10
|
+
countries?: string[];
|
|
11
|
+
industries?: string[];
|
|
12
|
+
technologies?: string[];
|
|
13
|
+
technologyCategories?: string[];
|
|
14
|
+
keywords?: string[];
|
|
15
|
+
revenueRanges?: string[];
|
|
16
|
+
ecommerce?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface OceanPeopleFilters {
|
|
19
|
+
seniorities?: string[];
|
|
20
|
+
departments?: string[];
|
|
21
|
+
jobTitleKeywords?: string[];
|
|
22
|
+
countries?: string[];
|
|
23
|
+
lookalikePeopleIds?: string[];
|
|
24
|
+
}
|
|
25
|
+
export interface OceanCompaniesSearchParams {
|
|
26
|
+
companiesFilters?: OceanCompaniesFilters;
|
|
27
|
+
size?: number;
|
|
28
|
+
from?: number;
|
|
29
|
+
searchAfter?: string;
|
|
30
|
+
includeDomains?: string[];
|
|
31
|
+
excludeDomains?: string[];
|
|
32
|
+
}
|
|
33
|
+
export interface OceanPhone {
|
|
34
|
+
country?: string;
|
|
35
|
+
number: string;
|
|
36
|
+
primary?: boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface OceanMediaProfile {
|
|
39
|
+
url?: string;
|
|
40
|
+
handle?: string;
|
|
41
|
+
name?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface OceanLocation {
|
|
44
|
+
primary?: boolean;
|
|
45
|
+
latitude?: number;
|
|
46
|
+
longitude?: number;
|
|
47
|
+
country?: string;
|
|
48
|
+
locality?: string;
|
|
49
|
+
region?: string;
|
|
50
|
+
postalCode?: string;
|
|
51
|
+
streetAddress?: string;
|
|
52
|
+
state?: string;
|
|
53
|
+
}
|
|
54
|
+
export interface OceanDepartmentSize {
|
|
55
|
+
department: string;
|
|
56
|
+
size: number;
|
|
57
|
+
}
|
|
58
|
+
export interface OceanHeadcountGrowth {
|
|
59
|
+
threeMonths?: number;
|
|
60
|
+
threeMonthsPercentage?: number;
|
|
61
|
+
sixMonths?: number;
|
|
62
|
+
sixMonthsPercentage?: number;
|
|
63
|
+
twelveMonths?: number;
|
|
64
|
+
twelveMonthsPercentage?: number;
|
|
65
|
+
}
|
|
66
|
+
export interface OceanCompanyResult {
|
|
67
|
+
domain: string;
|
|
68
|
+
name?: string;
|
|
69
|
+
legalName?: string;
|
|
70
|
+
description?: string;
|
|
71
|
+
countries?: string[];
|
|
72
|
+
primaryCountry?: string;
|
|
73
|
+
companySize?: string;
|
|
74
|
+
industryCategories?: string[];
|
|
75
|
+
industries?: string[];
|
|
76
|
+
linkedinIndustry?: string;
|
|
77
|
+
ecommerce?: boolean;
|
|
78
|
+
keywords?: string[];
|
|
79
|
+
employeeCountOcean?: number;
|
|
80
|
+
employeeCountLinkedin?: number;
|
|
81
|
+
revenue?: string;
|
|
82
|
+
yearFounded?: number;
|
|
83
|
+
emails?: string[];
|
|
84
|
+
phones?: OceanPhone[];
|
|
85
|
+
logo?: string;
|
|
86
|
+
technologies?: string[];
|
|
87
|
+
technologyCategories?: string[];
|
|
88
|
+
rootUrl?: string;
|
|
89
|
+
medias?: Record<string, OceanMediaProfile>;
|
|
90
|
+
locations?: OceanLocation[];
|
|
91
|
+
departmentSizes?: OceanDepartmentSize[];
|
|
92
|
+
headcountGrowth?: OceanHeadcountGrowth;
|
|
93
|
+
updatedAt?: string;
|
|
94
|
+
}
|
|
95
|
+
export interface OceanCompanyMatch {
|
|
96
|
+
company: OceanCompanyResult;
|
|
97
|
+
relevance?: string;
|
|
98
|
+
}
|
|
99
|
+
export interface OceanCompaniesSearchResponse {
|
|
100
|
+
total: number;
|
|
101
|
+
searchAfter?: string;
|
|
102
|
+
companies: OceanCompanyMatch[];
|
|
103
|
+
redirectMap?: Record<string, string>;
|
|
104
|
+
}
|
|
105
|
+
export interface OceanPersonExperience {
|
|
106
|
+
dateFrom?: string;
|
|
107
|
+
dateTo?: string;
|
|
108
|
+
description?: string;
|
|
109
|
+
domain?: string;
|
|
110
|
+
jobTitle?: string;
|
|
111
|
+
}
|
|
112
|
+
export interface OceanContactField {
|
|
113
|
+
address?: string;
|
|
114
|
+
status?: string;
|
|
115
|
+
}
|
|
116
|
+
export interface OceanPhoneField {
|
|
117
|
+
numbers?: string[];
|
|
118
|
+
status?: string;
|
|
119
|
+
}
|
|
120
|
+
export interface OceanPersonCompanySnapshot {
|
|
121
|
+
companySize?: string;
|
|
122
|
+
logo?: string;
|
|
123
|
+
name?: string;
|
|
124
|
+
}
|
|
125
|
+
export interface OceanPersonResult {
|
|
126
|
+
id: string;
|
|
127
|
+
domain?: string;
|
|
128
|
+
name?: string;
|
|
129
|
+
firstName?: string;
|
|
130
|
+
lastName?: string;
|
|
131
|
+
country?: string;
|
|
132
|
+
state?: string;
|
|
133
|
+
location?: string;
|
|
134
|
+
linkedinUrl?: string;
|
|
135
|
+
seniorities?: string[];
|
|
136
|
+
departments?: string[];
|
|
137
|
+
photo?: string;
|
|
138
|
+
jobTitle?: string;
|
|
139
|
+
jobTitleEnglish?: string;
|
|
140
|
+
currentJobDescription?: string;
|
|
141
|
+
experiences?: OceanPersonExperience[];
|
|
142
|
+
summary?: string;
|
|
143
|
+
skills?: string[];
|
|
144
|
+
phone?: OceanPhoneField;
|
|
145
|
+
email?: OceanContactField;
|
|
146
|
+
updatedAt?: string;
|
|
147
|
+
company?: OceanPersonCompanySnapshot;
|
|
148
|
+
}
|
|
149
|
+
export interface OceanPeopleSearchParams {
|
|
150
|
+
companiesFilters?: OceanCompaniesFilters;
|
|
151
|
+
peopleFilters?: OceanPeopleFilters;
|
|
152
|
+
size?: number;
|
|
153
|
+
from?: number;
|
|
154
|
+
searchAfter?: string;
|
|
155
|
+
enableEmailSearch?: boolean;
|
|
156
|
+
enablePhoneSearch?: boolean;
|
|
157
|
+
}
|
|
158
|
+
export interface OceanPeopleSearchResponse {
|
|
159
|
+
total: number;
|
|
160
|
+
searchAfter?: string;
|
|
161
|
+
people: OceanPersonResult[];
|
|
162
|
+
redirectMap?: Record<string, string>;
|
|
163
|
+
}
|
|
164
|
+
export declare function executeOcean<T = unknown>(operationId: OceanOperationId, params?: Record<string, unknown>): Promise<T>;
|
|
165
|
+
export declare function oceanSearchCompanies(params: OceanCompaniesSearchParams): Promise<OceanCompaniesSearchResponse>;
|
|
166
|
+
export declare function oceanSearchPeople(params: OceanPeopleSearchParams): Promise<OceanPeopleSearchResponse>;
|
package/dist/ocean.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OCEAN_OPERATION_IDS = void 0;
|
|
4
|
+
exports.executeOcean = executeOcean;
|
|
5
|
+
exports.oceanSearchCompanies = oceanSearchCompanies;
|
|
6
|
+
exports.oceanSearchPeople = oceanSearchPeople;
|
|
7
|
+
const api_1 = require("./api");
|
|
8
|
+
exports.OCEAN_OPERATION_IDS = {
|
|
9
|
+
searchCompanies: "search-companies",
|
|
10
|
+
searchPeople: "search-people"
|
|
11
|
+
};
|
|
12
|
+
async function executeOcean(operationId, params) {
|
|
13
|
+
return (0, api_1.post)("/execute/oceanio", {
|
|
14
|
+
operationId,
|
|
15
|
+
params: params ?? {}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
async function oceanSearchCompanies(params) {
|
|
19
|
+
return executeOcean(exports.OCEAN_OPERATION_IDS.searchCompanies, params);
|
|
20
|
+
}
|
|
21
|
+
async function oceanSearchPeople(params) {
|
|
22
|
+
return executeOcean(exports.OCEAN_OPERATION_IDS.searchPeople, params);
|
|
23
|
+
}
|
|
@@ -5,12 +5,18 @@ description: Patterns for enriching company data, tech stack detection, hiring d
|
|
|
5
5
|
|
|
6
6
|
# Data Enrichment
|
|
7
7
|
|
|
8
|
-
Standard pattern: **Search → Scrape → Extract**
|
|
8
|
+
Standard pattern: **Search/Domain → Scrape → Extract**
|
|
9
9
|
|
|
10
|
-
1. `web.search` with `site:` to find
|
|
10
|
+
1. Start with a company `domain` when you already have it, otherwise use `web.search` with `site:` to find relevant pages
|
|
11
11
|
2. `scrape.website` to get page content as markdown
|
|
12
12
|
3. `ai.generateObject` to extract structured fields
|
|
13
13
|
|
|
14
|
+
For company enrichment/classification, prefer the website over LinkedIn `industry`.
|
|
15
|
+
|
|
16
|
+
- LinkedIn `industry` is acceptable as lightweight lookup context
|
|
17
|
+
- LinkedIn `industry` is too sparse/generic to be your main enrichment signal
|
|
18
|
+
- Preferred workflow: `domain` -> `scrape.website` -> `ai.generateObject`
|
|
19
|
+
|
|
14
20
|
---
|
|
15
21
|
|
|
16
22
|
## Example: Does this law firm handle medical malpractice?
|
|
@@ -42,6 +48,8 @@ async function checkMedMalPractice(domain: string) {
|
|
|
42
48
|
|
|
43
49
|
---
|
|
44
50
|
|
|
51
|
+
---
|
|
52
|
+
|
|
45
53
|
## When to Use
|
|
46
54
|
|
|
47
55
|
| Use Search → Scrape → Extract | Use `browser.execute` instead |
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# createDraft
|
|
2
|
+
|
|
3
|
+
Create a Gmail draft without sending it yet.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
// Create a new draft
|
|
7
|
+
const draft = await integrations.gmail.createDraft({
|
|
8
|
+
recipient_email: "jane@example.com",
|
|
9
|
+
subject: "Draft follow-up",
|
|
10
|
+
body: "Sharing a quick follow-up before I send this."
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
// Draft a reply in an existing thread
|
|
14
|
+
await integrations.gmail.createDraft({
|
|
15
|
+
thread_id: "19bf77729bcb3a44",
|
|
16
|
+
body: "Thanks for the update. I will review this today."
|
|
17
|
+
});
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Input
|
|
21
|
+
|
|
22
|
+
| Parameter | Type | Required | Description |
|
|
23
|
+
| ------------------ | ---------- | -------- | -------------------------------------------- |
|
|
24
|
+
| `recipient_email` | `string` | No | Primary `To` recipient |
|
|
25
|
+
| `extra_recipients` | `string[]` | No | Additional `To` recipients |
|
|
26
|
+
| `cc` | `string[]` | No | CC recipients |
|
|
27
|
+
| `bcc` | `string[]` | No | BCC recipients |
|
|
28
|
+
| `subject` | `string` | No | Draft subject |
|
|
29
|
+
| `body` | `string` | No | Draft body content |
|
|
30
|
+
| `message_body` | `string` | No | Alternate body field accepted by some tools |
|
|
31
|
+
| `is_html` | `boolean` | No | Set to `true` when `body` contains HTML |
|
|
32
|
+
| `attachment` | `object` | No | Optional attachment payload |
|
|
33
|
+
| `thread_id` | `string` | No | Existing thread to draft a reply into |
|
|
34
|
+
| `from_email` | `string` | No | Optional verified send-as alias |
|
|
35
|
+
| `user_id` | `string` | No | Gmail user id (`\"me\"` by default) |
|
|
36
|
+
|
|
37
|
+
## Output
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
{
|
|
41
|
+
successful: boolean;
|
|
42
|
+
data?: {
|
|
43
|
+
id?: string;
|
|
44
|
+
draft_id?: string;
|
|
45
|
+
message?: GmailMessage;
|
|
46
|
+
};
|
|
47
|
+
error?: string;
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Notes
|
|
52
|
+
|
|
53
|
+
- Creating a draft is a mutating action and should be used intentionally
|
|
54
|
+
- If you pass `thread_id`, leave `subject` empty to stay in the existing thread
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# fetchEmails
|
|
2
|
+
|
|
3
|
+
Fetch inbox messages or Gmail search results from the connected account.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
// Read the current inbox
|
|
7
|
+
const inbox = await integrations.gmail.fetchEmails({
|
|
8
|
+
query: "in:inbox",
|
|
9
|
+
max_results: 10
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
// Search for unread emails from a sender
|
|
13
|
+
const unread = await integrations.gmail.fetchEmails({
|
|
14
|
+
query: "in:inbox is:unread from:alice@example.com",
|
|
15
|
+
max_results: 25
|
|
16
|
+
});
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Input
|
|
20
|
+
|
|
21
|
+
| Parameter | Type | Required | Description |
|
|
22
|
+
| --------------------- | ---------- | -------- | ----------------------------------------------------- |
|
|
23
|
+
| `query` | `string` | No | Gmail search query such as `in:inbox is:unread` |
|
|
24
|
+
| `verbose` | `boolean` | No | Fetch richer message details |
|
|
25
|
+
| `ids_only` | `boolean` | No | Only return message/thread identifiers |
|
|
26
|
+
| `label_ids` | `string[]` | No | Filter by Gmail label IDs |
|
|
27
|
+
| `page_token` | `string` | No | Pagination token from a previous call |
|
|
28
|
+
| `max_results` | `number` | No | Maximum messages to fetch in this page |
|
|
29
|
+
| `include_payload` | `boolean` | No | Include payload/body data when available |
|
|
30
|
+
| `include_spam_trash` | `boolean` | No | Include spam and trash |
|
|
31
|
+
| `user_id` | `string` | No | Gmail user id (`\"me\"` by default) |
|
|
32
|
+
|
|
33
|
+
## Output
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
{
|
|
37
|
+
successful: boolean;
|
|
38
|
+
data?: {
|
|
39
|
+
messages?: GmailMessage[];
|
|
40
|
+
nextPageToken?: string;
|
|
41
|
+
resultSizeEstimate?: number;
|
|
42
|
+
};
|
|
43
|
+
error?: string;
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Notes
|
|
48
|
+
|
|
49
|
+
- Results are not guaranteed to be sorted by recency, so sort client-side if order matters
|
|
50
|
+
- For large mailboxes, fetch IDs first and then hydrate specific messages with `fetchMessageByMessageId(...)`
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# fetchMessageByMessageId
|
|
2
|
+
|
|
3
|
+
Fetch a single Gmail message by its Gmail API message ID.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
const message = await integrations.gmail.fetchMessageByMessageId({
|
|
7
|
+
message_id: "19b11732c1b578fd",
|
|
8
|
+
format: "full"
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
console.log(message.data?.subject);
|
|
12
|
+
console.log(message.data?.threadId);
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Input
|
|
16
|
+
|
|
17
|
+
| Parameter | Type | Required | Description |
|
|
18
|
+
| ------------- | ----------------------------------------- | -------- | -------------------------------------- |
|
|
19
|
+
| `message_id` | `string` | Yes | Gmail API message ID |
|
|
20
|
+
| `format` | `\"minimal\" | \"full\" | \"raw\" | \"metadata\"` | No | Response format |
|
|
21
|
+
| `user_id` | `string` | No | Gmail user id (`\"me\"` by default) |
|
|
22
|
+
|
|
23
|
+
## Output
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
{
|
|
27
|
+
successful: boolean;
|
|
28
|
+
data?: GmailMessage;
|
|
29
|
+
error?: string;
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Notes
|
|
34
|
+
|
|
35
|
+
- Use real Gmail `message_id` values returned by Gmail list/search actions
|
|
36
|
+
- `format: "full"` is best when you need headers, payload parts, or body data
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# fetchMessageByThreadId
|
|
2
|
+
|
|
3
|
+
Fetch all messages belonging to a Gmail thread.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
const thread = await integrations.gmail.fetchMessageByThreadId({
|
|
7
|
+
thread_id: "19bf77729bcb3a44"
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
for (const message of thread.data?.messages || []) {
|
|
11
|
+
console.log(message.subject);
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Input
|
|
16
|
+
|
|
17
|
+
| Parameter | Type | Required | Description |
|
|
18
|
+
| ------------ | -------- | -------- | ----------------------------------- |
|
|
19
|
+
| `thread_id` | `string` | Yes | Gmail API thread ID |
|
|
20
|
+
| `user_id` | `string` | No | Gmail user id (`\"me\"` by default) |
|
|
21
|
+
|
|
22
|
+
## Output
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
{
|
|
26
|
+
successful: boolean;
|
|
27
|
+
data?: {
|
|
28
|
+
messages?: GmailMessage[];
|
|
29
|
+
};
|
|
30
|
+
error?: string;
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Notes
|
|
35
|
+
|
|
36
|
+
- Message order is not guaranteed, so sort by `internalDate` if you need oldest/newest order
|
|
37
|
+
- Read threads first before calling `replyToThread(...)` so you have the correct `thread_id`
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# getProfile
|
|
2
|
+
|
|
3
|
+
Read Gmail profile metadata for the connected account.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
const profile = await integrations.gmail.getProfile();
|
|
7
|
+
|
|
8
|
+
console.log(profile.data?.emailAddress);
|
|
9
|
+
console.log(profile.data?.messagesTotal);
|
|
10
|
+
console.log(profile.data?.threadsTotal);
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Input
|
|
14
|
+
|
|
15
|
+
| Parameter | Type | Required | Description |
|
|
16
|
+
| --------- | -------- | -------- | ----------------------------------- |
|
|
17
|
+
| `user_id` | `string` | No | Gmail user id (`\"me\"` by default) |
|
|
18
|
+
|
|
19
|
+
## Output
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
{
|
|
23
|
+
successful: boolean;
|
|
24
|
+
data?: {
|
|
25
|
+
emailAddress?: string;
|
|
26
|
+
messagesTotal?: number;
|
|
27
|
+
threadsTotal?: number;
|
|
28
|
+
historyId?: string;
|
|
29
|
+
};
|
|
30
|
+
error?: string;
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Notes
|
|
35
|
+
|
|
36
|
+
- This is a lightweight way to confirm which mailbox is connected
|
|
37
|
+
- Mailbox totals are useful for diagnostics, health checks, and quick account introspection
|