Last active
February 25, 2025 23:44
-
-
Save Igloczek/7bfc459109f4a01f7e046b591d2a842a to your computer and use it in GitHub Desktop.
Simple way to filter out most of the disposable / temporary emails
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import axios from "axios" | |
import TTLCache from "@isaacs/ttlcache" | |
const domainsCache = new TTLCache({ | |
ttl: 1000 * 60 * 60 * 24, | |
}) as TTLCache<string, Set<string>> | |
interface ListConfig { | |
url: string | |
type: "text" | "json" | |
} | |
const lists: ListConfig[] = [ | |
{ | |
url: "https://deviceandbrowserinfo.com/api/emails/disposable", | |
type: "json", | |
}, | |
{ | |
url: "https://raw.githubusercontent.com/Igloczek/burner-email-providers/master/emails.txt", | |
type: "text", | |
}, | |
{ | |
url: "https://raw.githubusercontent.com/wesbos/burner-email-providers/master/emails.txt", | |
type: "text", | |
}, | |
{ | |
url: "https://raw.githubusercontent.com/7c/fakefilter/main/txt/data.txt", | |
type: "text", | |
}, | |
{ | |
url: "https://raw.githubusercontent.com/unkn0w/disposable-email-domain-list/main/domains.txt", | |
type: "text", | |
}, | |
{ | |
url: "https://raw.githubusercontent.com/disposable/disposable-email-domains/master/domains_strict.txt", | |
type: "text", | |
}, | |
{ | |
url: "https://raw.githubusercontent.com/disposable-email-domains/disposable-email-domains/master/disposable_email_blocklist.conf", | |
type: "text", | |
}, | |
] | |
// stuff I want to block, but don't want to put in public lists, because that's paid email providers, just used for spam | |
const customDomains = ["trungtubemedia.com"] | |
async function loadDomains() { | |
const cached = domainsCache.get("domains") | |
if (cached) { | |
return cached | |
} | |
const domains = new Set<string>() | |
await Promise.allSettled( | |
lists.map(async (list) => { | |
const response = await axios.get(list.url) | |
if (list.type === "json") { | |
// Handle JSON response - assuming it's an array of domains | |
const jsonData = Array.isArray(response.data) ? response.data : [] | |
jsonData.forEach((domain) => { | |
if (typeof domain === "string" && domain.trim() !== "") { | |
domains.add(domain.trim()) | |
} | |
}) | |
} else { | |
// Handle text response | |
response.data.split("\n").forEach((item) => { | |
const line = item.trim() | |
if (line !== "" && !line.startsWith("#")) { | |
domains.add(line) | |
} | |
}) | |
} | |
}), | |
) | |
customDomains.forEach((domain) => { | |
domains.add(domain) | |
}) | |
domainsCache.set("domains", domains) | |
return domains | |
} | |
// warm up the cache | |
await loadDomains() | |
export async function verifyEmail(email) { | |
const domains = await loadDomains() | |
const isDisposable = domains.has(email.split("@")[1]) | |
return !isDisposable | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment