---
# System prepended metadata

title: Mailer

---

# Mailer
[TOC]

起手式

```ruby
gem install “mail”
```

google信箱容易被丟到垃圾郵件，以及一些奇怪的問題導致收不到信。

這裡採用第三方寄信服務[**mailgum**](https://www.mailgun.com/)

## mail設定

```ruby
# config/environments/development.rb

config.action_mailer.delivery_method = :smtp
  # delivery_method 有三種寄信方式 :test、:sendmail 和 :smtp
  # sendmail 須搭配 server 的 /user/bin/sendmail application
  # 而這邊我是透過 mailgun(and gmail) 的 smtp 協定作寄信
  # Mailgum
  config.action_mailer.smtp_settings = config_for(:email).symbolize_keys
  # config_for找到config目錄下的名為email的YAML設定檔，symbolize_keys將hash裡的string key轉為symbol key(smtp吃的是symbol key)

config.action_mailer.default_url_options = { host: "http://localhost:3000" }
  # 這邊填入的網址須要注意一下，他必須是絕對網址，且會被預設為 mail 中的 resource link
  # 像我是用 devise 寄發驗證信，所以 confirmation_url(@resource, confirmation_token: @token)
  # 中的 @resource 就會是 http://localhost:3000

config.action_mailer.raise_delivery_errors = true
  # rails_delivery_errors 設定為 false 可讓寄信時的錯誤被忽略，如果要 debug 就設 true
```

  - **mailgum登入後會給一串預設的資料，這裡選擇SMTP**

![](https://hackmd.io/_uploads/S1CKs75E2.png)



- **在config底下新增資料的yml檔，並且在.gitnore裡新增，為了在推送時排除掉自己的帳號密碼**

```ruby
development:
  address: "smtp.mailgun.org"
  domain: "Your Domain"
  authentication: "plain"
  port: 587
  user_name: "YourUserName"
  password: "YourPassWord"
  enable_starttls_auto: true
production:
  address: "smtp.mailgun.org"
  domain: "Your Domain"
  authentication: "plain"
  port: 587
  user_name: "YourUserName"
  password: "YourPassWord"
  enable_starttls_auto: true
```

- **Mail初始化**

![](https://hackmd.io/_uploads/rywIhXqV3.png)

```ruby
rails g mailer UserMailer hello_user
# 創建mailer的controller#hello_user這個方法及views
```


- **在app/mailers底下找到新建的user_mailer.rb**

```ruby
class UserMailer < ApplicationMailer

  # Subject can be set in your I18n file at config/locales/en.yml
  # with the following lookup:
  #
  #   en.user_mailer.hello_user.subject
  #
  def hello_user(user) # 給一個user的參數丟進去
    @user = user
    @greeting = "Hi"

    mail to: @user.email
  end
end
```

- **在views底下的user_mailer裡面生成了一個html以及一個純文字的模板**

![](https://hackmd.io/_uploads/BJ40s7qN3.png)

預先都不要更動，到rails console內測試看看

```bash
> rails c
Running via Spring preloader in process 4617
Loading development environment (Rails 6.1.6.1)
3.0.0 :001 > u1 = User.fint_by(email: "geminilin0619@gmail.com")
3.0.0 :001 > UserMailer.hello_user(u1).deliver_now!(現在就寄出！！)

# 若是沒問題就會收到信了
Rendering layout layouts/mailer.html.erb
  Rendering user_mailer/hello_user.html.erb within layouts/mailer
  Rendered user_mailer/hello_user.html.erb within layouts/mailer (Duration: 0.4ms | Allocations: 300)
  Rendered layout layouts/mailer.html.erb (Duration: 1.0ms | Allocations: 502)
  Rendering layout layouts/mailer.text.erb
  Rendering user_mailer/hello_user.text.erb within layouts/mailer
  Rendered user_mailer/hello_user.text.erb within layouts/mailer (Duration: 0.2ms | Allocations: 105)
  Rendered layout layouts/mailer.text.erb (Duration: 0.4ms | Allocations: 258)
UserMailer#hello_user: processed outbound mail in 63.7ms
 => #<Mail::Message:16680, Multipart: true, Headers: <Date: Tue, 06 Sep 2022 11:49:20 +0800>, <From: from@example.com>, <To: geminilin0619@gmail.com>, <Message-ID: <6316c3402a69c_13e4d0c46f3@VintLins-MBA.local.mail>>, <Subject: Hello user>, <Mime-Version: 1.0>, <Content-Type: multipart/alternative; boundary="--==_mimepart_6316c33edf229_13e4d0c4590"; charset=UTF-8>, <Content-Transfer-Encoding: 7bit>>
```

# signed_id

```ruby
u1 = User.last
u1.signed_in(expires_in: 15.minutes) # 設定15分鐘後失效
u1.signed_in(expires_in: 15.minutes, purpose: "reset_password") #加上reset_password訊息到token裡
```
![](https://hackmd.io/_uploads/Sy7G3Qc4n.png)
