MailKit を使用してメールを送信する

ページ作成日 :

環境

.NET
  • .NET 5.0
MailKit
  • 2.11.1

はじめに

以前はメールを送信するためのクラス「SmtpClient」が標準で含まれていましたが、仕様が古いため現在は非推奨となっています。

これにより .NET にはメール送信ライブラリが標準で備わっていないため、サードパーティー製のライブラリを使用することとなります。

現在主流なライブラリとして「MailKit」がありますので、今回これを使用してメールを送信してみたいと思います。

MailKit の導入

Visual Studio 2019 を起動し、新規でコンソールアプリ (.NET) のプロジェクトを作成します。 .NET を使用しているのであればプロジェクトの種類はある程度自由に使えるので詳細は割愛します。

プロジェクトを開いたらソリューション エクスプローラーから「依存関係」を右クリックして「NuGet パッケージの管理」を選択します。

「参照」タブをクリックして検索入力欄に「MailKit」と入力すると下の一覧に MailKit が表示されます。

一覧から MailKit を選択し、最新のバージョンが選択されていることを確認してから「インストール」ボタンをクリックします。

OK ボタンをクリックします。

パッケージに MailKit が含まれたことを確認します。

プログラム

以下はメールを送信するための最低限のコードとなります。

コードの前半にメールに必要な情報を定義し、後半はそれらの値を使用してメールを送信する処理になっています。 前半の定義を必要に応じて変えるだけで後半のコードは定型的に使用できるはずです。

using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
using MimeKit.Text;

namespace MailKitSend
{
  class Program
  {
    static void Main(string[] args)
    {
      // メールの送信に必要な情報
      var smtpHostName = "[SMTP サーバー名]";
      var smtpPort = 587;                         // or 25
      var smtpAuthUser = "[認証ユーザー名]";
      var smtpAuthPassword = "[認証パスワードまたはアプリパスワード]";

      // メールの内容
      var from = "[送信者メールアドレス]";
      var to = "[送り先メールアドレス]";

      var subject = "テストメールの件名です。";
      var body = "テストメールの本文です。\n改行です。";
      var textFormat = TextFormat.Text;

      // MailKit におけるメールの情報
      var message = new MimeMessage();

      // 送り元情報  
      message.From.Add(MailboxAddress.Parse(from));

      // 宛先情報  
      message.To.Add(MailboxAddress.Parse(to));

      // 表題  
      message.Subject = subject;

      // 内容  
      var textPart = new TextPart(textFormat)
      {
        Text = body,
      };
      message.Body = textPart;

      using var client = new SmtpClient();

      // SMTPサーバに接続  
      client.Connect(smtpHostName, smtpPort, SecureSocketOptions.Auto);

      if (string.IsNullOrEmpty(smtpAuthUser) == false)
      {
        // SMTPサーバ認証  
        client.Authenticate(smtpAuthUser, smtpAuthPassword);
      }

      // 送信  
      client.Send(message);

      // 切断  
      client.Disconnect(true);
    }
  }
}

メールの送信に必要な情報の定義

var smtpHostName = "[SMTP サーバー名]";
var smtpPort = 587;                         // or 25
var smtpAuthUser = "[認証ユーザー名]";
var smtpAuthPassword = "[認証パスワードまたはアプリパスワード]";

ここはどのメールサーバー (SMTP サーバー) を使うかによって設定する値が異なります。 この記事の最後の方で設定する値を少し説明しますが、基本的には使っているメールサーバーのサイトなどを参照してください。

本来は appsettigs.json などに記述するのですが Tips としては冗長になってしまうため割愛しています。

メールの内容の定義

var from = "[送信者メールアドレス]";
var to = "[送り先メールアドレス]";

var subject = "テストメールの件名です。";
var body = "テストメールの本文です。\n改行です。";
var textFormat = TextFormat.Text;

この部分は普通にメーラーなどを使用していればそのまま該当する部分だと思います。

from については最近のメールシステムでは偽装して送信できないようになっているので基本的にはメールアカウントと同じメールアドレスを設定することになります。

TextFormat についてはテキスト形式で送るか HTML 形式で送るかなどを指定できます。HTML で送る場合は body の部分に HTML タグなどを埋め込みます。

メール送信処理に必要な情報の設定

// MailKit におけるメールの情報
var message = new MimeMessage();

// 送り元情報  
message.From.Add(MailboxAddress.Parse(from));

// 宛先情報  
message.To.Add(MailboxAddress.Parse(to));

// 表題  
message.Subject = subject;

// 内容  
var textPart = new TextPart(textFormat)
{
   Text = body,
};
message.Body = textPart;

基本的には上記で定義した値を設定していく形になります。

From や To については複数設定することも可能です。

サンプルには含めていませんが CC や BCC も含めることができます。含める場合は以下のように From や To と同じ形で追加します。

message.Cc.Add(MailboxAddress.Parse(cc));
message.Bcc.Add(MailboxAddress.Parse(bcc));

また、メールの受け取り側が対応している場合、送信者や送り先の表示名を変えることも可能です。その場合は以下のようにコードを変更します。

message.From.Add(new MailboxAddress("送信者の名前", from));
message.To.Add(new MailboxAddress("送り先の名前", to));

メールの送信

using var client = new SmtpClient();

// SMTPサーバに接続  
client.Connect(smtpHostName, smtpPort, SecureSocketOptions.Auto);

if (string.IsNullOrEmpty(smtpAuthUser) == false)
{
   // SMTPサーバ認証  
   client.Authenticate(smtpAuthUser, smtpAuthPassword);
}

// 送信  
client.Send(message);

// 切断  
client.Disconnect(true);

メールに関連する定義が終わったら送信処理を行います。

送信は SmtpClient クラスのインスタンスで行います。Dispose 対象なので using var で宣言して自動的に解放処理ができるようにしています。 C# 8.0 の書き方なので、それ以前のバージョンの場合は通常の using の記述に直してください。

SmtpClient.Connect メソッドで SMTP サーバーに接続します。STMP サーバーによっては SSL 接続や TLS 接続が必要になりますが、SecureSocketOptions.Auto を指定しておけば大抵は問題ありません。

SMTP サーバーで認証が必要な場合は SmtpClient.Authenticate メソッドでユーザー名とパスワードを指定します。

接続が完了したら SmtpClient.Send メソッドでメールを送信します。

全てが完了したら SmtpClient.Disconnect メソッドで切断します。

なお、これらの処理は本 Tips では全て同期処理として実行していますが、各メソッドには xxxxxAsync という名前で非同期処理も実行できるようになっています。 必要に応じて使ってください。

添付ファイルを送付する方法

添付ファイルを送るには MimeMessage.Body に設定する値を以下のように変更します。

// using System.IO; 必要

var filePath = @"[ローカルに保存されているファイルパス].jpg";   // 例として JPEG ファイル指定
var buffer = File.ReadAllBytes(filePath);

var builder = new BodyBuilder();

// テキストか HTML で設定するプロパティが異なる
if (textFormat == TextFormat.Plain)
{
   builder.TextBody = body;
}
else
{
   builder.HtmlBody = body;
}

// 添付ファイルを追加
builder.Attachments.Add(Path.GetFileName(filePath), buffer, new ContentType("image", "jpg"));

message.Body = builder.ToMessageBody();

上記コードではローカルに保存されているファイルを添付ファイルとしていますが、データは byte 配列か Stream 化されていればよいので何でも構いません。 例として JPEG ファイルを送信しています。

MimeMessage.Body に設定する値は BodyBuilder として構築します。

Body のテキストは TextPart とは異なり、テキストか HTML かで設定先のプロパティが異なります。 両方設定しても先に設定したほうが消されますので注意してください。

添付ファイルは BodyBuilder.Attachments プロパティに追加していきます。 引数は「添付ファイルの名前」「添付ファイルデータ」「コンテンツタイプ (MIME)」となります。

「添付ファイルの名前」は拡張子を入れないと受け取り側で識別できない場合があるので注意してください。

ContentType に設定する値はファイル形式によって変わります。 インターネットで「ファイル形式 MIME」あたりで検索すれば組み合わせが分かると思います。

最後に BodyBuilder.ToMessageBody メソッドを呼んで MimeMessage.Body に設定します。

SMTP サーバーの指定について

メールを送信するための SMTP サーバーは使うメールサーバーによって設定が異なります。 以下は一例ですので、該当するものがない場合は使用しているサーバーのヘルプなどで確認してください。

また、2021年4月時点の情報ですので、現在情報が変わっている場合もあります。

メールサービス SMTP サーバー ポート 認証 2段階認証を使用している場合 暗号化
Outlook.com その1 smtp.office365.com 587 ユーザー名とパスワード ?? STARTTLS
Outlook.com その2 smtp-mail.outlook.com 587 ユーザー名とパスワード アプリパスワードを取得してパスワードに設定 STARTTLS
Gmail smtp.gmail.com 465(SSL) or 587(TLS) ユーザー名とパスワード アプリパスワードを取得してパスワードに設定 SSL or TLS or STARTTLS
Yahoo! メール smtp.mail.yahoo.co.jp 465 ユーザー名とパスワード ?? 種類不明
OCN smtp.ocn.ne.jp 465 ユーザー名とパスワード ?? SSL or TLS