/
mail.listener.coffee
78 lines (70 loc) · 2.25 KB
/
mail.listener.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
{EventEmitter} = require "events"
{MailParser} = require "mailparser"
Imap = require "imap"
# MailListener class. Can `emit` events in `node.js` fashion.
class MailListener extends EventEmitter
constructor: (options) ->
# set this option to `true` if you want to fetch unread emial immediately on lib start.
@fetchUnreadOnStart = options.fetchUnreadOnStart
@markSeen = options.markSeen
# TODO add validation for required parameters
@imap = new Imap
user: options.username
password: options.password
host: options.host
port: options.port
tls: options.secure
@mailbox = options.mailbox || "INBOX"
# start listener
start: =>
# 1. connect to imap server
@imap.once 'ready', (err) =>
if err
@emit "error", err
else
@emit "server:connected"
# 2. open mailbox
@imap.openBox @mailbox, false, (err) =>
if err
@emit "error", err
else
if @fetchUnreadOnStart
@_parseUnreadEmails()
# 3. listen for new emails in the inbox
@imap.on "mail", (id) =>
@emit "mail:arrived", id
# 4. find all unseen emails
@_parseUnreadEmails()
@imap.connect()
# stop listener
stop: =>
@imap.logout =>
@emit "server:disconnected"
_parseUnreadEmails: =>
@imap.search ["UNSEEN"], (err, searchResults) =>
if err
@emit "error", err
else
if Array.isArray(searchResults) and searchResults.length == 0
return
# 5. fetch emails
if @markSeen
markSeen = true
fetch = @imap.fetch(searchResults, { bodies: '', markSeen: markSeen })
# 6. email was fetched. Parse it!
fetch.on "message", (msg, id) =>
parser = new MailParser
parser.on "end", (mail) =>
mail.uid = id
@emit "mail:parsed", mail
msg.on "body", (stream, info) =>
buffer = '';
stream.on "data", (chunk) =>
buffer += chunk
stream.once "end", ->
parser.write buffer
msg.on "end", ->
parser.end()
# imap
imap = @imap
module.exports = MailListener