개인 프로젝트 진행 기록 : email 전송

인피니티·2024년 1월 18일
0

간단한 앱을 개발 중에 있는데, 문득 이런 생각이 들었습니다.

문의사항 같은걸 받을수 있게 하려면 어떻게 하는 것이 좋을까?

그리고 그것을 이메일로 받으면 되지 않을까 라는 생각에 이르렀고, 바로 실행으로 옮겼습니다.

구현도중 이메일 보다는 문의 게시판을 만드는게 더 좋을 것 같은데? 라는 생각도 들긴했는데, 거창하게 게시판에 남기는 것을 좋아하지 않을 수도 있는 사람도 있을테니, 이런 방법도 나쁘지 않다고는 생각이 들기는 합니다.

기능은 아래와 같습니다.

1. 상단의 메뉴에서 "만든사람 > 이메일" 을 선택할 수 있는 버튼 필요

버튼

<MenubarRadioItem value="andy" @click="email">
  이메일
</MenubarRadioItem>

다이아로그

<DialogEmail ref="emailRef" />

다이아로그 오픈

const emailRef = ref();
function email() {
  emailRef.value.onOpen();
}

2. 메일 전송 폼 필요

전송폼

  <Dialog @update:open="onOpen" :open="isOpen">
    <DialogContent class="w-5/6">
      <DialogHeader>
        <DialogTitle>이메일 양식</DialogTitle>
        <DialogDescription>
          만든이에게 궁금한점이나 질문사항이 있으시면 이메일을 보내주세요.
          <Badge variant="outline">연락처</Badge>,
          <Badge variant="outline">이메일 주소</Badge>는 필수는 아니지만, 답변을
          원하시면 남겨주세요.
        </DialogDescription>
      </DialogHeader>
      <div class="grid gap-4 py-4">
        <div class="grid grid-cols-4 items-center gap-4">
          <Label for="title" class="text-right"> 제목 </Label>
          <Input
            v-model="data.title"
            placeholder="궁금한 사항이 있습니다."
            class="col-span-3"
          />
        </div>
        <div class="grid grid-cols-4 items-center gap-4">
          <Label for="content" class="text-right"> 내용 </Label>
          <Textarea
            v-model="data.content"
            placeholder="Type your message here."
            class="col-span-3"
          />
        </div>
        <div class="grid grid-cols-4 items-center gap-4">
          <Label for="tel" class="text-right"> 연락처 </Label>
          <Input
            v-model="data.tel"
            placeholder="010-000-0000"
            class="col-span-3"
          />
        </div>
        <div class="grid grid-cols-4 items-center gap-4">
          <Label for="email" class="text-right"> 이메일 주소 </Label>
          <Input
            v-model="data.email"
            placeholder="inpiniti@gmail.com"
            class="col-span-3"
          />
        </div>
      </div>
      <DialogFooter>
        <Button @click="email"> 이메일 보내기 </Button>
      </DialogFooter>
    </DialogContent>
  </Dialog>

3. 메일 서버 필요

구글의 메일의 서버 연동하려고 한다면 아래의 2가지 절차를 거쳐야 합니다.

  • gmail > 설정 > IMAP 사용으로 변경
  • 2차 인증 (이걸 끝내면 pass 를 알려주는데, 기억해두셔야 합니다.)

4. 전송 api 필요

클라이언트에서의 전송 함수

async function email() {
  const {
    data: result,
    pending,
    error,
    refresh,
  } = await useFetch("/api/email", {
    method: "POST",
    body: JSON.stringify(data.value),
    onResponse({ request, response, options }) {
      console.log(response);
    },
  });
}

nodemailer 라는 라이브러리를 이용하였는데, 꼭 이걸 사용할 필요는 없습니다.

npm i nodemailer

nuxt 에서는 아래의 라이브러리를 추가 설치해야 했습니다.

npm i --save-dev @types/nodemailer

전송 소스

import nodemailer from "nodemailer";

export default defineEventHandler(async (event) => {
  let transporter = nodemailer.createTransport({
    // 사용하고자 하는 서비스, gmail계정으로 전송할 예정이기에 'gmail'
    service: "gmail",
    // host를 gmail로 설정
    host: "smtp.gmail.com",
    port: 587,
    secure: false,
    auth: {
      // Gmail 주소 입력, 'testmail@gmail.com'
      user: "개인 메일 주소",
      // Gmail 패스워드 입력
      pass: "2차 로 받았던 패스워드",
    },
  });

  await transporter.sendMail({
    from: `...`,
    to: `...`,
    subject: "...", // 타이틀
    text: "...", // 일반 text로 작성된 내용
  });

  return {
    result: "ok",
  };
});

5. 테스트 결과


단순히 html 이라고 전송시켯는데, 이 부분에 html 코딩을 하면 조금 더 그럴듯한 메일을 보내게 할 수 있을 것 같습니다.

profile
nuxt 개발자

0개의 댓글