RabbitMQとNodemailerを組み合わせてメールを非同期に処理


現在調べられているNodemailer資料は、ほとんどが同期処理に関する資料であり、NodemailerとRabbitMQを組み合わせてメールサービスを非同期で処理する方法に関する資料はNodemailerが提供する例であり、以前の資料にすぎず、例としてgssmtpやnsmtpをローカルで使用しているが、うまく動作していない.
そこで、彼はこの例をつかんで、ハミングして、それからGithubで他の人はnodemailerとRabbitMQを使ってメールサービスのコードを簡単に実現しますを見て、ついて行くことができます.
このコードは、sqlですべてのnoteを検索し、添付ファイルの非同期メールとして使用するコードであり、変換して使用されます.
次のようになります.
私たちのサービスは2つのメールで認証サービスを行います.1つは学校メール認証、1つはパスワードをリセットするための認証で、対応するタイプに応じて異なるファイルを表示するように設定されています.authcodeはresに送信する必要があるため、ルータはそれを処理します.
  • 内のサーバにRabbitMQをインストールしておく必要があります.
  • src/consumer.js
    const amqp = require("amqplib");
    const MailSender = require("./MailSender");
    const Listener = require("./Listener");
    
    const init = async () => {
      const mailSender = new MailSender();
      const listener = new Listener(mailSender);
    
      const connection = await amqp.connect(process.env.RABBITMQ_SERVER);
      const channel = await connection.createChannel();
    
      await channel.assertQueue("export:mail", {
        durable: true,
      });
    
      channel.consume("export:mail", listener.listen, { noAck: true });
    };
    
    init();
    
    src/Listener.js
    class Listener {
      constructor(mailSender) {
        this._mailSender = mailSender;
        this.listen = this.listen.bind(this);
      }
    
      async listen(message) {
        try {
          const { targetEmail, type, authCode } = message;
    
          const result = await this._mailSender.sendEmail(
            targetEmail,
            type,
            authCode
          );
    
          console.log(result);
        } catch (error) {
          console.error(error);
        }
      }
    }
    
    module.exports = Listener;
    
    src/MailSender.js
    const nodemailer = require("nodemailer");
    const ejs = require("ejs");
    const path = require("path");
    const appDir = path.dirname(require.main.filename);
    class MailSender {
      constructor() {
        this._transporter = nodemailer.createTransport({
          host: "smtp.gmail.com",
          port: 465,
          secure: true,
          auth: {
            user: process.env.NODEMAILER_USER,
            pass: process.env.NODEMAILER_PASS,
          },
        });
      }
    
      sendEmail(targetEmail, type, authCode) {
        let message;
        let emailTemplete;
        if (type == "auth") {
          ejs.renderFile(
            appDir + "/template/authmail.ejs",
            { authCode },
            function (err, data) {
              if (err) {
                console.log(err);
              }
              emailTemplete = data;
            }
          );
          message = {
            from: `UFO`,
            to: targetEmail,
            subject: "회원가입을 위한 인증번호를 입력해주세요.",
            html: emailTemplete,
          };
        } //다른 타입에 대한 코드 생략
    
        return this._transporter.sendMail(message);
      }
    }
    
    module.exports = MailSender;
    
    ルータセクション
    router.post("/email", async (req, res) => {
      try {
        const { school_email } = req.body;
        //school email에 대한 예외 처리 생략
        const authCode = Math.random().toString().substr(2, 6);
        const mailSender = new MailSender();
        const listener = new Listener(mailSender);
        listener.listen({
          targetEmail: school_email,
          type: "auth",
          authCode,
        });
        res.status(200).send({ authCode });
      } catch (err) {
        res.status(400).send({
          ok: false,
          message: err + " : email 전송 실패!",
        });
      }
    });
    他に解決すべき問題は、メールの転送に失敗したときに発生したエラーをテストして処理することです.