GitHub

[node.js] "실시간 메일 푸쉬를 받고 싶습니다" _ nodemailer 메일 알람 기능 구현

hojun lee · 09/05/2023
커버이미지

🎃 push 기능이 필요해진 이유

웹사이트를 의뢰해주신 법률사무소 대도 변호사님께 연락이 왔다.

실시간 상담 게시판에 글이 올라오면 알림을 받고 싶다는 것이었다.

사건의 발단은 이렇다. 업무로 바쁜 시간을 보내는 와중에 웹사이트에 접속해 매 번 게시판을 모니터링 하기엔 어려움이 있었고, 그로 인해 수임받을 수 있는 사건을 몇 건 놓쳤기 때문이다.

1~2시간만 지나도 더 빨리 응답한 법률사무소를 찾아가는게 응당한 이치이다. 고객의 입장에선 내 문제가 제일 중요하고! !impotant 한 사건이기 때문이다.

모든 마케팅에서 중요한 건 전환율을 이끌어 내는 것이다.

전환율 ( Conversion Rate )

특정한 행위를 한 방문자의 비율을 말합니다. 즉, 웹사이트 전환율은 웹사이트 방문 후 판매 및 유료 서비스 등의 구독 단계까지 진행한 방문자의 비율을 의미합니다.

기능 구현 목표 | svelteKit

실시간 상담이 들어오면 바로 메일 알람이 가게 해서 전환율을 높이는 작업을 해보자.

프레임워크는 svelteKit 입니다.

하지만 ssr을 기본으로 하는 프레임워크들과 사용방식은 비슷합니다. 응용만 하면 next.js에서도 사용할 수 있겠죠?

svelteKit + nodemailer

기능 프로세스

  1. 고객이 법률사무소 대도에 접속한다.
  2. 여러 정보를 읽어보고 믿어볼만하다고 판단한다.
  3. 실시간 상담문의에 글을 올린다.
  4. 이 과정에서 글이 등록됨과 동시에 메일이 발송되는 function을 추가한다.
  5. 제출 버튼 동작이 완료되면 글이 올라오고, 담당 변호사 메일로 푸쉬가 간다.
  6. 빠른 응답속도로 고객과의 접점을 만든다.
  7. 고객이 만족하며, 사업이 번창한다.

기존 node.js를 통해 구현해본 것을 토대로 추가 작성해본다.


nodemailer 패키지를 통해 server side에서 메일을 발송하는 컴포넌트를 만들자.

nodemailer 활용

install nodemailer Send emails from Node.js – easy as cake! 🍰✉️ 케이크처럼 쉽게 노드.js에서 메일들을 보낸다.

$> npm install nodemailer
  import nodemailer from 'nodemailer';

google 계정 활용 (앱 비밀번호)

!반드시 2차 비밀번호 보안인증이 된 계정만 사용가능함! google app password settings

  • https://myaccount.google.com/security 보안 탭 - 앱 비밀번호 탭
  • app account setting

구글 앱 비밀번호 활용하기

구글 앱

앱 선택 - 기타(노드를 쓸거니까) 기기 선택 - 기타 (mail-server) 이런식으로 써도됨

참고자료

그럼 앱 비밀번호가 나온다. 그 번호를 일단 잘 복사해둔다. 원래 nodemailer는 그냥 구글 id와 비밀번호를 그대로 받았는데 보안상의 문제로 이렇게 바뀐지 얼마 되지 않았다고 한다. 지금도 비밀번호를 그대로 넣을 수 있지만 기능이 제한된다고 한다.

위 내용을 숙지하며 GOOGLE_EMAIL 과 GOOGLE_EMAIL_PASSWORD의 값을 가지고 온다.

send 함수 작성

// .env
 GOOGLE_EMAIL=your_email
 GOOGLE_EMAIL_PASSWORD=위에서_받은_앱_비밀번호
 
// utils / emailSetup.server.js

import nodemailer from 'nodemailer';
import { GOOGLE_EMAIL, GOOGLE_EMAIL_PASSWORD } from '$env/static/private';

let transporter = nodemailer.createTransport({
    host: 'smtp.gmail.com',
    port: 587,
    secure: false,
    auth: {
        user: GOOGLE_EMAIL, //env에서 너가 넣은 값
        pass: GOOGLE_EMAIL_PASSWORD //env에서 너가 넣은 값
    }
});

transporter.verify(function (error, success) {
    if (error) {
        console.error(error);
    } else {
        console.log('Server is ready to take our messages');
    }
});

export default transporter;

form action에 메일 발송기능 추가

svelteKit에는 from action(댓글참고) 기능이 있다.

고객이 관련 폼을 입력해 제출을 누르면, form action이 작동하고, db에 글이 올라가는 프로세스였다. 여기에 메일을 발송하는 추가 기능을 추가하겠다.

// +page.server.js
import { GOOGLE_EMAIL } from '$env/static/private';
import transporter from '$lib/utils/emailSetup.server';

export const actions: Actions = {
 // 대충 formData 읽어와서 postgreSQL 에 때려넣는 코드
  
  
  //메일 발송 기능
  //html 형태로 내용을 담을 것임!
  //formData 가 있었기 때문에 메일에 간략한 내용을 담아준다.
  let html = `<h2>${title}</h2><pre>${name},${phone}<div>${context}</div><div>https://www.어드민페이지주소.com</div></pre>`;

  // 메일의 기본 정보
  const message = {
    from: GOOGLE_EMAIL,
    to: `메일 받을 사람 주소`,
     bcc: '참조인',
    subject: `🧙새로운 상담 등록, ${title}`,
    text: context,
    html: html
  };

// sendEmail function (비동기처리)
const sendEmail = async (message) => {
  await new Promise((resolve, reject) => {
    transporter.sendMail(message, (err, info) => {
      if (err) {
        console.error(err);
        reject(err);
      } else {
        resolve(info);
      }
    });
  });
};

await sendEmail(message);
  
}

form action에서 메일정보 폼을 만들고 transporter.sendMail 메서드를 통해 담당 변호사에게 메일이 발송된다.

간단하게 if 조건을 걸어주면 admin이 작성하거나 테스트용도로 보내는 메일이 푸쉬가지 않게 해줄 수도 있다.

메일 푸쉬 구현 완료!

테스트 메일

결론

실제 프로덕트, 상용 웹서비스를 개발한다는 건 개발을 잘한다를 넘어 서비스를 이해할 수 있는가가 중요한 점으로 작용한다고 생각한다. 나에겐 기획의 강점이 있었고, 그 영역은 개발이라는 무기를 하나 더 가지게 된 뒤 더 큰 역할을 하게 되었다. 서비스의 단위에서 포괄적으로 이해하며 개발하면 더 나은 개발자가 되리라 생각한다.


C++ 만든 Bjarne Stroustrup의 인생조언 지나지게 전문화(overspecialize)하지 마세요. 미래를 알고 있다고 너무 확신하지 마세요. 융통성을 가지고, 커리어와 직업은 장기적인 것이라는 것을 기억하세요. 너무 많은 젊은이들은 자신이 뭔가를 최적화 할 수 있다고 생각하고, Right Thing이 아닌 것에 전문화하면서 몇년이상을 소비했다는 것을 깨닫습니다. 그리고 그 과정에서 번아웃됩니다. 우정을 쌓고 컴퓨팅 밖에서의 삶을 사는데 충분한 시간을 보내지 않기 때문이에요.


살아가며 법적인 문제에 휘말리게 될지 아무도 몰랐을 걸요. 혹여나 당신이 그 문제에 직면해 있다면, 법률 사무소 대도를 만나보세요. 당신의 입장에 서서 생각하는 현명한 변호사가 당신과 함께할 거에요.