SMTPとは?メール送信の仕組みと実装・エラー内容まとめ

SMTPとは?メール送信の仕組みと実装・エラー内容まとめ API
SMTPとは?メール送信の仕組みと実装・エラー内容まとめ
この記事は約8分で読めます。

でじぼうです。

開発をすると SMTP って言葉よく聞きますよね。
実際よくわかっていない人、集まってください!ご説明します。

でじぼう
でじぼう

この記事は下記の方がおすすめ!

  • SMTPってなに?
  • どう実装するのかわからない
  • エラーが出ても解読できない

Instagramフォロワー数9,500人を越える人気のもち・大福店 えにかいたもち

SMTPとは?

SMTP(Simple Mail Transfer Protocol)とは、メールを送るときに使われる通信ルールのことです。

「プロトコル」とは「決まりごと」という意味なので、SMTPは「メール送信用の決まりごと」と覚えるとシンプルです。

SMTPはどんなときに使われる?

Gmailなどでメールを送るとき、その裏側ではSMTPが働いて、「どこに」「誰が」「何を」送ったかを伝えています。

例えるなら、SMTPは「郵便局の配達員」のような存在です。
書いた手紙(メール)を相手の住所(メールアドレス)に届けてくれる役割です。

メール送信の流れ

SMTPとは?メール送信の仕組みと実装・エラー内容まとめ

SMTPでよく出る用語と設定項目

下記に、SMTP関連でよく利用する用語をまとめました。

用語意味
SMTPサーバー・メールを送信するための中継サーバー
例:Gmailなら smtp.gmail.com
ポート番号・サーバーと通信する入口番号
・SMTPでは 465(SSL)
587(STARTTLS) がよく使われる
SSL(465番)・通信の最初から最後まで、ずっと暗号化された状態でやりとりする方式
STARTTLS(587番)・最初は普通の通信で始めて、途中で暗号化される方式
認証(Auth)・送信者が本人かを確認する仕組み
・メールアドレスとアプリパスワードなどでログインする
host・SMTPサーバーのアドレス
smtp.gmail.comsmtp.sendgrid.net のような形
secure・暗号化方式の指定
true で SSLfalse で STARTTLS を使用

どっちのポート番号を使えばいいの?【465 or 587】

基本的には 587(STARTTLS)を使うのが推奨 です。

多くのメールサービス(Gmail、SendGrid、Outlook など)でも推奨されています。

その理由は

  • セキュリティ標準として TLS(STARTTLS)が新しい
  • ファイアウォールやISP(ネット回線業者でブロックされにくい
  • 相互運用性が高く、失敗しづらい

465(SSL)を使ってもいいの?

使ってもOKです。ただし注意点もあります。

比較項目587(STARTTLS)465(SSL)
推奨度推奨されている古いがまだ使われている
安全性高い(TLS)高い(SSL)※非推奨化の流れ
対応範囲広い一部でのサーバーのみ使えることも

SMTPとPOP/IMAPの違いを比較

メールの送受信には、それぞれ役割の違うプロトコルが使われています。
特に、SMTP・POP・IMAPの3つはよく登場しますが、それぞれ役割がまったく異なります。
下の表で、その違いを比べてみましょう。

プロトコル役割使いどころ
SMTPメールを送る・Gmailやアプリから送信するときに使われる
POPメールを受け取る(削除型)・サーバーからPCやスマホにダウンロードして削除する方式
・1台の端末だけでメールを管理したいときに向いている
IMAPメールを受け取る(サーバーに残す)・メールをサーバー上に残したままアクセス
・複数の端末で同じメールを見たいときに便利

SMTPを使った開発実装の例

Web開発では、例えば「お問い合わせフォーム」からの自動返信メールなどにSMTPが使われます。

フォーム入力 → SMTP経由で自動返信メールを送信する流れです。

    Node.js + nodemailer の実装例

    .env にSMTP情報を記載し、それをNode.jsで読み込んでメール送信を行うコード例です。

    SMTP_HOST=smtp.gmail.com
    SMTP_PORT=587
    SMTP_USER=your-email@gmail.com
    SMTP_PASS=your-app-password
    import nodemailer from "nodemailer";
    
    // .env.local に記載した SMTP情報を読み込む
    const transporter = nodemailer.createTransport({
      // 接続先のSMTPサーバー
      host: process.env.SMTP_HOST,
    
      // 使用するポート番号
      port: Number(process.env.SMTP_PORT),
    
      // ポートが465ならSSL通信(secure: true)、それ以外ならSTARTTLS(secure: false)
      secure: Number(process.env.SMTP_PORT) === 465,
    
      // 認証情報(メールアドレスとアプリパスワードなど)
      auth: {
        user: process.env.SMTP_USER,
        pass: process.env.SMTP_PASS,
      },
    });
    
    // メールの内容
    const mailOptions = {
      from: "your-email@gmail.com",
      to: "receiver@example.com",
      subject: "お問い合わせありがとうございます",
      text: "これは自動返信メールです。",
    };
    
    // 送信
    async function sendEmail() {
      try {
        await transporter.sendMail(mailOptions);
        console.log("メール送信に成功しました");
      } catch (error) {
        console.error("メール送信に失敗しました:", error);
      }
    }
    
    sendEmail(); // 関数を実行

    よくある設定ミス:「secureを省略」

    SMTP設定で以下のように書いている場合:

    port: Number(process.env.SMTP_PORT),
    secure: Number(process.env.SMTP_PORT) === 465,

    この secure の指定は省略せず、明示するのが推奨です。
    なぜなら、ポート番号だけでは nodemailer はどの暗号化方式(SSLかSTARTTLS)を使うか判断できないからです。

    port: 465,
    secure: false  // ← ポート465なのにSSLを使わない ⇒ エラーになる可能性大

    上記のように設定が矛盾していると、connect errorSSL wrong version number のようなエラーになります。

    正しい設定例

    // SSL(465番)で送信する場合
    port: 465,
    secure: true,
    // STARTTLS(587番)で送信する場合
    port: 587,
    secure: false,

    SMTPエラーと確認方法

    エラーの種類・確認方法の例をご紹介します。

    エラー確認方法

    • 開発環境:VSCodeのターミナルに表示
    • 本番環境:ログファイルに記載される等
    エラー表示意味
    SMTP Authentication errorメールアドレスやパスワード(アプリパスワード)が間違っている
    Connection timeoutポSMTPサーバーに接続できない(ポート番号やネット環境の問題)
    550 Relay not permitted外部ドメインへの送信がサーバー側で許可されていない
    getaddrinfo ENOTFOUNDSMTPサーバー名が間違っている、または存在しない
    SSL wrong version numberポートと secure の設定が合っていない
    ECONNREFUSEDサーバーが接続を拒否している(ホスト名やポートのミス)
    Invalid sender addressfrom アドレスの形式が正しくない、または拒否された


    認証エラーの場合、ターミナルに下記のようにエラー文が表示されます。

    Error: Invalid login: 535-5.7.8 Username and Password not accepted.

    コメント

    タイトルとURLをコピーしました