LoginSignup
2
1

More than 1 year has passed since last update.

Next.js + サーバーサイドTypeScript + 関数フレーバーでクリーンなアプリを作ったので実装意図とか書く Advent Calendar 2022
20日目株式会社mofmofに生息しているshwldです。

前日はVitestでGraphQLとReactをテストするための環境づくりについて書きました

Node.jsでMailgunを使ってメールを送信する

/infrastructures/mailer/src/index.ts
import ky from 'ky';
import FormData from 'form-data';
import type { Mailer as MailerType, MailSendResult } from 'domain-interfaces';
import { Result, RuntimeError, tryCatch } from 'core-domain/src/shared';

const API_KEY = process.env.MAILGUN_API_KEY as string;
const MAILGUN_DOMAIN = process.env.MAILGUN_DOMAIN as string;

export const createMailer = (): MailerType => {
  const mailer: MailerType = {
    send(mail): Result<RuntimeError, MailSendResult> {
      const result = tryCatch(
        async () => {
          const data = new FormData();
          data.append('from', mail.from);
          data.append('to', mail.to);
          data.append('subject', mail.subject);
          data.append('html', mail.body);

          const response = await ky
            .post(`https://api.mailgun.net/v3/${MAILGUN_DOMAIN}/messages`, {
              headers: {
                Authorization: `Basic ${Buffer.from(`api:${API_KEY}`).toString(
                  'base64'
                )}`,
              },
              // @ts-ignore FIXME: error TS2322: Type 'FormData' is not assignable to type 'BodyInit | null | undefined'.
              body: data,
            })
            .json();
          const result = JSON.stringify(response);

          return {
            body: result,
          };
        },
        () => {
          return new RuntimeError('Mail Sender Error');
        }
      );

      return result;
    },
  };

  return mailer;
};

https://github.com/shwld/uzumaki/blob/advent-calendar/infrastructures/mailer/src/index.ts

const mailer = createMailer()
mailer.send({
  from: 'from@example.com';
  to: 'to@example.com';
  subject: '懸命に賢明な件名';
  body: 'ボディ';
})

npmパッケージを使わない理由

npm: mailgun.js というのがあるんですがなぜ使わなかったのか。
謎です(覚えてない)

turbopackでのバンドルが理由だった気がしますが...
謎です。

次回予告

明日は、GraphQL Subscriptionについて書きます。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1