init
This commit is contained in:
commit
d295c7f139
1527 files changed
+270726
No files matched your search
@@ -0,0 +1,115 @@
|
||||
// @ts-check
|
||||
// Pure, side-effect-free Gmail helpers. Ported verbatim from the gmail-helpers
|
||||
// contributed by @SparshGarg999 in #1203 (with thanks). Files prefixed with _
|
||||
// are never discovered as plugins.
|
||||
|
||||
/**
|
||||
* Extract all http/https URLs from a string (plain text or HTML). Normalizes
|
||||
* & and strips trailing punctuation. Dedups.
|
||||
* @param {string} body
|
||||
* @returns {string[]}
|
||||
*/
|
||||
export function extractUrls(body) {
|
||||
if (!body) return [];
|
||||
const urls = [];
|
||||
const regex = /https?:\/\/[^\s"'<>\(\)]+/gi;
|
||||
let match;
|
||||
while ((match = regex.exec(body)) !== null) {
|
||||
const url = match[0].replace(/[.,;:!?]+$/, '').replace(/&/g, '&');
|
||||
urls.push(url);
|
||||
}
|
||||
return [...new Set(urls)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a URL clean and relevant (not a click tracker, unsubscribe link, or pixel)?
|
||||
* @param {string} url
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isCleanUrl(url) {
|
||||
try {
|
||||
const u = new URL(url);
|
||||
const lowerUrl = url.toLowerCase();
|
||||
const badKeywords = [
|
||||
'click', 'track', 'openpixel', 'sendgrid', 'unsubscribe', 'optout',
|
||||
'newsletter', 'subscribe', 'w3.org', 'doubleclick', 'googlesyndication',
|
||||
'googleadservices', 'mailgun', 'mandrill', 'mjml', 'github.com/login',
|
||||
'linkedin.com/legal', 'linkedin.com/help', 'linkedin.com/settings',
|
||||
];
|
||||
if (badKeywords.some(kw => lowerUrl.includes(kw))) return false;
|
||||
return u.protocol === 'https:';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DMARC alignment check (anti-spoof gate, fail-closed). Only emails whose
|
||||
* Authentication-Results header reports dmarc=pass are trusted.
|
||||
* @param {Array<{ name: string, value: string }>} headers
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isAuthenticEmail(headers) {
|
||||
if (!Array.isArray(headers)) return false;
|
||||
for (const h of headers) {
|
||||
if (h.name && h.name.toLowerCase() === 'authentication-results') {
|
||||
if (h.value && /dmarc=pass/i.test(h.value)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse "{Role} at {Company}" from a subject line.
|
||||
* @param {string} subject
|
||||
* @returns {{ role: string, company: string } | null}
|
||||
*/
|
||||
export function parseRoleAtCompany(subject) {
|
||||
if (!subject) return null;
|
||||
let clean = subject.replace(/^(re|fwd|new match|job alert|alert|match|notification|alert for|daily alert for):\s*/i, '').trim();
|
||||
clean = clean.split(/\s+[-|]\s+/)[0].trim();
|
||||
const match = clean.match(/^(.+?)\s+at\s+(.+)$/i);
|
||||
if (match) {
|
||||
const role = match[1].trim();
|
||||
const company = match[2].trim();
|
||||
if (role && company && role.length < 100 && company.length < 100) {
|
||||
return { role, company };
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively decode a Gmail message payload's base64url body parts to text.
|
||||
* @param {any} payload
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getMessageBody(payload) {
|
||||
if (!payload) return '';
|
||||
let body = '';
|
||||
if (payload.body && payload.body.data) {
|
||||
const base64 = payload.body.data.replace(/-/g, '+').replace(/_/g, '/');
|
||||
body += Buffer.from(base64, 'base64').toString('utf-8');
|
||||
}
|
||||
if (payload.parts) {
|
||||
for (const part of payload.parts) body += getMessageBody(part);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Best-effort company name from a known ATS URL (greenhouse/lever slug).
|
||||
* @param {string} url
|
||||
* @returns {string}
|
||||
*/
|
||||
export function companyFromUrl(url) {
|
||||
try {
|
||||
const { hostname, pathname } = new URL(url);
|
||||
if (hostname === 'boards.greenhouse.io' || hostname.endsWith('.greenhouse.io') ||
|
||||
hostname === 'jobs.lever.co' || hostname.endsWith('.lever.co')) {
|
||||
const parts = pathname.split('/').filter(Boolean);
|
||||
if (parts.length > 0) return parts[0];
|
||||
}
|
||||
} catch { /* malformed → no company */ }
|
||||
return '';
|
||||
}
|
||||
Reference in new issue
Block a user