ginでメールを送信する機能を作成する

# はじめに
- GmailやOutlookなどのメールアプリにメールを送信する関数を作成したのでその備忘録です。

# 目次
1. **どんな機能を作成したかの概要**
1. **実際のコード**
1. **保存した値の編集方法**

# どんな機能を作成したかの概要
- 任意のタイミングでメール送信するとメールアプリに下記の画像のようなメールが送信されます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758326/1679fc32-db55-4749-8616-41a6744fb38e.png)

# 実際のコード
- 実際のコードは下記の関数を使用します。
```go:email_service.go
func (s *EmailService) SendWelcomeEmail(to string) error {
	// 環境変数から必要な情報を取得
	smtpHost := os.Getenv("SMTP_HOST")
	smtpPort := os.Getenv("SMTP_PORT")
	smtpUsername := os.Getenv("SMTP_USERNAME")
	smtpPassword := os.Getenv("SMTP_PASSWORD")

	// 送信元は SMTP_USERNAME を利用
	from := smtpUsername

	subject := "エンジニアのポートフォリオ へようこそ！"
	body := `
    <html>
    <body>
        <div style="font-family: Arial, sans-serif; color: #333;">
            <h2>エンジニアのポートフォリオ へようこそ！</h2>
            <p>この度はご登録ありがとうございます！エンジニアのポートフォリオは「エンジニアを目指す、すべての学生のためのプラットフォーム」です。</p>
            <p>他大学の学生ポートフォリオを見ることで本格的な就職活動でご利用いただけます！</p>
            <p>プロフィールや作品をアップすることによって、企業の人たちがあなたを見つけることができるようになるかもしれません。ぜひあなたのことを、あなたの作品や言葉で教えてくださいね。</p>
        </div>
    </body>
    </html>
    `

	message := []byte("To: " + to + "\r\n" +
		"Subject: " + subject + "\r\n" +
		"MIME-version: 1.0;\r\n" +
		"Content-Type: text/html; charset=\"UTF-8\";\r\n" +
		"\r\n" + body + "\r\n")

	// SMTP認証情報の設定
	auth := smtp.PlainAuth("", smtpUsername, smtpPassword, smtpHost)

	return smtp.SendMail(smtpHost+":"+smtpPort, auth, from, []string{to}, message)
}

```

- **SMTPサーバーに関する情報を取得する**
    - 以下のコードで**SMTPサーバーの情報を取得しています**。
    ```go:email_service.go
    smtpHost := os.Getenv("SMTP_HOST")
	smtpPort := os.Getenv("SMTP_PORT")
	smtpUsername := os.Getenv("SMTP_USERNAME")
	smtpPassword := os.Getenv("SMTP_PASSWORD")
    ```
    - そもそもsmtpサーバーを含んだメール送信の一連の流れは以下の図のようになります。
    
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758326/ee41c66a-369d-4ea3-83d9-59f8dce09ab7.png)


    - この図を見ればわかるように**smtpサーバーを用意する必要がある**ので、それらの情報を取得しなければなりません。
    - 今回はsmtpサーバとして**Gmail SMTPサーバー**を採用しています。このsmtpサーバーでは**このサーバー専用のGoogleアカウントを用意する**ことが推奨されると思います。
    - envファイルから取得する必要のあるsmtpサーバーに関連した認証情報は以下の通りに指定しました。

    | SMTP_HOST | SMTP_PORT | SMTP_USERNAME | SMTP_PASSWORD |
    |---------|---------|---------| ---------|
    | smtp.gmail.com | 587 | Googleアカウントのメアド | アプリパスワード |

    - アプリパスワードとは普通のパスワードのことではありません。この[リンク](https://security.google.com/settings/security/apppasswords)から入手してください。
    :::note warn
    - 前提として**Googleアカウントの2段階認証が有効になっている必要**があります。もし必要であればこの[リンク](https://support.google.com/accounts/answer/185839?hl=ja&co=GENIE.Platform%3DDesktop)を活用にして2段階認証を有効にしてください。

    - また、**アプリパスワードは１度しか表示されない**ので気を付けてください。

    

- 以下のコードで**メールの本文と件名を作成**します。**HTML形式**で作成しています。
```html
    subject := "エンジニアのポートフォリオ へようこそ！"
    body := `
    <html>
    <body>
        <div style="font-family: Arial, sans-serif; color: #333;">
            <h2>エンジニアのポートフォリオ へようこそ！</h2>
            <p>この度はご登録ありがとうございます！エンジニアのポートフォリオは「エンジニアを目指す、すべての学生のためのプラットフォーム」です。</p>
            <p>他大学の学生ポートフォリオを見ることで本格的な就職活動でご利用いただけます！</p>
            <p>プロフィールや作品をアップすることによって、企業の人たちがあなたを見つけることができるようになるかもしれません。ぜひあなたのことを、あなたの作品や言葉で教えてくださいね。</p>
        </div>
    </body>
    </html>
```

- 以下のコードで**メールを組み立てています**。メールメッセージをMIME形式で組み立てます。宛先、件名、MIMEバージョン、コンテンツタイプ（HTML形式）を指定します。

    ```go:email_service.go
        message := []byte("To: " + to + "\r\n" +
            "Subject: " + subject + "\r\n" +
            "MIME-version: 1.0;\r\n" +
            "Content-Type: text/html; charset=\"UTF-8\";\r\n" +
            "\r\n" + body + "\r\n")
    ```
    - **このコードに記述されている「to」は引数として扱われていて、受信者のメールアドレスが格納**されています。

- 以下のコードでSMTPサーバーの認証情報を設定してSMTPサーバー経由でメールを送信しています。
```go:email_service.go
    auth := smtp.PlainAuth("", smtpUsername, smtpPassword, smtpHost)
	return smtp.SendMail(smtpHost+":"+smtpPort, auth, from, []string{to}, message)
```
# まとめ
- 今回はsmtpサーバーを使用したメール送信の仕方に関してまとめました。しかしよくわからないところもぶっちゃけ多い。。。これは勉強するべきなのか必要ないのか。。。