@pipedream/voilanorbert 0.0.2 → 0.0.3

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 CHANGED
@@ -1,20 +1,11 @@
1
1
  # Overview
2
2
 
3
- VoilaNorbert is the easiest way to find the most accurate email addresses and
4
- contact info in a few seconds. Thanks to its powerful API, you can quickly
5
- access information and create custom applications to help you get the data you
6
- need and make the best use of that information.
3
+ VoilaNorbert is a potent tool for finding and verifying email addresses. With its API, you can automate processes like enriching leads with verified contact information, streamlining your email outreach, and maintaining the health of your email lists. The API's main features include searching for email addresses based on names and domains, verifying email deliverability, and managing your contacts. When used within Pipedream, you can leverage these capabilities to create workflows that respond to events, integrate with other services, and process data in real time.
7
4
 
8
- The VoilaNorbert API can help you with many tasks, including:
5
+ # Example Use Cases
9
6
 
10
- - Building contact pages and customer lists
11
- - Generating personalized lead reports
12
- - Creating targeted campaigns for customers and prospects
13
- - Improving customer segmentation and list management
14
- - Validating customer contact information
15
- - Enhancing customer data for use in marketing
16
- - Automating lead verification processes
17
- - Integrating email address data into customer relationship management (CRM)
18
- systems
19
- - Identifying customer contacts from web interactions
20
- - Enhancing existing customer contact databases with additional details
7
+ - **Lead Enrichment Workflow**: Triggered by a new entry on a Google Sheet (containing names and companies), this workflow uses VoilaNorbert to find corresponding email addresses, verifies them to ensure deliverability, and then updates the Google Sheet with the new data. This automation keeps your lead database fresh and actionable.
8
+
9
+ - **Email Verification on Signup**: When a new user signs up through a website form, VoilaNorbert is employed to verify the email address provided. If verified, the user's information is added to a CRM like Salesforce, and a welcome email is sent via SendGrid. This process ensures that you're capturing genuine leads without manual vetting.
10
+
11
+ - **Periodic Email List Cleaning**: A scheduled workflow runs monthly, fetching email addresses from an email marketing platform like Mailchimp. It uses VoilaNorbert to verify and clean the list, removing invalid emails automatically. The cleaned list is then re-uploaded to Mailchimp, optimizing your email campaign's deliverability and engagement rates.
@@ -0,0 +1,15 @@
1
+ import voilanorbert from "../../voilanorbert.app.mjs";
2
+
3
+ export default {
4
+ type: "action",
5
+ props: {
6
+ voilanorbert,
7
+ },
8
+ async run({ $ }) {
9
+ const response = await this.processEvent({
10
+ $,
11
+ });
12
+
13
+ $.export("$summary", this.getSummary(response));
14
+ },
15
+ };
@@ -0,0 +1,32 @@
1
+ import common from "../common/base.mjs";
2
+
3
+ export default {
4
+ ...common,
5
+ key: "voilanorbert-find-contact",
6
+ name: "Find Contact",
7
+ description: "This action returns a specific contact. The object email is either null when the email is not found, or contains an object with at least email (the email string) and the score. [See the docs here](https://api.voilanorbert.com/2018-01-08/#contacts-get-1)",
8
+ version: "0.0.2",
9
+ type: "action",
10
+ props: {
11
+ ...common.props,
12
+ contactId: {
13
+ propDefinition: [
14
+ common.props.voilanorbert,
15
+ "contactId",
16
+ ],
17
+ },
18
+ },
19
+ methods: {
20
+ async processEvent() {
21
+ const { contactId } = this;
22
+ return this.voilanorbert.getContact({
23
+ contactId,
24
+ });
25
+ },
26
+ getSummary({
27
+ name, email,
28
+ }) {
29
+ return `Contact '${name ?? email.email}' Successfully fetched!`;
30
+ },
31
+ },
32
+ };
@@ -0,0 +1,88 @@
1
+ import common from "../common/base.mjs";
2
+ import { ConfigurationError } from "@pipedream/platform";
3
+
4
+ export default {
5
+ ...common,
6
+ key: "voilanorbert-start-contact-search",
7
+ name: "Start Contact Search",
8
+ description: `Search emails are based on the full name plus the domain or company name.
9
+ When your account does not have sufficient credits an HTTP status code of 402 is returned.
10
+ Also, take into consideration that we check the domain for its validity. So even if you provide a correct name+domain set, we may return a HTTP status code of 400 for the domain if we can't locate it.
11
+ [See the docs here](https://api.voilanorbert.com/2018-01-08/#search-endpoint-post)`,
12
+ version: "0.0.2",
13
+ type: "action",
14
+ props: {
15
+ ...common.props,
16
+ name: {
17
+ propDefinition: [
18
+ common.props.voilanorbert,
19
+ "name",
20
+ ],
21
+ },
22
+ domain: {
23
+ propDefinition: [
24
+ common.props.voilanorbert,
25
+ "domain",
26
+ ],
27
+ optional: true,
28
+ },
29
+ company: {
30
+ propDefinition: [
31
+ common.props.voilanorbert,
32
+ "company",
33
+ ],
34
+ optional: true,
35
+ },
36
+ listId: {
37
+ propDefinition: [
38
+ common.props.voilanorbert,
39
+ "listId",
40
+ ],
41
+ optional: true,
42
+ },
43
+ webhookUrl: {
44
+ type: "string",
45
+ label: "Webhook URL",
46
+ description: "The URL to send the webhook to. Required for Pipedream Connect. If not specified, the workflow will be suspended until verification results are returned.",
47
+ optional: true,
48
+ },
49
+ },
50
+ methods: {
51
+ async processEvent({ $ }) {
52
+ if (!this.domain && !this.company) {
53
+ throw new ConfigurationError("Either domain or company is required.");
54
+ }
55
+
56
+ const { resume_url } = this.webhookUrl
57
+ ? {
58
+ resume_url: this.webhookUrl,
59
+ }
60
+ : $.flow
61
+ ? $.flow.suspend()
62
+ : {
63
+ resume_url: undefined,
64
+ };
65
+ if (!resume_url) {
66
+ throw new ConfigurationError("Webhook URL is required for Pipedream Connect.");
67
+ }
68
+
69
+ const {
70
+ name,
71
+ domain,
72
+ company,
73
+ listId,
74
+ } = this;
75
+
76
+ return this.voilanorbert.startContactSearch({
77
+ name,
78
+ domain,
79
+ company,
80
+ webhook: resume_url,
81
+ list_id: listId,
82
+ });
83
+ },
84
+ getSummary() {
85
+ return "Contact Search Successfully fetched!";
86
+ },
87
+ },
88
+ };
@@ -0,0 +1,52 @@
1
+ import common from "../common/base.mjs";
2
+ import { ConfigurationError } from "@pipedream/platform";
3
+
4
+ export default {
5
+ ...common,
6
+ key: "voilanorbert-verifiy-email",
7
+ name: "Verify Email",
8
+ description: `Verifies the given list of emails.
9
+ In case your account does not have a sufficient Verify API balance the service will try to auto refill the balance by charging using the billing details of the account. If it fails to charge, an HTTP status code of 402 will be returned.
10
+ [See the docs here](https://api.voilanorbert.com/2018-01-08/#verify-endpoint-post)`,
11
+ version: "0.0.2",
12
+ type: "action",
13
+ props: {
14
+ ...common.props,
15
+ emails: {
16
+ propDefinition: [
17
+ common.props.voilanorbert,
18
+ "emails",
19
+ ],
20
+ },
21
+ webhookUrl: {
22
+ type: "string",
23
+ label: "Webhook URL",
24
+ description: "The URL to send the webhook to. Required for Pipedream Connect. If not specified, the workflow will be suspended until verification results are returned.",
25
+ optional: true,
26
+ },
27
+ },
28
+ methods: {
29
+ async processEvent({ $ }) {
30
+ const { resume_url } = this.webhookUrl
31
+ ? {
32
+ resume_url: this.webhookUrl,
33
+ }
34
+ : $.flow
35
+ ? $.flow.suspend()
36
+ : {
37
+ resume_url: undefined,
38
+ };
39
+ if (!resume_url) {
40
+ throw new ConfigurationError("Webhook URL is required for Pipedream Connect.");
41
+ }
42
+
43
+ return this.voilanorbert.verifyEmails({
44
+ emails: this.emails.toString(),
45
+ webhook: resume_url,
46
+ });
47
+ },
48
+ getSummary() {
49
+ return "Emails Successfully sent for verification!";
50
+ },
51
+ },
52
+ };
@@ -0,0 +1,8 @@
1
+ export const objectToString = (data) => {
2
+ return Object.keys(data).reduce((prev, key) => {
3
+ if (data[key] === undefined) return prev;
4
+ return `${prev
5
+ ? `${prev}&`
6
+ : ""}${key}=${data[key]}`;
7
+ }, "");
8
+ };
package/package.json CHANGED
@@ -1,21 +1,18 @@
1
1
  {
2
2
  "name": "@pipedream/voilanorbert",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Pipedream VoilaNorbert Components",
5
- "main": "dist/app/voilanorbert.app.mjs",
5
+ "main": "voilanorbert.app.mjs",
6
6
  "keywords": [
7
7
  "pipedream",
8
8
  "voilanorbert"
9
9
  ],
10
- "files": [
11
- "dist"
12
- ],
13
10
  "homepage": "https://pipedream.com/apps/voilanorbert",
14
11
  "author": "Pipedream <support@pipedream.com> (https://pipedream.com/)",
15
- "dependencies": {
16
- "@pipedream/platform": "^1.1.1"
17
- },
18
12
  "publishConfig": {
19
13
  "access": "public"
14
+ },
15
+ "dependencies": {
16
+ "@pipedream/platform": "^3.1.0"
20
17
  }
21
18
  }
@@ -0,0 +1,124 @@
1
+ import { axios } from "@pipedream/platform";
2
+ import { objectToString } from "./common/utils.mjs";
3
+
4
+ export default {
5
+ type: "app",
6
+ app: "voilanorbert",
7
+ propDefinitions: {
8
+ contactId: {
9
+ type: "integer",
10
+ label: "Contact Id",
11
+ description: "The contact's id.",
12
+ async options({ page }) {
13
+ const { result } = await this.getContacts(page + 1);
14
+
15
+ return result?.map(({
16
+ name, email, id,
17
+ }) => ({
18
+ label: `${name} - ${email?.email}`,
19
+ value: id,
20
+ })) ?? [];
21
+ },
22
+ },
23
+ name: {
24
+ type: "string",
25
+ label: "Name",
26
+ description: "Full name of the person to search.",
27
+ },
28
+ domain: {
29
+ type: "string",
30
+ label: "Domain",
31
+ description: "The domain of the company. (Either `domain` or `company` is required).",
32
+ },
33
+ company: {
34
+ type: "string",
35
+ label: "Company",
36
+ description: "The name of the company. (Either `domain` or `company` is required).",
37
+ },
38
+ emails: {
39
+ type: "string[]",
40
+ label: "Emails",
41
+ description: "A list of emails",
42
+ },
43
+ listId: {
44
+ type: "integer",
45
+ label: "List ID",
46
+ description: "A List ID the contact will affected to.",
47
+ async options() {
48
+ const { result } = await this.getLists();
49
+
50
+ return result.map(({
51
+ name: label, id: value,
52
+ }) => ({
53
+ label,
54
+ value,
55
+ }));
56
+ },
57
+ },
58
+ },
59
+ methods: {
60
+ _accessToken() {
61
+ return this.$auth.api_key;
62
+ },
63
+ _auth() {
64
+ return {
65
+ username: "",
66
+ password: this._accessToken(),
67
+ };
68
+ },
69
+ _apiUrl() {
70
+ return "https://api.voilanorbert.com/2018-01-08";
71
+ },
72
+ async _makeRequest({
73
+ $ = this, path, ...options
74
+ }) {
75
+ const config = {
76
+ url: `${this._apiUrl()}/${path}`,
77
+ ...options,
78
+ auth: this._auth(),
79
+ headers: {
80
+ "Content-Type": "application/x-www-form-urlencoded",
81
+ },
82
+ };
83
+ return axios($, config);
84
+ },
85
+ async getContacts(page) {
86
+ try {
87
+ return await this._makeRequest({
88
+ path: "contacts/",
89
+ params: {
90
+ page,
91
+ },
92
+ });
93
+ } catch (e) {
94
+ return [];
95
+ }
96
+ },
97
+ async getContact({ contactId }) {
98
+ return await this._makeRequest({
99
+ path: `contacts/${contactId}`,
100
+ });
101
+ },
102
+ async getLists() {
103
+ return await this._makeRequest({
104
+ path: "lists/",
105
+ });
106
+ },
107
+ async startContactSearch(data) {
108
+ const bodyFormData = objectToString(data);
109
+ return await this._makeRequest({
110
+ method: "POST",
111
+ path: "search/name",
112
+ data: bodyFormData,
113
+ });
114
+ },
115
+ async verifyEmails(data) {
116
+ const bodyFormData = objectToString(data);
117
+ return await this._makeRequest({
118
+ method: "POST",
119
+ path: "verifier/upload",
120
+ data: bodyFormData,
121
+ });
122
+ },
123
+ },
124
+ };