Skip to content

Instantly share code, notes, and snippets.

@Igloczek
Last active February 25, 2025 23:44
Show Gist options
  • Save Igloczek/7bfc459109f4a01f7e046b591d2a842a to your computer and use it in GitHub Desktop.
Save Igloczek/7bfc459109f4a01f7e046b591d2a842a to your computer and use it in GitHub Desktop.
Simple way to filter out most of the disposable / temporary emails
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