📧

2024年2月でもメールを送信したい【Node・SendGrid】

2024/03/01に公開

最近ナウい記事書いてます。
有償本ですが「結局今(2024年)「Firebase Authentication」を使うには(Nuxt3 × Vercel)」たった300円です。
まだ未対応の方はどうぞ。

はじめに

2024年2月ごろからGoogleとかYahooのメールの規約?が厳しくなったようだ。
色々読んだが正直なんのこっちゃわからない。
正直メールの仕組みなんてしっかり勉強したことがない。
誤り等があれば是非是非指摘していただきたい。

取り合えず中身を読みたい人は「Node × SendGrid」まで飛んでくだされ。

現在弊社ではPHPが使用できるレンタルサーバがあって、だいたいそこからメールを送っている。
レンタルサーバ内にメールサーバがあるんであろう。
送信時の「From」は弊社のメールアドレスにしているが、特にそれ用の設定はしてないので、ある意味送り主を偽っている。これまでですらちょっと怪しい感じだった。

ところで、ちょうど弊社ではバックエンドをNodeに切り替えている最中であり、大したことのない(と言うと失礼だが)サービスはVercel等でデプロイしている。
調べちゃないがまずメール機能など使えないであろう。

ということで、いよいよメール配信サービスに手を出す時が来たのである。
メール配信サービスを使えば、さすがにGoogleやYahooにも準拠してるよね!という完全無欠な論法である。もしこれが揺らいだらやり直しなので、これでだめだったら教えてほしい。

サービス選定

メール配信サービスと言えば、最初に思い浮かんだのが「SendGrid」、5年は前にAWSを使ってた際には、なんか「SendGrid」をお勧めされてた気がします。

さて、改めてメール配信サービス調べてみると出るわ出るわ
https://www.bloggersideas.com/ja/best-sendgrid-alternatives/
https://kinsta.com/jp/blog/mailchimp-alternatives/
https://www.poptin.com/blog/ja/sendgrid-alternatives/

ここで選べってのはちょっと無理があるので、別の方向から探します。
現在弊社では「Firebase」を使用しています。Firebaseの拡張から使えると便利だなー、と思ったので、拡張で「mail」調べて出てきたのを見てみます。

  • MailerSend
  • SendGrid

MailerSend

MailerSendは「SendGrid」以外では現在唯一の「Firebase拡張」のある配信サービスです。
結構使いやすいと思いますし、ドメインのDNSの設定をすることになるので、本格的に正規のメールを送信できると思います。
が、以下の2点欠点があります。

  • 日本語がない
  • 審査が取らない

日本語がないのは日常茶飯事なんですが、色々設定させた後に審査があり、その審査が通らないんですよね。
いや先に審査しろよと、というか審査通してくれよ正規の会社だしDUNSもあるんだから、と思うわけですが、日本語がないのも関係してますが、はっきりと何を入力してほしいのか、拒否された時にその理由が何なのか、これが良くわからないんです。

ざっくりいうと、「ドメインにアクセスできません」なのだけれど、ドメインってなんだよ。
ドメインというワードが意味が広すぎてわからぬ、、、
日本で一般的にドメインというと、所謂URLに含まれるあのドメインですけども、ドメイン駆動設計、なんかのワードもある通り意味はかなり広いと思われます。
メールの設定や送信テストは済ませてあるので、メールに使うドメインは良いはずだし、後はせいぜい会社のHPなのだけれど。
うちはホームページにゃ金かけねえ、という意思でGoogleサイトでHP作ってますが、それが海外だからと言ってアクセスできないことあるだろうか?
うーんわからん。一応VPN的なのかませて表示してみたけれど、ちゃんと表示される。
日本語だからわからん、ということならありえそうだけど、それならそうと言ってくれ、というか書いといてくれ、という感じ。

ま、理由はともかく、5,6回は申請したけれど結局通らなかったので断念。
通った方がいたら教えてくださいまし。

SendGrid

さて、はじめにSendGridの印象というか使ってみた感じですけども「最悪です!!」。
いやー、サイト遅いし、見にくいし、サイトの説明も整ってない(古い)とか不具合があるとか。
とはいえ、今回の目的に適って使えるのはSendGridだけだし、老舗ではあるので、今回は使うんですけどね。
これで老舗じゃなかったら違うとこ使ってますね。

ただ、良くも悪くも日本の代理店が入っていて、日本語で諸々できるのは悪くないと思います。
また、どうやら代理店を経由することで料金や機能も違うようですが、それが4月には解消されるという話もあるので、そのあたりは見守りましょう。
*どうしても日本語が良いのでなければ、直接アクセスして直接利用するほうが良い気はします。
*私は公式で作り直しました、代理店には怒られそうですね

Node × SendGrid

ここからが本題です。
WEB上の設定等についてはここでは概要のみ書きます。

審査(代理店経由の場合)

登録後に審査があります。審査はなんか1つのサービス・アプリについて聞かれてる気がしますが、アプリごとに審査、というわけでもない、というか、アプリごとにどうこう、という機能はない(と思う)ので、色々使いたい方は全体を記載したほうが良いかもしれません。

審査が無い?

代理店を経由せずに登録したところ、なんか手順は結構認証が多くて大変でしたが、審査はありませんでした。

送信者認証

「Single Sender Verification」を必要に応じてやります。送信者(アドレス)を登録してメールを確認するだけなので簡単です。これはしておいたほうが良いでしょう。

ドメイン認証

「Domain Verification」を必要に応じてやります。MailerSendと同様、DNSにCNAMEやらTXTのレコードを設定します。CNAMEが5件、TXTが1件となんか多いですけど。
恐らくここまでしておくと完璧でしょう。
Googleドメインをお使いの方は急ぎGoogleドメインで行ったほうが良い気はします。
「Squarespace Domains」使ったことないですけどどうなんですかね。

実際に送信する(Web API)

ようやっと実際のコードとかです。
言語は8つです。cURLに対応しているので究極なんでもいけるでしょう。

今回はNodeです。
公式は以下の通りです。
因みにGithubはこちら

sendMail.js
const sgMail = require('@sendgrid/mail')
sgMail.setApiKey(process.env.SENDGRID_API_KEY)
const msg = {
  to: 'test@example.com', // Change to your recipient
  from: 'test@example.com', // Change to your verified sender
  subject: 'Sending with SendGrid is Fun',
  text: 'and easy to do anywhere, even with Node.js',
  html: '<strong>and easy to do anywhere, even with Node.js</strong>',
}
sgMail
  .send(msg)
  .then(() => {
    console.log('Email sent')
  })
  .catch((error) => {
    console.error(error)
  })

まあ、特に問題は無いんですが。
TypeScriptの例が無いので、うちの使い方の例です。

sendMail.ts
import sg from '@sendgrid/mail';

export const sendSGMail = (to: string, subject: string, text: string, html: string | null): Promise<void> => {
    if (!process.env?.SENDGRID_API_KEY) return;
    sg.setApiKey(process.env?.SENDGRID_API_KEY.trim());

    let msg: sg.MailDataRequired = {
        to: to,
        from: 'info@nexsjp.com',
        subject: subject,
        text: text,
        html: html || undefined,
    };
    return sg.send(msg)
        .then(() => {
            console.log('Email sent');
            return some;
        })
        .catch((error) => {
            console.error(error);
            console.error(error.response.body);
            return some;
        });
}

「sg」は「sgMail」としたほうが公式準拠です。

発行されるAPIキーは環境変数「SENDGRID_API_KEY」に設定することが推奨されているのでそのようにしますが、TSではundefinedは許されないので例ではreturnしてます。
また、通常問題ありませんが、環境によってはスペース等入ることがあるようなので「.trim()」を付けておくとより安心でしょう。

さて、フィールドに「text」と「html」がありますが、両方設定した場合は「html」が優先されると思われます。
片方のみ設定した場合は当然そちらになります。
私が引っ掛かったのは、htmlに空文字を入れた場合で、空文字では送信できずにエラーとなります。
「text」メールを送信する場合は、htmlを設定しないか、明示的にundefinedを設定しましょう。
以下に関連して気を付けること、気付いたことを上げます。

  • 400エラー(認証エラー)が出ることがあった、原因は不明でAPIキーは正しく設定されていた。APIキーを同名で複数作っていたので、使うものだけに絞ったりしている間に解決した。
  • 401エラーが出た。上記の「html」が空文字であったことによるエラー。
  • 「error」のネストが深く、通常設定ではconsole.log(error)で原因まで表示されない。
    console.log(error.response.body);で表示する。
  • 上記エラーで、「contentフィールドは空にできない」などと言われるが、contentとは恐らく「text」と「html」フィールドのことで、「content」フィールドはない。
  • 上記エラー時に参照すべきURLが表示されるが、表示されたURLの項はない。
  • メール中URLはSendGrid経由のURLに変換される。URLのクリック数を数える等の理由と思われる。設定で変えられる可能性はある。
  • たまにSendGridのページ自体が開けなることがある。キャッシュ削除して再度試す。
  • 代理店経由の場合、会社情報入力等ページが使用できない。その旨の記載が無いので不親切ではある。
  • 代理店経由の場合、2024年4月よりFreeプランで送信できるメール数が12,000通/から100通/になる。なお、完全な従量課金プランは無く、基本料+従量課金になる。基本料は2,400円からとそれなりにする。
  • 代理店を経由してない場合はそもそもが変更後の価格、ただしドル建てになる。19.95ドルの為、代理店を経由したほうが安い。

Discussion