Skip to content

메일링 기능 구현하기

kyunghan edited this page May 28, 2021 · 6 revisions

메일 기능은 관리자가 사용할 수 있습니다.

관리자로 로그인한 후 초대관리 페이지에서 메일기능을 활용할 수 있습니다.

  1. 기자가 pre-signup을 통해 이메일과 이름을 관리자에게 전달하면 관리자가 이를 확인하여 역할을 지정하고, 해당 계정을 승인할지 거절할지 결정할 수 있습니다.

  2. 또는 관리자가 기자의 이메일과 이름 역할을 지정하여 해당 기자에게 메일을 직접 보낼 수 있습니다.

# lib/sendMail.js #


const nodemailer = require('nodemailer');

module.exports = (invitationId, email, code) => {
  if (code != '0') {
    const myEmail = {
      service:'gmail',
      auth: {
        user: process.env.GMAIL_USER_NAME,
        pass: process.env.GMAIL_PASSWORD,
      },
      tls: {
        rejectUnauthorized: false,
      }
    };
    const send = async (data) => {
      nodemailer.createTransport(myEmail).sendMail(data, function (error, info) {
        if (error) {
          console.log(error);
        } else {
          return info.response;
        }
      });
    };
    const content = {
      from: '[email protected]',
      to: email,
      subject: 'saver입니다',
      html: `<h1>SAVER</h1><a href="">http://saver.42seoul.io/author/signup?id=${invitationId}</a>`,
    };
    send(content);
  }
};

nodemailer 패키지를 활용하여 메일을 전송합니다.

메일 전송을 위해 invitationId, email, 역할 code를 받아야합니다.

myEmail의 user, pass에 자신의 Gmail계정과 비밀번호를 입력한 뒤 content의 내용을 전송합니다.

시나리오 1

기자가 직접 회원가입을 할 때

기자가 직접 회원가입을 할 때

기자가 직접 회원가입을 할 때는 saver.42seoul.io/pre-signup을 통해 회원가입을 요청합니다.

# controllers/authorController.js #

preSignupRequest: async (req, res, next) => {
    const { email, name } = req.body;
    try {
      await Invitation.create({ email, name });
    } catch (error) {
      if (error.errors) {
        error.errors.forEach((e) => {
          alert(e.message);
        });
      } else {
        alert('알 수 없는 에러 발생');
      }
      return res.redirect('/author/pre-signup');
    }
    alert('성공적으로 저장되었습니다.');
    return res.redirect('/author/login');
  },

기자가 이메일과 이름을 담아 회원가입 요청을 보내면 해당 정보를 토대로 Invitation을 생성합니다.

그리고 생성된 Invitation을 관리자가 살펴보고 기자로 승인할 지 거절할지를 결정합니다.

# controllers/authorController.js #

decision: async (req, res, next) => {
    const { approved, declined, email, code } = req.body;
    if (approved === '' && code !== '0') {
      const candidate = await Invitation.findOne({ where: { email } });
      const invitationId = candidate.id;
      candidate.state = 1;
      candidate.code = code;
      sendMail(invitationId, email, code);
      await candidate.save();
    } else if (declined === '') {
      await Invitation.update({ state: 3 }, { where: { email } });
    } else if (code === '0') {
      alert("역할을 설정해 주십시오!");
    }
    res.redirect('/author/_admin/invitation');
  },

관리자가 가입을 승인하거나 거절 했을 때 데이터베이스에서 Invitation을 찾아서 상태를 가입 대기중에서 가입 승인 상태로 변경하고, 이메일을 보내게 됩니다.

그러면 가입을 요청한 기자는 링크를 받아서 해당 링크로 회원가입을 할 수 있게됩니다.

시나리오 2

관리자가 기자를 초대할 때

관리자가 기자를 초대할 때

기자의 가입 요청없이 관리자가 직접 기자를 초대할 수 있습니다.

# controllers/authorController.js #

inviteRequest: async (req, res, next) => {
    const { invite, email, name, code } = req.body;
    if (email === '' || name === '' || code === '') {
      alert("빈 항목이 있어서는 안됩니다.");
    } else if (invite === '') {
      try {
        await Invitation.create({ email, name, code, state: 1 });
        const candidate = await Invitation.findOne({ where: { email } });
        const invitationId = candidate.id;
        sendMail(invitationId, email, code);
      } catch (error) {
        alert("에러가 발생하였습니다!");
      }
    }
    res.redirect('/author/_admin/invitation');
  },

관리자가 기자를 초대하는 경우에는 이메일과 이름 역할(코드)를 직접 지정하여 초대 메일을 보내게 됩니다.

이후 과정은 위와 같습니다.

출처

nodemailer

Clone this wiki locally