【问题标题】:Sendgrid API for Ruby on RailsRuby on Rails 的 Sendgrid API
【发布时间】:2016-07-24 16:36:40
【问题描述】:

我似乎找不到关于如何将 Sendgrid Web API 集成到 Ruby on Rails 应用程序的分步教程。我对此很陌生,所以也许我遗漏了一些明显的东西。

我想使用 Sendgrid Web API 而不是 smtp 传递方法(mailgun 在这里讨论了 Web API 相对于 SMTP 方法的好处:https://documentation.mailgun.com/quickstart-sending.html,我认为 Sendgrid 要么具有相同的好处或者我以后可能会切换到mailgun)。

安装 sendgrid gem (https://github.com/sendgrid/sendgrid-ruby) 后,文档告诉我“使用您的 SendGrid API 密钥创建一个新客户端”,我可以通过两种方式完成:

require 'sendgrid-ruby'

# As a hash
client = SendGrid::Client.new(api_key: 'YOUR_SENDGRID_APIKEY')

# Or as a block
client = SendGrid::Client.new do |c|
  c.api_key = 'YOUR_SENDGRID_APIKEY'
end

我应该把这段代码放在我的应用程序的什么地方?我应该把它放在我的邮件程序、我的应用程序邮件程序还是 config/environments/production.rb 文件中?

我查看了本教程,其中介绍了如何设置 Mailgun API:https://launchschool.com/blog/handling-emails-in-rails

根据本教程,client = SendGrid::Client.new(api_key: 'YOUR_SENDGRID_APIKEY') 行实际上应该进入邮件方法本身。请参阅下面的 launchschool.com 示例(可能将 mailgun 特定信息替换为 sendgrid 信息):

class ExampleMailer < ActionMailer::Base

      def sample_email(user)
    @user = user
    mg_client = Mailgun::Client.new ENV['api_key']
    message_params = {:from    => ENV['gmail_username'],
                      :to      => @user.email,
                      :subject => 'Sample Mail using Mailgun API',
                      :text    => 'This mail is sent using Mailgun API via mailgun-ruby'}
    mg_client.send_message ENV['domain'], message_params
  end
end

此外,我如何让我的邮件方法发​​送邮件视图,而不是像 launchschool 示例中所述的简单文本?例如,我想发送一个邮件视图(类似于 account_activation.html.erb),而不是发送文本“此邮件是使用...发送的”。

最后,我在我的应用程序中使用了 Devise,我想让 Devise 使用 Web API 来发送电子邮件(即密码重置等)。这是否意味着我需要为 Devise 创建一个自定义邮件?如果是这样,我该怎么做?

根据 Devise (https://github.com/plataformatec/devise/wiki/How-To:-Use-custom-mailer),我应该“创建一个扩展 Devise::Mailer 的类”。这是否意味着我只需在我的邮件文件夹中创建一个文件,其中包含文档中列出的信息?我是否需要单独的 Devise 邮件程序,或者我可以从 Devise 邮件程序继承现有的邮件程序?最后,我如何告诉 devise 使用 sendgrid web api 发送电子邮件(而不是简单的 smtp 方法)?

抱歉这个问题太长了,但希望其他人觉得它有用。

谢谢!

【问题讨论】:

标签: ruby-on-rails email devise sendgrid mailgun


【解决方案1】:

我会创建一个邮件类来执行此操作

class SendgridWebMailer < ActionMailer::Base
  include Sendgrid

  def initialize
    @client = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY']).client
  end

  def send_some_email(record, token)
    mail = Mail.new
    // do your mail setup here
    mail = Mail.new
    mail.from = Email.new(email: YOUR_EMAIL_HERE)
    mail.subject = YOUR_SUBJECT

    // I personally use sendgrid templates, but if you would like to use html - 
    content = Content.new(
      type: 'text/html',
      value: ApplicationController.render(
        template: PATH_TO_TEMPLATE,
        layout: nil,
        assigns: IF_NEEDED || {}
      )
    mail.contents = content 

    personalization = Personalization.new
    personalization.to = Email.new(email: EMAIL, name: NAME)
    personalization.subject = SUBJECT

    mail.personalizations = personalization
    @client.mail._('send').post(request_body: mail.to_json)
  end
end

调用它使用

SendgridWebMailer.send_some_email(record, token).deliver_later

为了设计

 class MyDeviseMailer < Devise::Mailer
   helper :application # gives access to all helpers defined within `application_helper`.
   include Devise::Controllers::UrlHelpers # Optional. eg. `confirmation_url`

   def reset_password_instructions(record, token, opts={})

      SendgridWebMailer.send_some_email(record, token).deliver_later
   end
end

在 config/devise.rb 中

# Configure the class responsible to send e-mails.
  config.mailer = 'MyDeviseMailer'

【讨论】:

  • 为什么SendgridWebMailer需要继承ActionMailer::Base
【解决方案2】:

编辑:

很遗憾,此方法仅适用于远程图像。


好的,这就是我的做法。可能有更好的方法来做到这一点,但这对我有用。

因此,在发送电子邮件时,您最初会通过 UserMailer.reset_email(user).deliver 之类的方式发送它。所以删除交付并将其保存到变量中:

object = UserMailer.reset_email(user)

深深嵌套在这个ish中的是电子邮件的正文。它所在的位置可能会随着上下文而变化,所以我的建议是将对象返回到前端,以便您可以深入挖掘并找到它。对我来说,身体就住在这里:

object = UserMailer.reset_email(user)
body = object.body.parts.last.body.raw_source

好的,现在你得到了原始来源。现在发送它,这是我创建的一个方法:

def self.sendEmail(from,to,subject,message)
    from = Email.new(email: from)
    to = Email.new(email: to)
    content = Content.new(type: 'text/html', value: message)
    mail = Mail.new(from, subject, to, content)

    sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
    response = sg.client.mail._('send').post(request_body: mail.to_json) 
    puts response.status_code
    puts response.body
    puts response.headers
  end

这样称呼它(在我的例子中,它在用户模型中):

User.sendEmail('noreply@waydope.com',user.email,'Reset Password', body)

确保将内容类型从纯文本更改为 html,否则您只会得到原始代码。希望这可以帮助。

【讨论】:

    【解决方案3】:

    这是一个分步指南,可帮助您将 SendGrid 集成到您的 RoR 应用程序中。希望对您有所帮助!

    • 首先创建一个 SendGrid 帐户:http://sendgrid.com/
    • 创建一个新的 rails 文件夹 (sendgrid_confirmation)

      • rails new sendgrid_confirmation
    • 导航到“sendgrid_confirmation”文件夹

      • cd sendgrid_confirmation
    • 在您的文本编辑器 (Sublime) 中打开“sendgrid_confirmation”

    • 创建一个用户模型(用户是一个测试模型,您可以根据项目的用途创建任何其他模型)

      • rails 生成脚手架用户名邮箱登录
      • rake db:迁移
    • 在你的 Gemfile 中包含 sendgrid-rails gem

      • gem 'sendgrid-rails', '~> 2.0'
    • 在终端中运行 bundle install

      • 捆绑安装
    • 使用 secrets.yml 定义 SendGrid API 凭据:(config/secrets.yml) 生产: sendgrid_username:您的发送网格用户名 sendgrid_password:您的发送网格密码 (电子邮件不在开发和测试环境中发送。因此您只能将其定义为生产环境。)

    • 生成一个 Mailer 类。 Mailer 类充当我们的电子邮件视图控制器。

      • rails 生成邮件程序 UserNotifier
    • 打开 app/mailers/user_notifier.rb 并添加以下向用户发送注册邮件的邮件操作

    class UserNotifier < ActionMailer::Base
      default :from => 'any_from_address@example.com'
      # send a signup email to the user, pass in the user object that  contains the user's email address
      def send_signup_email(user)
        @user = user
        mail(:to => @user.email,
          :subject => 'Thanks for signing up for our amazing app')
      end
    end
    
    • 如下创建文件 app/views/User_notifier/send_signup_email.html.erb:(这将创建一个与我们的操作对应的视图并为我们的电子邮件输出 HTML)

    <!DOCTYPE html>
        <html>
            <head>
                    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
            </head>
            <body>
                    <h1>Thanks for signing up, <%= @user.name %>!</h1>
                    <p>Thanks for joining and have a great day! Now sign in and do awesome things!</p>
            </body>
        </html>
    
    • 转到用户控制器 (app/controllers/users_controller.rb) 并在保存用户时添加对 UserNotifier.send_signup_email 的调用。

    def create
      @user = User.new(user_params)
      respond_to do |format|
        if @user.save
          UserNotifier.send_signup_email(@user).deliver
          format.html { redirect_to @user, notice: 'User was successfully created.' }
          format.json { render :show, status: :created, location: @user }
        else
          format.html { render :new }
          format.json { render json: @user.errors, status: :unprocessable_entity }
        end
      end
    end
    
    • 更新您的 config/environment.rb 以将您的 ActionMailer 设置指向 SendGrid 的服务器。您的 environment.rb 文件应如下所示:

    # Load the Rails application.
    require File.expand_path('../application', __FILE__)
    
    # Initialize the Rails application.
    Rails.application.initialize!
    
    ActionMailer::Base.smtp_settings = {
        :user_name => ‘your_sendgrid_username’,
        :password => 'your_sendgrid_password’,
        :domain => ‘your_domain.com',
        :address => 'smtp.sendgrid.net',
        :port => 587,
        :authentication => :plain,
        :enable_starttls_auto => true
    }
    
    • 指向您的 config/routes.rb 文件以在加载时加载索引页面。在您的 routes.rb 文件中添加以下内容:

    get ‘/’ => ‘users#index’
    

    就是这样!现在,当您创建新用户时,您应该会收到一封来自any_from_address@example.com 的电子邮件(在您提供的 user.email 上)。您可以将其更改为:来自app/mailers/user_notifier.rb 的电子邮件。更改默认 :from 地址,它应该这样做。您可以在同一文件内的 send_signup_mail 方法中添加电子邮件参数,并添加您想要添加的详细信息。您还可以将邮件正文从 app/views/user_notifier/send_signup_email.html.erb 更改为显示您想要的任何内容。

    【讨论】:

    • 虽然这个答案正确解释了(如 sendgrid 文档)如何使用 SMTP 从您的 RoR 应用程序发送电子邮件,但它没有回答所提出的问题。该问题明确要求使用 sendgrid API 而不是 SMTP。
    • 失望!这不是一个答案,而是从许多其他地方很容易找到的过时方法的剪切和粘贴。
    猜你喜欢
    • 1970-01-01
    • 2016-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-16
    相关资源
    最近更新 更多