From bd888ec283de9cf0583675391efb665adc74286d Mon Sep 17 00:00:00 2001 From: Michelle Bergeron Date: Fri, 20 Jun 2025 14:58:14 -0400 Subject: [PATCH 1/3] new components --- .../find-email-linkedin.mjs | 65 ++++++++++++++++++ .../find-email-news-article.mjs | 51 ++++++++++++++ .../find-email-professional.mjs | 64 ++++++++++++++++++ .../get-single-task/get-single-task.mjs | 27 ++++++++ components/finalscout/common/utils.mjs | 25 +++++++ components/finalscout/finalscout.app.mjs | 66 +++++++++++++++++-- components/finalscout/package.json | 7 +- 7 files changed, 299 insertions(+), 6 deletions(-) create mode 100644 components/finalscout/actions/find-email-linkedin/find-email-linkedin.mjs create mode 100644 components/finalscout/actions/find-email-news-article/find-email-news-article.mjs create mode 100644 components/finalscout/actions/find-email-professional/find-email-professional.mjs create mode 100644 components/finalscout/actions/get-single-task/get-single-task.mjs create mode 100644 components/finalscout/common/utils.mjs diff --git a/components/finalscout/actions/find-email-linkedin/find-email-linkedin.mjs b/components/finalscout/actions/find-email-linkedin/find-email-linkedin.mjs new file mode 100644 index 0000000000000..72c98c7d3ac91 --- /dev/null +++ b/components/finalscout/actions/find-email-linkedin/find-email-linkedin.mjs @@ -0,0 +1,65 @@ +import finalscout from "../../finalscout.app.mjs"; +import { parseObject } from "../../common/utils.mjs"; + +export default { + key: "finalscout-find-email-linkedin", + name: "Find Email from LinkedIn", + description: "Finds an email address from a LinkedIn profile URL. [See the documentation](https://finalscout.com/public/doc/api.html#tag/Single-Find/paths/~1v1~1find~1linkedin~1single/post)", + version: "0.0.1", + type: "action", + props: { + finalscout, + url: { + type: "string", + label: "LinkedIn Profile URL", + description: "The URL of the LinkedIn profile.", + }, + tags: { + propDefinition: [ + finalscout, + "tags", + ], + }, + metadata: { + propDefinition: [ + finalscout, + "metadata", + ], + }, + enablePersonalEmail: { + type: "boolean", + label: "Enable Personal Email", + description: "Whether to find personal emails (e.g. john@gmail.com) when a professional email address is not found", + optional: true, + }, + enableGenericEmail: { + type: "boolean", + label: "Enable Generic Email", + description: "Whether to find generic emails (e.g. john@gmail.com) when a professional email address is not found", + optional: true, + }, + webhookUrl: { + propDefinition: [ + finalscout, + "webhookUrl", + ], + }, + }, + async run({ $ }) { + const response = await this.finalscout.findEmailViaLinkedIn({ + $, + data: { + person: { + linkedin_url: this.url, + }, + tags: this.tags, + metadata: parseObject(this.metadata), + enable_personal_email: this.enablePersonalEmail, + enable_generic_email: this.enableGenericEmail, + webhook_url: this.webhookUrl, + }, + }); + $.export("$summary", "Successfully requested email for LinkedIn profile."); + return response; + }, +}; diff --git a/components/finalscout/actions/find-email-news-article/find-email-news-article.mjs b/components/finalscout/actions/find-email-news-article/find-email-news-article.mjs new file mode 100644 index 0000000000000..0825514456400 --- /dev/null +++ b/components/finalscout/actions/find-email-news-article/find-email-news-article.mjs @@ -0,0 +1,51 @@ +import finalscout from "../../finalscout.app.mjs"; +import { parseObject } from "../../common/utils.mjs"; + +export default { + key: "finalscout-find-email-news-article", + name: "Find Email from News Article", + description: "Finds an email address from a news article URL. [See the documentation](https://finalscout.com/public/doc/api.html#tag/Single-Find/paths/~1v1~1find~1author~1single/post)", + version: "0.0.1", + type: "action", + props: { + finalscout, + url: { + type: "string", + label: "News Article URL", + description: "The URL of the news article.", + }, + tags: { + propDefinition: [ + finalscout, + "tags", + ], + }, + metadata: { + propDefinition: [ + finalscout, + "metadata", + ], + }, + webhookUrl: { + propDefinition: [ + finalscout, + "webhookUrl", + ], + }, + }, + async run({ $ }) { + const response = await this.finalscout.findEmailViaNewsArticle({ + $, + data: { + person: { + article_url: this.url, + }, + tags: this.tags, + metadata: parseObject(this.metadata), + webhook_url: this.webhookUrl, + }, + }); + $.export("$summary", "Successfully requested email for news article."); + return response; + }, +}; diff --git a/components/finalscout/actions/find-email-professional/find-email-professional.mjs b/components/finalscout/actions/find-email-professional/find-email-professional.mjs new file mode 100644 index 0000000000000..93d2783b6dd42 --- /dev/null +++ b/components/finalscout/actions/find-email-professional/find-email-professional.mjs @@ -0,0 +1,64 @@ +import finalscout from "../../finalscout.app.mjs"; +import { parseObject } from "../../common/utils.mjs"; + +export default { + key: "finalscout-find-email-professional", + name: "Find Email from Professional", + description: "Finds an email address from a person's name and company/domain. [See the documentation](https://finalscout.com/public/doc/api.html#tag/Single-Find/operation/email_finder_v1_person_email_finder_post)", + version: "0.0.1", + type: "action", + props: { + finalscout, + fullName: { + type: "string", + label: "Full Name", + description: "The full name of the contact", + }, + domain: { + type: "string", + label: "Company Domain", + description: "The company domain for the contact", + }, + deepVerify: { + type: "boolean", + label: "Deep Verify", + description: "Whether to perform a deep verification of the email address", + optional: true, + }, + tags: { + propDefinition: [ + finalscout, + "tags", + ], + }, + metadata: { + propDefinition: [ + finalscout, + "metadata", + ], + }, + webhookUrl: { + propDefinition: [ + finalscout, + "webhookUrl", + ], + }, + }, + async run({ $ }) { + const response = await this.finalscout.findEmailProfessional({ + $, + data: { + person: { + full_name: this.fullName, + domain: this.domain, + deep_verify: this.deepVerify, + }, + tags: this.tags, + metadata: parseObject(this.metadata), + webhook_url: this.webhookUrl, + }, + }); + $.export("$summary", "Successfully requested email for professional."); + return response; + }, +}; diff --git a/components/finalscout/actions/get-single-task/get-single-task.mjs b/components/finalscout/actions/get-single-task/get-single-task.mjs new file mode 100644 index 0000000000000..5f5884bc46edd --- /dev/null +++ b/components/finalscout/actions/get-single-task/get-single-task.mjs @@ -0,0 +1,27 @@ +import finalscout from "../../finalscout.app.mjs"; + +export default { + key: "finalscout-get-single-task", + name: "Get Single Task", + description: "Get the task status for any Single Find task. [See the documentation](https://finalscout.com/public/doc/api.html#tag/Single-Find/paths/~1v1~1find~1single~1status/get)", + version: "0.0.1", + type: "action", + props: { + finalscout, + id: { + type: "string", + label: "Task ID", + description: "The ID of the task to get the status for", + }, + }, + async run({ $ }) { + const response = await this.finalscout.getSingleTask({ + $, + params: { + id: this.id, + }, + }); + $.export("$summary", `Successfully retrieved status for task with ID: ${this.id}`); + return response; + }, +}; diff --git a/components/finalscout/common/utils.mjs b/components/finalscout/common/utils.mjs new file mode 100644 index 0000000000000..2b06bbed266b5 --- /dev/null +++ b/components/finalscout/common/utils.mjs @@ -0,0 +1,25 @@ +export const parseObject = (obj) => { + if (!obj) { + return undefined; + } + if (typeof obj === "string") { + try { + return JSON.parse(obj); + } catch (e) { + return undefined; + } + } + if (Array.isArray(obj)) { + return obj.map(parseObject); + } + if (typeof obj === "object") { + return Object.fromEntries(Object.entries(obj).map(([ + key, + value, + ]) => [ + key, + parseObject(value), + ])); + } + return obj; +}; diff --git a/components/finalscout/finalscout.app.mjs b/components/finalscout/finalscout.app.mjs index a0f7f37915684..806ca2a0cabe4 100644 --- a/components/finalscout/finalscout.app.mjs +++ b/components/finalscout/finalscout.app.mjs @@ -1,11 +1,69 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "finalscout", - propDefinitions: {}, + propDefinitions: { + tags: { + type: "string[]", + label: "Tags", + description: "Use tags to organize your contacts in FinalScout web app", + optional: true, + }, + webhookUrl: { + type: "string", + label: "Webhook URL", + description: "A URL to receive the webhook event for this task. A webhook event will be sent to the URL when the task is completed, regardless of whether an email is found or not", + optional: true, + }, + metadata: { + type: "object", + label: "Metadata", + description: "Use this param to send custom meta data (like contact id) associated with the contact. The custom data will be returned in the response and webhook event.", + optional: true, + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return "https://api.finalscout.com/v1"; + }, + _makeRequest({ + $ = this, path, ...opts + }) { + return axios($, { + url: `${this._baseUrl()}${path}`, + headers: { + Authorization: this.$auth.api_key, + }, + ...opts, + }); + }, + findEmailViaLinkedIn(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/find/linkedin/single", + ...opts, + }); + }, + findEmailViaNewsArticle(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/find/author/single", + ...opts, + }); + }, + findEmailProfessional(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/find/professional/single", + ...opts, + }); + }, + getSingleTask(opts = {}) { + return this._makeRequest({ + path: "/find/single/status", + ...opts, + }); }, }, }; diff --git a/components/finalscout/package.json b/components/finalscout/package.json index 52889e69b22cd..e9d0c9c625d9b 100644 --- a/components/finalscout/package.json +++ b/components/finalscout/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/finalscout", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream FinalScout Components", "main": "finalscout.app.mjs", "keywords": [ @@ -11,5 +11,8 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.1.0" } -} \ No newline at end of file +} From b601e1e28044ecb6f2954c509047d69cda3e59fc Mon Sep 17 00:00:00 2001 From: Michelle Bergeron Date: Fri, 20 Jun 2025 14:58:55 -0400 Subject: [PATCH 2/3] pnpm-lock.yaml --- pnpm-lock.yaml | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 96ee5db69210c..e76eb1a67a105 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1124,8 +1124,7 @@ importers: components/avochato: {} - components/avosms: - specifiers: {} + components/avosms: {} components/aweber: dependencies: @@ -2853,8 +2852,7 @@ importers: components/common_paper: {} - components/commonninja: - specifiers: {} + components/commonninja: {} components/commpeak: dependencies: @@ -4615,7 +4613,11 @@ importers: components/finage: {} - components/finalscout: {} + components/finalscout: + dependencies: + '@pipedream/platform': + specifier: ^3.1.0 + version: 3.1.0 components/findymail: dependencies: @@ -6774,8 +6776,7 @@ importers: specifier: ^1.1.1 version: 1.6.6 - components/ipstack: - specifiers: {} + components/ipstack: {} components/iqair_airvisual: {} @@ -9313,8 +9314,7 @@ importers: specifier: ^17.0.45 version: 17.0.45 - components/openai_passthrough: - specifiers: {} + components/openai_passthrough: {} components/opencage: dependencies: @@ -9913,8 +9913,7 @@ importers: specifier: ^1.5.1 version: 1.6.6 - components/phonely: - specifiers: {} + components/phonely: {} components/php_point_of_sale: dependencies: @@ -10403,8 +10402,7 @@ importers: components/predictleads: {} - components/predis_ai: - specifiers: {} + components/predis_ai: {} components/prepr_graphql: {} @@ -10565,8 +10563,7 @@ importers: specifier: ^3.0.0 version: 3.0.3 - components/prompthub: - specifiers: {} + components/prompthub: {} components/promptmate_io: {} @@ -13433,8 +13430,7 @@ importers: components/test_apps_for_switching_appslug_009: {} - components/test_apps_for_switching_appslug_025: - specifiers: {} + components/test_apps_for_switching_appslug_025: {} components/testlocally: dependencies: From b7e8c3243e9cebdf68e5d9e7e824dd8560178bbc Mon Sep 17 00:00:00 2001 From: Michelle Bergeron Date: Fri, 20 Jun 2025 15:09:24 -0400 Subject: [PATCH 3/3] update --- .../actions/find-email-linkedin/find-email-linkedin.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/finalscout/actions/find-email-linkedin/find-email-linkedin.mjs b/components/finalscout/actions/find-email-linkedin/find-email-linkedin.mjs index 72c98c7d3ac91..4a49d21fb9ff1 100644 --- a/components/finalscout/actions/find-email-linkedin/find-email-linkedin.mjs +++ b/components/finalscout/actions/find-email-linkedin/find-email-linkedin.mjs @@ -35,7 +35,7 @@ export default { enableGenericEmail: { type: "boolean", label: "Enable Generic Email", - description: "Whether to find generic emails (e.g. john@gmail.com) when a professional email address is not found", + description: "Whether to find generic emails (e.g. support@company.com) when a professional email address is not found", optional: true, }, webhookUrl: {