Sendgrid v3无法与Rails my_mailer.rb一起使用 [英] Sendgrid v3 not working for me with rails my_mailer.rb

查看:106
本文介绍了Sendgrid v3无法与Rails my_mailer.rb一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在用户注册时通过Sendgrid发送交易邮件(我使用devise进行身份验证).我在my_mailer.rb中使用SMTP的情况如下:

I want to send a transactional mail via Sendgrid when a user registers (I use devise for authentication). I had this working fine in my_mailer.rb using SMTP as follows:

  def confirmation_instructions(record, token, opts={})
    # SMTP header for Sendgrid - v2
    # headers["X-SMTPAPI"]= {
    #  "sub": {
    #    "-CONFIRM_TOKEN-": [
    #      token
    #    ]       
    #   },
    #  "filters": {
    #   "templates": {
    #     "settings": {
    #       "enable": 1,
    #       "template_id": "1111111-1111-1111-1111-111111111111"
    #     }
    #   }
    #  }   
    # }.to_json    

但是,在Sendgrid的提示下,使用v3语法来支持较新的邮件模板,我将代码更改为以下内容(来自sendgrid帮助文档,而不是真正的理解):

However, prompted by Sendgrid to use v3 syntax to support newer mail templates, I changed code to the following (from the sendgrid help docs, as opposed to a real understanding):

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

    require 'sendgrid-ruby'
    include SendGrid

    sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])

    data = JSON.parse('{
      "substitutions": {
        "-CONFIRM_TOKEN-": [
          token
        ],
      "template_id": "1111111-1111-1111-1111-111111111111"
    }')

    response = sg.client.mail._("send").post(request_body: data)
    puts response.status_code
    puts response.body
    puts response.parsed_body
    puts response.headers    

现在我收到错误消息:
'NoMethodError (undefined method `include' for #<MyMailer:0x0000000003cfa398>):'

Now I get the error message:
'NoMethodError (undefined method `include' for #<MyMailer:0x0000000003cfa398>):'

如果我将"include"行注释掉,则会得到:
'TypeError (no implicit conversion of nil into String):' on the line: "sg = SendGrid..."

If I comment out the 'include' line I get:
'TypeError (no implicit conversion of nil into String):' on the line: "sg = SendGrid..."

我使用宝石:sendgrid-ruby(5.3.0)

I use the Gem: sendgrid-ruby (5.3.0)

任何想法都将不胜感激-一段时间以来,我一直试图通过反复试验来尝试正确的语法,最后承认我被卡住了.

Any ideas would be appreciated - I've been trying to hit on the correct syntax by trial-and-error for a while now and finally admit I am stuck.

UPDATE#1:
第一个问题是我使用了错误的API_KEY env.变量(从2个不同的帮助文档中复制):"SENDGRID_API_KEY"(在代码中)与SENDGRID_APIKEY_GENERAL(在Heroku中设置).固定.

UPDATE#1:
The first issue was I was using the wrong API_KEY env. variable (copied from 2 different help docs): "SENDGRID_API_KEY" (in code) vs. SENDGRID_APIKEY_GENERAL (set in Heroku). Fixed.

更新#2:
注释掉"include"行之后,我现在似乎正在收到JSON解析错误:

UPDATE #2:
With the "include" line commented out I now seem to be getting a JSON parse error:

JSON::ParserError (416: unexpected token at 'token

所以我现在有2个问题:
(1)我希望令牌"成为确认令牌变量,但未传递

So my 2 current issues are now:
(1) I would like 'token' to be the confirmation token variable but it is not being passed

(2)发送下面的数据"简单内容(1行)不会引发错误,但是未选择Sendgrid中的适当模板:

(2) Sending the below simple (1 line) content of 'data' does not throw up an error, but the appropriate template within Sendgrid is not selected:

data = JSON.parse('{
  "template_id": "1111111-1111-1111-1111-111111111111"    
}')

更新#3:
这是有关我的问题状态以及我现在所处位置的最新信息:

UPDATE #3:
Here's an update on the status of my issue and exactly where I am now stuck:

此代码可以正常工作(使用我要从中升级的Sendgrid v2):

This code works fine (using Sendgrid v2 which I am trying to upgrade from):

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

    #
    # SMTP header for Sendgrid     - v2
    #     This works fine
    #

    headers["X-SMTPAPI"]= {
     "sub": {
       "-CONFIRM_TOKEN-": [
         token
       ]
      },
     "filters": {
      "templates": {
        "settings": {
          "enable": 1,
          "template_id": "1111111-1111-1111-1111-111111111111"
        }
      }
     }
    }.to_json 

此Sendgrid v3代码不起作用(电子邮件确实通过Sendgrid发送,但未在Sendgrid中选择模板-它仅使用app/views/my_mailer/confirmation_instructions.html.erb中的任何代码):

This Sendgrid v3 code does not work (the email does get sent via Sendgrid but it does not select the template within Sendgrid - it just uses whatever code is in app/views/my_mailer/confirmation_instructions.html.erb):

    #
    # Sendgrid API v3
    #   This sends an email alright but it takes content from app/views/my_mailer/confirmation_instructions.html.erb
    #   It DOES NOT select the template within Sendgrid
    #

    data = JSON.parse('{
      "template_id": "1111111-1111-1111-1111-111111111111",
      "personalizations": [
        {
          "substitutions": {
            "-CONFIRM_TOKEN-": "'+token+'"
          } 
        }
      ]
    }')

    sg = SendGrid::API.new(api_key: ENV['SENDGRID_APIKEY_GENERAL2'])
    response = sg.client.mail._("send").post(request_body: data)
    puts response.status_code
    puts response.body
    puts response.parsed_body
    puts response.headers

一如既往,任何见识都值得赞赏.

As always, any insight appreciated.

推荐答案

对于那些试图使SendGrid v3 API与Ruby/Devise/Heroku一起使用并使用SendGrid的动态交易电子邮件的人,这些提示可能会对您有所帮助.我花了一个星期使它生效,这些步骤(以及我犯的错误)在各种文档中都没有明显体现:

For anyone trying to get SendGrid v3 API working with Ruby/Devise/Heroku and use SendGrid's dynamic transactional emails these tips may help you. I spent a week getting this to work and these steps (& mistakes I made) were not apparent in the various documentation:

  1. 生成SendGrid API密钥(在SendGrid网站上):生成密钥时,API密钥仅出现一次,允许您复制它,此后就不可见.稍后我看不到密钥,因此我在Heroku环境变量中错误地使用了"API密钥ID",而不是真正的API密钥.

  1. Generating the SendGrid API key (on SendGrid website): when generating the key, the API key only appears once allowing you to copy it, from then on it is invisible. As I could not see the key later I mistakenly used the "API Key ID" in my Heroku environment variables, rather than the true API Key.

确保在Heroku中为您提供密钥的名称(对我来说:"SENDGRID_APIKEY_GENERAL")与用于引用它的代码匹配,即sg = SendGrid :: API.new(api_key:ENV ['SENDGRID_APIKEY_GENERAL'])

Ensure the name you give the key in Heroku (for me: "SENDGRID_APIKEY_GENERAL") matches the code you use to reference it i.e. sg = SendGrid::API.new(api_key: ENV['SENDGRID_APIKEY_GENERAL'])

要发送要在模板中替换的变量,请使用"dynamic_template_data"而不是"substitutions".这应该在个性化设置"部分中(请参见下面的代码示例).

For sending variables to be substituted in the template use "dynamic_template_data" and not "substitutions". This should be within the "personalizations" section (see code example below).

我发现通过在Heroku中使用环境变量(对我来说:'SENDGRID_TRANS_EMAIL_CONFIRM_TEMPLATE_ID')来引用Sendgrid动态模板ID很有用,这与在Ruby中进行硬编码(只是允许我尝试使用不同的模板)而不是更改代码).

I found it useful to refer to the Sendgrid dynamic template ID by using an environment variable in Heroku (for me: 'SENDGRID_TRANS_EMAIL_CONFIRM_TEMPLATE_ID') as opposed to hard-coding in Ruby (just allowed me to experiment with different templates rather than changing code).

在Ruby中的JSON字符串中使用变量的正确语法例如"CONFIRM_TOKEN":'+ token +'"(请参见下面的代码示例)

The correct syntax for using a variable in the JSON string in Ruby is e.g. "CONFIRM_TOKEN": "'+token+'" (see code example below)

请勿在名称中使用其他字符:即"CONFIRM_TOKEN"有效,但"-CONFIRM_TOKEN-"无效

Do not use other characters in the name: i.e. "CONFIRM_TOKEN" worked but "-CONFIRM_TOKEN-" did not work

在SendGrid上的事务电子邮件模板的HTML中,使用以下语法进行替换:{{CONFIRM_TOKEN}}

In the HTML of the transactional email template on SendGrid use this syntax for the substitution: {{CONFIRM_TOKEN}}

在SendGrid上创建事务模板时,您只能拥有一个设计"视图或一个代码"视图,而不能同时拥有这两个视图.创建模板时,您必须从头开始选择,之后不能再切换.

When creating a transactional template on SendGrid you can only have a 'design' view or a 'code' view not both. You must select at the start when creating the template and cannot switch after.

在设计确认"操作中,将用户称为记录(例如电子邮件),称为record.email

In the devise confirmations_instructions action refer to the user as a record (e.g. email) as record.email

Gemfile: gem'rails','5.2.2' 红宝石'2.6.1' gem'devise','4.6.1 ' gem'sendgrid-ruby','6.0.0'

Gemfile: gem 'rails', '5.2.2' ruby '2.6.1' gem 'devise', '4.6.1' gem 'sendgrid-ruby', '6.0.0'

这是my_mailer.rb中成功的红宝石代码:

Here is my successful ruby code that I have in my_mailer.rb:

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

    data = JSON.parse('{
      "personalizations": [
        {
          "to": [
            {
              "email": "'+record.email+'"
            }
          ],
          "subject": "Some nice subject line content",
          "dynamic_template_data": {
            "CONFIRM_TOKEN": "'+token+'",
            "TEST_DATA": "hello"
          }
        }
      ],
      "from": {
        "email": "aaaa@aaaa.com"
      },
      "content": [
        {
          "type": "text/plain",
          "value": "and easy to do anywhere, even with Ruby"
        }
      ],
      "template_id": "'+ENV['SENDGRID_TRANS_EMAIL_CONFIRM_TEMPLATE_ID']+'"
    }')

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

这篇关于Sendgrid v3无法与Rails my_mailer.rb一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆