dotenv-railsを使ったグループへのGmail送信機能

この記事では、dotenv-railsを使ってGmailのメール送信機能を実装し、イベント通知を行うシステムをRailsで構築する方法について説明します。
今回はグループに入っているメンバーに，グループリーダーがメールを一括送信できるような機能を作成していきたいと思います．
グループ機能の作り方については、別の記事の方でまとめているので、こちらの方を参考にしていただけるとありがたいです。
https://qiita.com/TPO/items/d4b64688c8280c282f73
## 1. dotenv-railsの導入
まず、dotenv-railsをGemfileに追加します。


```:Gemfile
gem 'dotenv-rails', groups: [:development, :test]
```
<details>
<summary>※dotenv-railsとは</summary>
dotenv-railsは、Railsアプリケーションで環境変数を管理するためのGemです。`.env`ファイルに設定した環境変数をアプリケーション内で利用できるようにし、セキュリティや設定の管理を簡単にします。特に、開発やテスト環境での機密情報の管理に役立ちます。
</details>

その後、`bundle install`コマンドを実行します。

## 2. 環境変数の設定
プロジェクトのルートディレクトリに.envファイルを作成し、Gmailの認証情報を設定します。これにより、Gmailのアカウント情報をコードに直接記述することを避け、GitHubにアップロードされるのを防ぎます。

`.env`ファイルの内容：
```:.env
GMAIL_USERNAME=自分のメールアドレス
GMAIL_PASSWORD=自分のパスワード
```
ここに記述したメールアドレスからメールが送信されます．
<details>
<summary>※アプリケーションパスワードを使用する方法</summary>
セキュリティの観点から直接パスワードを記述せずにアプリケーションパスワードを用いて記述することもできます．

1.Googleのアカウント設定ページにアクセスします。
2.「2段階認証プロセス」に進み、ログインします。
3.「アプリケーションパスワード」をクリックします。
4.「メール」や「カスタム名前」を選択し、アプリケーションパスワードを生成します。
5. 生成された16文字のパスワードを.envファイルに使用します。

</details>



### 3. Action Mailerの設定
`config/environments/development.rb`に`Action Mailer`の設定を追加します。

```Ruby:config/environments/development.rb
  :
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address: 'smtp.gmail.com', #GmailのSMTPサーバーのアドレス
    port: 587, #GmailのSMTPサーバーのポート番号
    domain: 'gmaill.com',#送信するメールのドメイン
    user_name: ENV['GMAIL_USERNAME'], #ここに.envファイルに記述した文字列が入る
    password: ENV['GMAIL_PASSWORD'], #ここに.envファイルに記述した文字列が入る
    authentication: 'plain',
    enable_starttls_auto: true,
    open_timeout: 5,
    read_timeout: 5 
  }
end
```
## 4. eventモデルの追加
次に、`rails g model Event title:string content:text group_id:integer`でeventモデルを作成します。
作成されたら`rails db:migrate`しましょう．
```ruby:eventのマイグレーションファイル.rb
create_table "events", force: :cascade do |t|
class CreateEvents < ActiveRecord::Migration[6.0]
  def change
    create_table :events do |t|
      t.string :title #タイトル
      t.text :content #本文
      t.integer :group_id #送る先の外部キー

      t.timestamps
    end
  end
end
```
## 5. アソシエーションとバリデーションの追加
`event.rb`にアソシエーションとバリデーションを追加します。
```ruby:event.rb
class Event < ApplicationRecord
  belongs_to :group
  validates :title, presence: true
  validates :content, presence: true
end
```
### 6. ルーティングの追加

routes.rbに`events`用のルーティングを追加します。

```ruby:routes.rb
    :
    resources :groups do
      resource :group_users, only: [:create, :destroy] 
      resources :events, only: [:new, :create, :show] #追加
    end
    :
```
ルーティングは以下のようになっています．
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882438/74715dc5-13f0-1078-aad0-8bc10ad0b347.png)

## 7. ボタンの追加
メール作成画面へ遷移するためのボタンを追加します。

```erb:groups/show.html.erb
:
<% if @group.owner_id == current_user.id %>
  <td><%= link_to 'Edit', edit_group_path(@group.id), class: "btn btn-sm btn-success edit_book" %></td>
  <td><%= link_to 'Notice an Event', new_group_event_path(@group), class: "btn btn-sm btn-info" %></td>
<% else %>
:
```
![image (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882438/29563a74-cc3d-93a8-bf35-1f6fa2a06f59.png)

## 8. viewの作成
events/new(メール作成ページ)
```erb:events/new.html.erb
<div class='container'>
  <div class='row'>
    <div class="col-sm-12 col-md-8 col-lg-5 px-5 px-sm-0 mx-auto">
      <h2>Event Mail</h2>
      <%= form_with model: [@group, @event], local: true do |f| %>
        <div class="form-group">
          <%= f.label :title %>
          <%= f.text_field :title, class: "form-control" %>
        </div>
        <div class="form-group">
          <%= f.label :content %>
          <%= f.text_area :content, class: "form-control" %>
        </div>
        <%= f.submit "送信", class: "btn btn-primary" %>
      <% end %>
    </div>
  </div>
</div>
```
![image (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882438/1ecb788b-bd5f-3f9d-498e-fe26b570e856.png)


events/show(送信後の完了ページ)
```erb:events/show.html.erb
<div class='container'>
  <div class='row'>
    <div class="col-sm-12 col-md-8 col-lg-5 px-5 px-sm-0 mx-auto">
      <h1>送信が完了しました</h1>
      <p>内容は以下の通りです。</p>
      <p>[タイトル]</p>
      <p><%= @event.title %></p>
      <p>[本文]</p>
      <p><%= @event.content %></p>
    </div>
  </div>
</div>
```
![image (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882438/ba23666f-a5ce-1a84-ac3a-893c6661a1a4.png)

## 9. コントローラーの作成
`rails g controller Events`で`events_controller.rb`を作成し、イベントの新規作成、保存、表示を行います。

```ruby:events_controller.rb
class EventsController < ApplicationController
  def new
    @event = Event.new
    @group = Group.find(params[:group_id])
  end

  def create
    @group = Group.find(params[:group_id])
    @event = @group.events.new(event_params)
    if @event.save
      EventMailer.notice_event(@group, @event).deliver_now #重要
      redirect_to group_event_path(params[:group_id], @event.id)
    else
      render :new
    end
  end

  def show
    @event = Event.find(params[:id])
  end

  private

  def event_params
    params.require(:event).permit(:title, :content)
  end
end
```
この時createアクションに追記した
`EventMailer.notice_event(@group, @event).deliver_now`
で，RailsのAction Mailerを使用してメールを送信する処理を行っている．

`EventMailer`クラスの`notice_event(@group, @event)`メソッドで引数として`@group`と`@event`を受け取り、メールの内容を設定します。そして`deliver_now`でメールを即時に送信します。
それでは`EventMailer`クラスを作成していきましょう．



## 10. Mailer作成
`rails g mailer EventMailer`コマンドで`Mailer`を生成します。
`Mailer`とはメールの内容、送信先、送信元などを設定し、管理するためのクラスです．

```ruby:app/mailers/event_mailer.rb

class EventMailer < ApplicationMailer
  # 環境変数 GMAIL_USERNAME に格納されたメールアドレスを使用する。
  default from: ENV['GMAIL_USERNAME']

  def notice_event(group, event)
	#メールを送るuser達を代入
    @group = group
    @users = @group.users 
    
    #メール文(title,contentなど)を代入
    @event = event
    
    #@usersに代入されたuser全員に送信、件名は@eventのtitle
    mail to: @users.pluck(:email), subject: @event.title
  end
end
```
`default from: ENV['GMAIL_USERNAME']`は、`.env`ファイルに記述したメールアドレスを送信元として設定する記述
`def notice_event(group, event)`メソッドではコントローラーから受け取った`group`と`event`を使用して，メールの受信者として`@users`に，メールの内容(title,content)として`@event`に情報を格納します．
そして，`mail to: @users.pluck(:email), subject: @event.title`で`@users`の`email`属性を取得し，`@users`のメアドに`@event.title`という件名でメールが送信されます．
まとめると，`.env`ファイルに記述したメアドで，グループに入っている`@users`のメアドにメールが届くということである．
最後にメールの中身を記述して終わりです！



## 11. メールビューの作成
`app/views/event_mailer/notice_event.html.erb`でメールに表示させる内容を記述します。

```erb:app/views/event_mailer/notice_event.html.erb
<h1>イベント通知</h1>
<p>[タイトル]</p>
<p><%= @event.title %></p>
<p>[本文]</p>![スクリーンショット 2024-09-11 155512.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882438/ec33b0d8-3ea6-dbf3-3cbe-c8aff2818647.png)

<p><%= @event.content %></p>
```
![スクリーンショット 2024-09-11 160243.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882438/fa17ee32-ebd3-6dd1-daf8-0c12143634d1.png)
上記のようにメールが届いたら実装完了です！


# 最後に
最初の投稿なのでわかりにくい部分が多々あると思います🙇
呼んだ感想などをコメントしていただけるとありがたいです！