Created
April 25, 2023 23:00
-
-
Save jerbear2008/4e2e9383d454695e9810f531498b39c3 to your computer and use it in GitHub Desktop.
This file contains 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 Imap from 'imap' | |
import { simpleParser } from 'mailparser' | |
import util from 'util' | |
// Modernized verison, with modern JS, async/await, util.promisify, etc. | |
class MailListener { | |
constructor({ | |
username, | |
password, | |
host, | |
port, | |
tls, | |
tlsOptions = {}, | |
connTimeout = null, | |
authTimeout = null, | |
debug = null, | |
xoauth2, | |
mailbox = 'INBOX', | |
searchFilter = ['UNSEEN'], | |
markSeen, | |
fetchUnreadOnStart, | |
attachments = false, | |
attachmentOptions = {}, | |
mailParserOptions = {}, | |
}) { | |
this.markSeen = markSeen | |
this.mailbox = mailbox | |
if ('string' === typeof searchFilter) { | |
this.searchFilter = [searchFilter] | |
} else { | |
this.searchFilter = searchFilter | |
} | |
this.fetchUnreadOnStart = fetchUnreadOnStart | |
this.mailParserOptions = mailParserOptions | |
if (attachments && attachmentOptions && attachmentOptions.stream) { | |
this.mailParserOptions.streamAttachments = true | |
} | |
this.attachmentOptions = attachmentOptions | |
this.attachments = attachments | |
this.attachmentOptions.directory = this.attachmentOptions.directory ?? '' | |
this.imap = new Imap({ | |
xoauth2, | |
user: username, | |
password, | |
host, | |
port, | |
tls, | |
tlsOptions, | |
connTimeout, | |
authTimeout, | |
debug, | |
}) | |
this.imap.once('ready', this.imapReady) | |
this.imap.once('close', this.imapClose) | |
this.imap.on('error', this.imapError) | |
} | |
start() { | |
this.imap.connect() | |
} | |
stop() { | |
this.imap.end() | |
} | |
imapReady() { | |
this.imap.openBox(this.mailbox, false, (err, mailbox) => { | |
if (err) { | |
this.emit('error', err) | |
} else { | |
this.emit('server:connected') | |
if (this.fetchUnreadOnStart) { | |
this.parseUnread() | |
} | |
this.imap.on('mail', this.imapMail) | |
this.imap.on('update', this.imapMail) | |
} | |
}) | |
} | |
imapClose() { | |
this.emit('server:disconnected') | |
} | |
imapError(err) { | |
this.emit('error', err) | |
} | |
imapMail() { | |
this.parseUnread() | |
} | |
async parseUnread() { | |
// modern version without async library, using modern async/await syntax instead (with util.promisify to convert imap functions to promises) | |
const search = util.promisify(this.imap.search).bind(this.imap) | |
const fetch = util.promisify(this.imap.fetch).bind(this.imap) | |
const results = await search(this.searchFilter) | |
if (results.length === 0) return | |
for (const result of results) { | |
const fetchResult = await fetch(result, { | |
bodies: '', | |
markSeen: this.markSeen, | |
}) | |
fetchResult.on('message', async (message, sequenceNumber) => { | |
let attributes = null | |
let emailBuffer = Buffer.from('') | |
message.on('attributes', (attrs) => { | |
attributes = attrs | |
}) | |
const parsed = await simpleParser(emailBuffer) | |
this.emit('mail', parsed, sequenceNumber, attributes) | |
}) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment