使用node.js搭建邮件服务器——第一章

704 阅读2分钟

现在开始学习 如果使用node.js 搭建一个邮件服务器哦

初入殿堂

1、简易smtp服务搭建

const SMTPServer = require('smtp-server').SMTPServer;
const server = new SMTPServer({
    secure: false, // 明确指定不使用安全连接 上线后不能这样哦,需要配置证书
    onAuth(auth, session, callback) {
        if (auth.username === 'your_username' && auth.password === 'your_password') {
            callback(null, { user: 'user' });
        } else {
            callback(new Error('Authentication failed'));
        }
    },
    onData(stream, session, callback) {
        let data = '';
        stream.on('data', (chunk) => {
            data += chunk;
        });
        stream.on('end', async () => {
         
                console.error('Error parsing email:', data);
                callback(error);
           
        });
    },
});

server.listen(25, () => {
    console.log("SMTP服务器已启动,监听端口25");
});

2、发送邮件 验证

let smtpConfig = {
        host: 'localhost',
        port: 25,
        secure: false, // 明确指定不使用安全连接 上线后不能这样哦,需要配置证书
        auth: {
            user: 'your_username',
            pass: 'your_password'
        },
        tls: {
            rejectUnauthorized: false, // 指定不拒绝自签名证书
        }
    };
    let transporter = nodeMailer.createTransport(smtpConfig);
    var mailOptions = {
        from: 'zouchengzhuo@163.com',
        to: '405966530@qq.com',
        subject: '测试SMTP发送邮件',
        text: 'email text content',
        html: '<h1>Hello SMTP protocol</h1>'
    };
    transporter.sendMail(mailOptions, function (error, info) {
        if (error) {
            return console.log(error);
        }
        console.log('Message sent: ' + info.response);
    });

结果如下:

image.png

3、解析邮件内容

这时发现上面的邮件内容,貌似也太简单了,那怎么解析邮件内容呢?

const { simpleParser } = require('mailparser');

const server = new SMTPServer({
    secure: false,
    onAuth(auth, session, callback) {
        if (auth.username === 'your_username' && auth.password === 'your_password') {
            callback(null, { user: 'user' });
        } else {
            callback(new Error('Authentication failed'));
        }
    },
    onData(stream, session, callback) {
        let data = '';
        stream.on('data', (chunk) => {
            data += chunk;
        });
        stream.on('end', async () => {
            try {
                // 使用 mailparser 解析邮件内容
                const parsed = await simpleParser(data);
                console.log('Received the following message:\n', parsed);

                // 在这里可以处理邮件内容,例如存储到数据库或执行其他操作

                callback();
            } catch (error) {
                console.error('Error parsing email:', error);
                callback(error);
            }
        });
    },
});

解析后内容如下:


Received the following message:
 {
  attachments: [],  # 附件
  headers: Map(7) {
    'content-type' => { value: 'multipart/alternative', params: [Object] },
    'from' => {
      value: [Array],
      html: '<span class="mp_address_group"><span class="mp_address_name">zoucz</span> &lt;<a href="mailto:zouchengzhuo@163.com" class="mp_address_email">zouchengzhuo@163.com</a>&gt;</span>',
      text: '"zoucz" <zouchengzhuo@163.com>'
    },
    'to' => {
      value: [Array],
      html: '<span class="mp_address_group"><span class="mp_address_name">zoucz</span> &lt;<a href="mailto:405966530@qq.com" class="mp_address_email">405966530@qq.com</a>&gt;</span>',        
      text: '"zoucz" <405966530@qq.com>'
    },
    'subject' => '测试SMTP发送邮件',
    'message-id' => '<1df7ba5d-f751-8219-1381-0b064c46f75b@163.com>',
    'date' => 2024-01-16T03:11:45.000Z,
    'mime-version' => '1.0'
  },
  headerLines: [
    {
      key: 'content-type',
      line: 'Content-Type: multipart/alternative;\r\n' +
        ' boundary="--_NmP-fc0d67adb93111ec-Part_1"'
    },
    { key: 'from', line: 'From: zoucz <zouchengzhuo@163.com>' },
    { key: 'to', line: 'To: zoucz <405966530@qq.com>' },
    {
      key: 'subject',
      line: 'Subject: =?UTF-8?B?5rWL6K+VU01UUOWPkemAgemCruS7tg==?='
    },
    {
      key: 'message-id',
      line: 'Message-ID: <1df7ba5d-f751-8219-1381-0b064c46f75b@163.com>'
    },
    { key: 'date', line: 'Date: Tue, 16 Jan 2024 03:11:45 +0000' },
    { key: 'mime-version', line: 'MIME-Version: 1.0' }
  ],
  html: '<h1>Hello SMTP protocol</h1>', # 内容
  text: 'email text content', 
  textAsHtml: '<p>email text content</p>',
  subject: '测试SMTP发送邮件', # 标题 
  date: 2024-01-16T03:11:45.000Z, # 时间
  to: {
    value: [ [Object] ],
    html: '<span class="mp_address_group"><span class="mp_address_name">zoucz</span> &lt;<a href="mailto:405966530@qq.com" class="mp_address_email">405966530@qq.com</a>&gt;</span>',
    text: '"zoucz" <405966530@qq.com>' # 去哪里
  },
  from: {
    value: [ [Object] ],
    html: '<span class="mp_address_group"><span class="mp_address_name">zoucz</span> &lt;<a href="mailto:zouchengzhuo@163.com" class="mp_address_email">zouchengzhuo@163.com</a>&gt;</span>',
    text: '"zoucz" <zouchengzhuo@163.com>' # 来着哪里
  },
  messageId: '<1df7ba5d-f751-8219-1381-0b064c46f75b@163.com>'
}
Message sent: 250 OK: message queued

4、构建IMAP

npm install node-imap
const Imap = require('imap');

// 配置 IMAP 连接参数
const imapConfig = {
    user: 'your_email@example.com',
    password: 'your_email_password',
    host: 'imap.example.com',
    port: 993, // 默认 IMAP over SSL/TLS 端口
    tls: true,
};

const imap = new Imap(imapConfig);

// 处理邮件
function processMail(mail) {
    console.log('Subject:', mail.subject);
    console.log('From:', mail.from[0].address);
    console.log('Text:', mail.text);
    console.log('---');
}

// 连接到 IMAP 服务器
imap.once('ready', () => {
    imap.openBox('INBOX', true, (err, box) => {
        if (err) throw err;

        // 搜索收件箱中的所有邮件
        const searchCriteria = ['ALL'];
        const fetchOptions = { bodies: '', struct: true };

        const fetch = imap.seq.fetch(box.messages.total + ':*', fetchOptions);
        fetch.on('message', (msg, seqno) => {
            console.log('Message #%d', seqno);

            msg.on('body', (stream, info) => {
                let buffer = '';

                stream.on('data', (chunk) => {
                    buffer += chunk.toString('utf8');
                });

                stream.once('end', () => {
                    const mail = Imap.parseMessage(buffer);
                    processMail(mail);
                });
            });
        });

        fetch.once('end', () => {
            imap.end();
        });
    });
});

imap.connect();