@konfeature/ap-email-guessr 0.1.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 +128 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +21 -0
- package/dist/src/lib/actions/find-email.d.ts +10 -0
- package/dist/src/lib/actions/find-email.js +90 -0
- package/dist/src/lib/actions/generate-emails.d.ts +8 -0
- package/dist/src/lib/actions/generate-emails.js +56 -0
- package/dist/src/lib/common/dns.d.ts +14 -0
- package/dist/src/lib/common/dns.js +37 -0
- package/dist/src/lib/common/find-email.d.ts +39 -0
- package/dist/src/lib/common/find-email.js +78 -0
- package/dist/src/lib/common/find-person.d.ts +31 -0
- package/dist/src/lib/common/find-person.js +102 -0
- package/dist/src/lib/common/http.d.ts +24 -0
- package/dist/src/lib/common/http.js +67 -0
- package/dist/src/lib/common/mx-fingerprint.d.ts +30 -0
- package/dist/src/lib/common/mx-fingerprint.js +114 -0
- package/dist/src/lib/common/patterns.d.ts +28 -0
- package/dist/src/lib/common/patterns.js +105 -0
- package/dist/src/lib/common/providers/o365.d.ts +51 -0
- package/dist/src/lib/common/providers/o365.js +171 -0
- package/dist/src/lib/common/verifier.d.ts +22 -0
- package/dist/src/lib/common/verifier.js +10 -0
- package/dist/src/lib/common/verifiers/no2bounce-verifier.d.ts +34 -0
- package/dist/src/lib/common/verifiers/no2bounce-verifier.js +123 -0
- package/dist/src/lib/common/verifiers/o365-verifier.d.ts +9 -0
- package/dist/src/lib/common/verifiers/o365-verifier.js +30 -0
- package/package.json +42 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Verifier adapter for the no2bounce API (wire format confirmed against the
|
|
4
|
+
* live API).
|
|
5
|
+
*
|
|
6
|
+
* Async flow: POST a 1-email batch to get a `trackingId` (under `data`), then
|
|
7
|
+
* GET-poll `?trackingId=` until the *top-level* `overallStatus` is "Completed".
|
|
8
|
+
* For a single email the top-level count fields are that email's verdict.
|
|
9
|
+
* Billing is 1 credit per email (`creditDebited`), with no refund on undeliverable.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.decodeSingle = decodeSingle;
|
|
13
|
+
exports.createNo2BounceVerifier = createNo2BounceVerifier;
|
|
14
|
+
const http_1 = require("../http");
|
|
15
|
+
const ENDPOINT = "https://connect.no2bounce.com/v2/n2b_validate_bulk";
|
|
16
|
+
// no2bounce risk-scores accept-all domains per address: "Deliverable/AcceptAll"
|
|
17
|
+
// is a predicted hit, "UnDeliverable/AcceptAll" a predicted miss, and
|
|
18
|
+
// "Risky/AcceptAll" genuinely uncertain (so we stop on it).
|
|
19
|
+
function decodeSingle(r) {
|
|
20
|
+
if ((r.Deliverable ?? 0) >= 1) {
|
|
21
|
+
return { verdict: "valid", catchAll: false };
|
|
22
|
+
}
|
|
23
|
+
if ((r["Deliverable/AcceptAll"] ?? 0) >= 1) {
|
|
24
|
+
return { verdict: "valid", catchAll: true };
|
|
25
|
+
}
|
|
26
|
+
if ((r["Risky/AcceptAll"] ?? 0) >= 1) {
|
|
27
|
+
return { verdict: "catch_all", catchAll: true };
|
|
28
|
+
}
|
|
29
|
+
if ((r.Undeliverable ?? 0) >= 1) {
|
|
30
|
+
return { verdict: "invalid", catchAll: false };
|
|
31
|
+
}
|
|
32
|
+
if ((r["UnDeliverable/AcceptAll"] ?? 0) >= 1) {
|
|
33
|
+
return { verdict: "invalid", catchAll: true };
|
|
34
|
+
}
|
|
35
|
+
return { verdict: "unknown", catchAll: false };
|
|
36
|
+
}
|
|
37
|
+
function isComplete(r) {
|
|
38
|
+
return (String(r.overallStatus ?? "")
|
|
39
|
+
.toLowerCase()
|
|
40
|
+
.startsWith("complet") || (r.percent ?? 0) >= 100);
|
|
41
|
+
}
|
|
42
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
43
|
+
function createNo2BounceVerifier(options) {
|
|
44
|
+
const pollIntervalMs = options.pollIntervalMs ?? 2000;
|
|
45
|
+
const maxWaitMs = options.maxWaitMs ?? 30000;
|
|
46
|
+
const authHeader = { apitoken: options.apitoken };
|
|
47
|
+
async function submit(email) {
|
|
48
|
+
const res = await (0, http_1.httpRequest)({
|
|
49
|
+
url: ENDPOINT,
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers: { ...authHeader, "Content-Type": "application/json" },
|
|
52
|
+
body: JSON.stringify({ emailList: [email] }),
|
|
53
|
+
timeoutMs: options.timeoutMs,
|
|
54
|
+
});
|
|
55
|
+
if (res.status !== 200) {
|
|
56
|
+
throw new Error(`submit_${res.status}`);
|
|
57
|
+
}
|
|
58
|
+
const json = JSON.parse(res.body);
|
|
59
|
+
const id = json.data?.trackingId ?? json.data?.taskId;
|
|
60
|
+
return id === undefined ? undefined : String(id);
|
|
61
|
+
}
|
|
62
|
+
async function poll(trackingId) {
|
|
63
|
+
const url = `${ENDPOINT}?trackingId=${encodeURIComponent(trackingId)}`;
|
|
64
|
+
const deadline = Date.now() + maxWaitMs;
|
|
65
|
+
while (Date.now() < deadline) {
|
|
66
|
+
await sleep(pollIntervalMs);
|
|
67
|
+
try {
|
|
68
|
+
const res = await (0, http_1.httpRequest)({
|
|
69
|
+
url,
|
|
70
|
+
method: "GET",
|
|
71
|
+
headers: authHeader,
|
|
72
|
+
timeoutMs: options.timeoutMs,
|
|
73
|
+
});
|
|
74
|
+
if (res.status !== 200) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const parsed = JSON.parse(res.body);
|
|
78
|
+
if (isComplete(parsed)) {
|
|
79
|
+
return parsed;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// Transient poll error; keep trying until the deadline.
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
name: "no2bounce",
|
|
90
|
+
async verify(email) {
|
|
91
|
+
let trackingId;
|
|
92
|
+
try {
|
|
93
|
+
trackingId = await submit(email);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
// Submission rejected → no credit charged.
|
|
97
|
+
return {
|
|
98
|
+
email,
|
|
99
|
+
verdict: "unknown",
|
|
100
|
+
creditsUsed: 0,
|
|
101
|
+
reason: error instanceof Error ? error.message : "submit_failed",
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
if (!trackingId) {
|
|
105
|
+
return { email, verdict: "unknown", creditsUsed: 0, reason: "no_tracking_id" };
|
|
106
|
+
}
|
|
107
|
+
const parsed = await poll(trackingId);
|
|
108
|
+
if (!parsed) {
|
|
109
|
+
return { email, verdict: "unknown", creditsUsed: 1, reason: "poll_timeout" };
|
|
110
|
+
}
|
|
111
|
+
const { verdict, catchAll } = decodeSingle(parsed);
|
|
112
|
+
return {
|
|
113
|
+
email,
|
|
114
|
+
verdict,
|
|
115
|
+
catchAll,
|
|
116
|
+
creditsUsed: parsed.creditDebited ?? 1,
|
|
117
|
+
reason: `n2b_${verdict}${catchAll ? "_acceptall" : ""}`,
|
|
118
|
+
raw: parsed,
|
|
119
|
+
};
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=no2bounce-verifier.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verifier adapter for the direct Microsoft 365 account check. Free (no
|
|
3
|
+
* credits): it asks Azure AD whether the account exists over HTTPS, so it never
|
|
4
|
+
* touches port 25 and never spends a no2bounce credit.
|
|
5
|
+
*/
|
|
6
|
+
import { type O365Namespace } from "../providers/o365";
|
|
7
|
+
import type { Verifier } from "../verifier";
|
|
8
|
+
export declare function createO365Verifier(namespace: O365Namespace, applicable: boolean, timeoutMs: number): Verifier;
|
|
9
|
+
//# sourceMappingURL=o365-verifier.d.ts.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Verifier adapter for the direct Microsoft 365 account check. Free (no
|
|
4
|
+
* credits): it asks Azure AD whether the account exists over HTTPS, so it never
|
|
5
|
+
* touches port 25 and never spends a no2bounce credit.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.createO365Verifier = createO365Verifier;
|
|
9
|
+
const o365_1 = require("../providers/o365");
|
|
10
|
+
function createO365Verifier(namespace, applicable, timeoutMs) {
|
|
11
|
+
return {
|
|
12
|
+
name: "o365",
|
|
13
|
+
async verify(email) {
|
|
14
|
+
const result = await (0, o365_1.checkO365Account)(email, namespace, applicable, timeoutMs);
|
|
15
|
+
const verdict = result.exists === true
|
|
16
|
+
? "valid"
|
|
17
|
+
: result.exists === false
|
|
18
|
+
? "invalid"
|
|
19
|
+
: "unknown";
|
|
20
|
+
return {
|
|
21
|
+
email,
|
|
22
|
+
verdict,
|
|
23
|
+
creditsUsed: 0,
|
|
24
|
+
reason: result.reason,
|
|
25
|
+
raw: result,
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=o365-verifier.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@konfeature/ap-email-guessr",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Activepieces piece that finds a person's email from their name and company domain — free Microsoft 365 account checks plus no2bounce verification, with early-stop to minimize credits.",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"main": "./dist/src/index.js",
|
|
7
|
+
"types": "./dist/src/index.d.ts",
|
|
8
|
+
"files": ["dist/src/**/*.js", "dist/src/**/*.d.ts", "README.md"],
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"author": "KONFeature",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/KONFeature/ap-email-guessr.git"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/KONFeature/ap-email-guessr#readme",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/KONFeature/ap-email-guessr/issues"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"activepieces",
|
|
21
|
+
"activepieces-piece",
|
|
22
|
+
"email",
|
|
23
|
+
"email-finder",
|
|
24
|
+
"email-verification",
|
|
25
|
+
"no2bounce",
|
|
26
|
+
"office365"
|
|
27
|
+
],
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsc -p tsconfig.json",
|
|
33
|
+
"prepublishOnly": "npm run build"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@activepieces/pieces-framework": "0.30.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^20.19.0",
|
|
40
|
+
"typescript": "^5.7.3"
|
|
41
|
+
}
|
|
42
|
+
}
|