[SendGrid] C#でメールを送信する 1 

今日はSendGridを使ってメールを送ってみます。問い合わせフォームのメールからMA的なメール送信まで幅広く利用することを想定しています。利用用途は幅広く提供されている機能も多いので何度かに分けて整理したいと思います。 マイクロソフトからもドキュメントがまとめられているので、こちらのドキュメントも参照してください。https://docs.microsoft.com/en-us/azure/sendgrid-dotnet-how-to-send-email

# 環境
Visual Studio 2019, C#, ASP.NET Core 2.2
SendGrid API Version 3
もうすでにASP.NET Core プロジェクトがあるものとします。

# SendGridとは?

SendGridはメール配信サービスです。名だたるサービスがSendGridを使ってメール配信をおこなっています。自社でメールサーバーを持つような時代は終わって、SendGridに面倒なメンテ作業を任せて、メールを送ることだけにフォーカスすることができます。

Send Grid Official Page
https://sendgrid.com/

Azureからもマーケットプレイスで購入することができます。Azure Marketplaceから購入すると月25,000通まで無料。

# Azure Market Placeから購入

Azureのアカウントを持っている方はこちらのリンクからSendGridのサービスを購入。https://portal.azure.com/#create/Sendgrid.sendgrid

赤いマークがついてるフィールは必須なので埋めてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/0842763d-6e58-16ad-f879-125545851705.png)

今日は一番右にあるフリープランで進めます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/1db03da2-ac23-ef77-5c24-2cf3987451ef.png)

# ライブラリーの準備

SendGridを使ってメールを送信するには便利なライブラリーがあるので下記のNugetコマンドから入手します。 

SendGrid、C#用SDKGitHubはこちらから
https://github.com/sendgrid/sendgrid-csharp
.Net Core要のサンプルコードはこちらから
https://github.com/sendgrid/sendgrid-csharp/tree/master/ExampleCoreProject

パッケージマネージャーコンソールより

```
PM> Install-Package SendGrid
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/afed2dbf-4530-4773-cc7a-0d0578bcef5b.png)

SendGrid Version 9.11.0 がインストールされています。

# APIの準備

作成したSendGridメニューにある`Manage`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/253b7c5b-3d78-ab47-fe5f-8863d1e606de.png)

SendGridの管理画面がたちがりますので、右側にある`Setting`から`API Keys`をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/b3fe7df2-4a72-6a1e-6e39-c2be0966601e.png)

右上にある`Create API Key`をクリック。APIアクセスのアクセスレベルを選択して、名前を入力して作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/d88c5de3-7773-56e9-9268-4b16ae081554.png)

ここで生成されたAPI KeyをAppSettings.jsonに入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/96003fc0-ccbd-0e8f-6fa9-6ae173d48789.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/0044a30a-d053-68a4-db2b-ede02b5f6299.png)

これで一旦設定はおしまいです。次は実際にサービスを書いてみます。

# サービスを書く

まず、メールを送るサービスである
サービスクラスとインターフェイスを書きます。

他のサービスクラスも格納するため、サービスフォルダーとインターフェイスフォルダーを作成し。　サービスフォルダーに EmailSernder.csというクラス、インターフェイスフォルダーの中にIEmailSender.cs というEmailSender のインターフェイスを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/bf2fed50-12b5-4e21-ddd7-8b8b4c8a4083.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/59353b19-2541-3e2c-2f56-2437ce14bd5a.png)

```csharp:IEmailSender.cs
using SendGrid.Helpers.Mail;
using System.Threading.Tasks;

namespace wppSample.Services.Interfaces
{
    public interface IEmailSender
    {
        Task SendEmailAsyc(SendGridMessage msg);
    }
}
```

```csharp:EmailSender.cs
using Microsoft.Extensions.Options;
using SendGrid;
using SendGrid.Helpers.Mail;
using System.Threading.Tasks;
using wppSample.Models;
using wppSample.Services.Interfaces;

namespace wppSample.Services
{
    public class EmailSender : IEmailSender
    {
        /// <summary>
        /// For Secure API Value
        /// </summary>
        private readonly IOptions<AppSettings> _config;

        /// <summary>
        /// Construct and get _config
        /// </summary>
        /// <param name="config"></param>
        public EmailSender(IOptions<AppSettings> config)
        {
            _config = config;
        }

        /// <summary>
        /// Send Email via SendGrid
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public async Task SendEmailAsyc(SendGridMessage msg)
        {
            var client = new SendGridClient(_config.Value.SendGrid.ApiKey);
            var response = await client.SendEmailAsync(msg);
        }
    }
}

```

これでサービスをDIすることによって、メールが送れる状態になっています。次は具体的にメールフォームを送信したときの処理を書いてみます。

# 問い合わせフォームからメールを送る

まずは問い合わせフォームのRazorページ

```html:ContactUs.cshtml
@page
@model wppSample.Pages.ContactUsModel
@{
    ViewData["Title"] = "お問合せフォーム";
}

<div class="container py-4">
    <h1>お問合せ</h1>
    <p>
        下記のお問合せフォームをご利用ください。1-2営業日で返信させていただいています。
    </p>
    <div class="py-3">
        @using (Html.BeginForm(FormMethod.Post))
        {
            <div class="form-group">
                @Html.Label("お名前")
                @Html.TextBox("name", "", new { @class = "form-control border-color-2", @type = "Text", @style = "background-color:#FFFFEF", @placeholder = "お名前" })
            </div>
            <div class="form-group">
                @Html.Label("email", "メールアドレス", new { @class = "color-2" })
                @Html.TextBox("email", "", new { @class = "form-control border-color-2", @type = "Email", @style = "background-color:#FFFFEF", @placeholder = "メールアドレス" })
            </div>

            <div class="form-group">
                @Html.Label("inquiry", "問合せ内容", new { @class = "color-2" })
                @Html.TextArea("inquiry", "", new { @class = "form-control border-color-2", @style = "background-color:#FFFFEF; height:200px;", @placeholder = "問合せ内容" })
            </div>
            <div class="form-group">
                <input type="submit" class="btn btn-primary btn-rounded-0" value="送信" />
            </div>
        }
    </div>
</div>
```


## OnPostの処理

```csharp:ContactUs.cshtml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using SendGrid.Helpers.Mail;
using wppSample.Services.Interfaces;

namespace wppSample.Pages
{
    public class ContactUsModel : PageModel
    {
        private readonly IEmailSender _emailSender;

        /// <summary>
        /// Construct ContactUsModel
        /// </summary>
        /// <param name="emailSender"></param>
        public ContactUsModel(IEmailSender emailSender)
        {
            _emailSender = emailSender;
        }

        /// <summary>
        /// On Get Action
        /// </summary>
        public void OnGet()
        {

        }

        /// <summary>
        /// On Post Action
        /// </summary>
        /// <param name="name"></param>
        /// <param name="email"></param>
        /// <param name="inquiry"></param>
        public async Task<IActionResult> OnPostAsync(string name, string email, string inquiry)
        {
            // Send email to the customers to confirm the email sent

            var from = new EmailAddress()
            {
                Name = name,
                Email = email
            };

            var to = new EmailAddress()
            {
                Name = "Support",
                Email = "support email address"
            };

            var subject = "お問合せがありました";
            var plainCointent =　name + "さんより、問合せ内容: " + inquiry;
            var htmlContent = name + "さんの問合せ内容<br/><br/>" + inquiry;

            var msg = MailHelper.CreateSingleEmail(from, to,subject,plainCointent,htmlContent);

            // Send email to the customer support so that they can help the customer
            await _emailSender.SendEmailAsyc(msg);

            ViewData["Name"] = name;
            ViewData["Email"] = email;
            ViewData["Inquiry"] = inquiry;

            return RedirectToPage("Index");
        }
    }
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/e8952179-6ffc-d43b-5f97-099a20546f44.png)

こんな感じの問合せページからメールが送れている事が確認できました。

# 次

次回はフォームのバリデーションや、本人へも問合せ内容を知らせるメールを送ったりなどリッチな問合せフォーム体験を書きたいと思います。今日は一旦SendGridを動かすところまでに。