仅用于内部开发环境无法访问邮件服务器的情况下,测试SMTP邮件发送有没有成功。收到邮件发送请求后仅打印内容和保存附件用于测试验证。
安装库
实验环境使用了Nodejs版本16。
npm install smtp-server mailparser
JS版SMTP服务器代码
没有使用TSL/SSL,使用的话需要证书,设定secure=false。secure=false的时候,必须禁用STARTTLS,不然会报错。其他设定可以参照 SMTP Server :: Nodemailer
const SMTPServer = require('smtp-server').SMTPServer;
const MailParser = require('mailparser').MailParser;
const path = require('path');
const fs = require('fs');
const log = (msg, ...params) => {
if (params.length > 0) {
console.log(new Date().toISOString() + ' INFO ' + ' : ' + msg, params);
} else {
console.log(new Date().toISOString() + ' INFO ' + ' : ' + msg);
}
}
const server = new SMTPServer({
secure: false,
disabledCommands: ['STARTTLS'],
onAuth(auth, session, callback) {
log('onAuth', `username:${auth.username}', 'password:${auth.password}`);
callback(null, { user: 123 }); // where 123 is the user id or similar property
},
onData(stream, session, callback) {
log('onData', session);
try{
const parser = new MailParser();
stream.pipe(parser);
parser.on('data', data=> {
try{
if (data.type === "attachment") {
log('attachment start');
const filename = `${data.filename}`;
const saveFilename = path.join('', new Date().getTime() + filename.substring(filename.lastIndexOf('.')));
const writeStream = fs.createWriteStream(saveFilename);
data.content.pipe(writeStream);
data.content.on('end', () => {
data.release();
writeStream.end();
log(`attachment [${filename}] is saved to [${saveFilename}].`);
});
} else {
log('MessageText', data);
}
}catch(err) {
log('Error', err);
}finally {
const response = session.envelope.rcptTo.map((rcpt) => "<" + rcpt.address + "> Accepted");
callback(null, response);
}
});
parser.on('headers', headers => {
log('headers', headers);
});
}catch(err) {
log('Error', err);
}
}
});
server.on('error', (err) => {
log('Error', err.message);
});
server.listen(25, () => {
log('SMTP server listening on port 25');
});