node-poplib offers an MIT-licensed client library for the POP3 protocol. It is currently provides the following capabilities:
It complies to:
You have two installation options:
Via npm: npm install poplib
Download the source and install it yourself
Connect to GMail's POP3 servers using the provided demo script as follows:
$ node demos/demo.js --host pop.gmail.com --port 995 --username user@gmail.com --password potato --tls on --debug on --networkdebug on
Server: '+OK Gpop ready for requests from 1.2.3.4 bh7pf61475604pab.24\r\n'
CONNECT success
Client: 'USER user@gmail.com\r\n'
Server: '+OK send PASS\r\n'
Client: 'PASS potato\r\n'
Server: '-ERR [AUTH] Username and password not accepted.\r\n'
LOGIN/PASS failed
Client: 'QUIT\r\n'
Server: '+OK Farewell.\r\n'
QUIT success
node-poplib is event based. It is best to illustrate via examples:
Here we initialize the client (for plain text transmission):
var POP3Client = require("poplib");
var client = new POP3Client(port, host, {
tlserrs: false,
enabletls: true,
debug: false
});
The third parameter, options
, takes three options. If enabletls
is true, the library will use a TLS connection. Note that you will have to set the correct port (generally 995). If tlserrs
is true, then TLS errors will be ignored. Finally, the debug
parameter prints out requests and responses.
Next, we trap several common states:
client.on("error", function(err) {
if (err.errno === 111) console.log("Unable to connect to server");
else console.log("Server error occurred");
console.log(err);
});
client.on("connect", function() {
console.log("CONNECT success");
client.login(username, password);
});
client.on("invalid-state", function(cmd) {
console.log("Invalid state. You tried calling " + cmd);
});
client.on("locked", function(cmd) {
console.log("Current command has not finished yet. You tried calling " + cmd);
});
The error
event is emitted when there is a network error. The underlying error object is passed back to user-code.
The connect
event is emitted when the connection to the remote server is successful.
The invalid-state
event is emitted when you try to carry out an action not allowed within your current state (eg, attempting to RETR
-ieve a message when authentication has not been completed).
The locked
event is emitted when you try to execute another command while the current command has not finished executing successfully (eg, attempting to RETR
-ieve a message while the remote server has not finished sending LIST
data).
On a successful connect, we try authenticating:
client.on("connect", function() {
console.log("CONNECT success");
client.login(username, password);
});
Note that on successful login, we try listing. For all events, the first received argument is always a boolean indicating whether the command succeeded. The last received argument is always the raw unparsed data received from the remote server. The intermediate arguments contain parsed data.
client.on("login", function(status, rawdata) {
if (status) {
console.log("LOGIN/PASS success");
client.list();
} else {
console.log("LOGIN/PASS failed");
client.quit();
}
});
// Data is a 1-based index of messages, if there are any messages
client.on("list", function(status, msgcount, msgnumber, data, rawdata) {
if (status === false) {
console.log("LIST failed");
client.quit();
} else {
console.log("LIST success with " + msgcount + " element(s)");
if (msgcount > 0)
client.retr(1);
else
client.quit();
}
});
client.on("retr", function(status, msgnumber, data, rawdata) {
if (status === true) {
console.log("RETR success for msgnumber " + msgnumber);
client.dele(msgnumber);
client.quit();
} else {
console.log("RETR failed for msgnumber " + msgnumber);
client.quit();
}
});
client.on("dele", function(status, msgnumber, data, rawdata) {
if (status === true) {
console.log("DELE success for msgnumber " + msgnumber);
client.quit();
} else {
console.log("DELE failed for msgnumber " + msgnumber);
client.quit();
}
});
client.on("quit", function(status, rawdata) {
if (status === true) console.log("QUIT success");
else console.log("QUIT failed");
});
login(username, password)
Self explanatory. This executes USER
and PASS
. Do not use over cleartext channels. Preferably don't use it at all as auth()
implements AUTH
which deprecates the need for USER and PASS. Emits login
event.
apop(username, password)
This executes APOP
. Requires server side support. Preferably don't use it as auth()
implements AUTH
which deprecates the need for USER and PASS. Emits apop
event.
auth(type, username, password)
This executes AUTH
. Requires server side support. Currently only "PLAIN" and "CRAM-MD5" types are supported. Emits auth
event.
stls()
This executes STLS
. Requires server side support (check using capa()
first). According to the RFC's, using STLS
is preferable to a purely TLS connection (although some servers only support purely TLS connections). Emits stls
event.
capa()
This executes CAPA
. Requires server side support. Emits capa
event.
list([msgnumber])
This executes LIST
. If the optional msgnumber
is provided, then LIST msgnumber
is executed. Emits list
event.
top(msgnumber, lines)
This executes TOP
. Requires server side support. msgnumber
and lines
must be provided. TEmits top
event.
stat()
This executes STAT
. Emits stat
event.
uidl([msgnumber])
This executes UIDL
. If the optional msgnumber
is provided, then UIDL msgnumber
is executed. Emits uidl
event.
retr(msgnumber)
This executes RETR
. msgnumber
must be provided. Emits retr
event.
dele(msgnumber)
This executes DELE
. msgnumber
must be provided. Emits dele
event.
rset()
This executes RSET
. Emits rset
event.
noop()
This executes NOOP
. Emits noop
event.
quit()
This executes QUIT
. Emits quit
event.
connect
The connect
event is emitted upon competion of connection attempt (initiated in the constructor). The arguments, in order, are:
login
The login
event is emitted upon competion of login()
method. The arguments, in order, are:
apop
The apop
event is emitted upon competion of apop()
method. The arguments, in order, are:
auth
The auth
event is emitted upon competion of auth()
method. The arguments, in order, are:
stls
The stls
event is emitted upon competion of stls()
method. The arguments, in order, are:
capa
The capa
event is emitted upon competion of capa()
method. The arguments, in order, are:
list
The list
event is emitted upon competion of list()
method. The arguments, in order, are:
list()
method. If a valid msgnumber was provided, this value will naturally be 1
(else null
)undefined
)null
)top
The top
event is emitted upon competion of top()
method. The arguments, in order, are:
undefined
)null
)stat
The stat
event is emitted upon competion of stat()
method. The arguments, in order, are:
count
and octet
(else null
)uidl
The uidl
event is emitted upon competion of uidl()
method. The arguments, in order, are:
undefined
)null
)retr
The retr
event is emitted upon competion of retr()
method. The arguments, in order, are:
msgnumber
provided to the methodtrue
, the results are returned as an ASCII string (else null
)dele
The dele
event is emitted upon competion of the dele()
method. The arguments, in order, are:
msgnumber
provided to the methodrset
The rset
event is emitted upon competion of the rset()
method. The arguments, in order, are:
noop
The noop
event is emitted upon competion of the noop()
method. The arguments, in order, are:
quit
The quit
event is emitted upon competion of the quit()
method. The arguments, in order, are:
error
The error
event is emitted if there is an error
event from the underlying socket. The original error object is passed as an argument.
invalid-state
The invalid-state
event is emitted when an action not allowed within the current state s attmempted (eg, attempting to RETR
-ieve a message when AUTH
-entication has not been completed).
locked
The locked
event is emitted when a method is called while existing execution has not finished executing (eg, attempting to RETR
-ieve a message while the remote server has not finished sending LIST
data).
Tests are in tests
. Demos are in demos
.
There is a full-featured POP3 client example in demos/demo.js
. There is also a simple example of downloading all emails in a POP3 server and saving it locally in an mbox formatted file in demos/retrieve-all.js
.
For testing purposes, you can use the following sendmail.sh script to pump email into your SMTP server for retrieval via POP3:
./sendmail.sh 10 "user@example.com" "this is my subject" "this is my body"
You can execute the test-runner as follows:
./runner.sh username password pop3server pop3port pop3tlsport testemail@address.com