Skip to content

Instantly share code, notes, and snippets.

@nippe
Last active June 26, 2024 13:15
Show Gist options
  • Select an option

  • Save nippe/073d577e4502f97b4504107dcd6e2d94 to your computer and use it in GitHub Desktop.

Select an option

Save nippe/073d577e4502f97b4504107dcd6e2d94 to your computer and use it in GitHub Desktop.
import { checkMX } from './mx'
import { checkSMTP } from './smtp'
import { Result } from './types'
const DEFAULT_RESULT = {
reachable: false,
mx: { valid: false },
smtp: { valid: false },
}
async function checkEmail(email: string): Promise<Result> {
const result: Result = { email, ...DEFAULT_RESULT }
const [username, domain] = email.split('@')
const mx = await checkMX(domain!)
if (!mx.valid || !mx.mxRecords) {
return { ...result, mx }
}
const records = mx.mxRecords.sort((a, b) => a.priority - b.priority)
const smtp = await checkSMTP(email, records[0]!.exchange, 25)
if (!smtp.valid) {
return { ...result, mx, smtp }
}
return { ...result, reachable: true, mx, smtp }
}
export { checkEmail, checkMX, checkSMTP }
import { resolveMx } from 'node:dns'
import { MxResult } from '../types'
async function checkMX(domain: string): Promise<MxResult> {
return new Promise((resolve) => {
resolveMx(domain, (err, mxRecords) => {
if (err || mxRecords.length === 0) {
return resolve({ valid: false, mxRecords: [] })
} else {
resolve({ valid: true, mxRecords })
}
})
})
}
export default checkMX
import { Client } from 'smtp-fetch'
import { SMTPResult } from '../types'
async function checkSMTP(
to: string,
host: string,
port: number,
timeout: number = 5000,
): Promise<SMTPResult> {
const c = new Client(host, port)
try {
await c.connect({ timeout })
await c.mail('')
await c.rcpt(to)
await c.quit()
return {
valid: true,
}
} catch (err: any) {
return {
valid: false,
error: err.message,
}
} finally {
c.close()
}
}
export default checkSMTP
{
...
"dependencies": {
"smtp-fetch" : "^1.0.5"
}
...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment