首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Sendgrid v3不适合我使用rails my_mailer.rb

Sendgrid v3不适合我使用rails my_mailer.rb
EN

Stack Overflow用户
提问于 2019-07-10 09:37:12
回答 2查看 1.3K关注 0票数 1

当用户注册时,我想通过Sendgrid发送事务性邮件(我使用devise进行身份验证)。在使用SMTP的my_mailer.rb中,我可以这样做,如下所示:

代码语言:javascript
复制
  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帮助文档,而不是真正的理解):

代码语言:javascript
复制
  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>):'

如果我注释掉“包括”行,我会得到:

'TypeError (no implicit conversion of nil into String):' on the line: "sg = SendGrid..."

我使用Gem: sendgrid-ruby (5.3.0)

任何想法都会被感激--我已经尝试了一段时间的反复尝试,试图找到正确的语法,并最终承认我被困住了。

UPDATE#1:

第一个问题是我使用了错误的API_KEY env。变量(从两个不同的帮助文档中复制):"SENDGRID_API_KEY“(代码中)与SENDGRID_APIKEY_GENERAL (设置在Heroku中)。已修复。

更新2:

对于注释掉的"include“行,我现在似乎收到了一个JSON解析错误:

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

因此,我目前的两个问题是:

(1)我希望“令牌”作为确认令牌变量,但它没有被传递。

(2)发送以下简单(1行)“数据”内容不会引发错误,但不会在Sendgrid中选择适当的模板:

代码语言:javascript
复制
data = JSON.parse('{
  "template_id": "1111111-1111-1111-1111-111111111111"    
}')

更新3:

下面是关于我的问题的最新情况,以及我现在所处的位置:

这段代码运行良好(使用我正在尝试升级的Sendgrid v2 ):

代码语言:javascript
复制
  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):中的任何代码)

代码语言:javascript
复制
    #
    # 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

和往常一样,任何洞察力都会受到赞赏。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-12 10:42:06

对于任何试图让SendGrid / v3 /v3/Heroku使用v3的动态事务性电子邮件的人来说,这些技巧可能会对您有所帮助。我花了一周的时间完成这些工作,而这些步骤(&我所犯的错误)在各种文档中并不明显:

  1. 生成SendGrid API密钥(在SendGrid网站上):生成密钥时,API密钥只出现一次,允许您复制它,从那时起它是不可见的。由于后来看不到密钥,所以我在Heroku环境变量中错误地使用了"API密钥ID“,而不是真正的API密钥。
  2. 确保您在Heroku中指定的密钥(对于我:"SENDGRID_APIKEY_GENERAL")匹配用于引用它的代码,即sg = SendGrid::API.new(api_key: ENV‘’SENDGRID_APIKEY_GENERAL‘)
  3. 对于要在模板中替换的变量,请使用"dynamic_template_data“而不是”替换“。这应该在“个性化”部分中(参见下面的代码示例)。
  4. 我发现引用Sendgrid动态模板ID很有用,方法是在Heroku中使用一个环境变量(对于我来说:'SENDGRID_TRANS_EMAIL_CONFIRM_TEMPLATE_ID'),而不是使用Ruby中的硬编码(只允许我尝试使用不同的模板,而不是修改代码)。
  5. 在Ruby中使用JSON字符串中的变量的正确语法是。"CONFIRM_TOKEN":“+token+”(参见下面的代码示例)
  6. 不要在名称中使用其他字符:"CONFIRM_TOKEN“有效,但”确认令牌-“不起作用
  7. 在SendGrid上事务性电子邮件模板的HTML中,使用以下语法替换:{CONFIRM_TOKEN}
  8. 在SendGrid上创建事务模板时,您只能拥有“设计”视图或“代码”视图,而不能两者兼有。创建模板时,必须在开始时进行选择,之后不能切换。
  9. 在设计中,confirmations_instructions操作将用户称为记录(例如电子邮件)为record.email
  10. Gemfile:gem 'rails','5.2.2' ruby '2.6.1‘gem 'devise','4.6.1' gem 'sendgrid-ruby',’6.0‘

下面是我在my_mailer.rb中获得的成功的ruby代码:

代码语言:javascript
复制
  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
票数 0
EN

Stack Overflow用户

发布于 2019-07-10 10:45:29

不能在方法中include模块。您必须将它包含在您的类中,所以在methode之外,就像

代码语言:javascript
复制
class SomethingMailer
  require 'sendgrid-ruby'
  include SendGrid

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

对于第三个更新问题:

您不是要发送JSON,而是要创建JSON,然后将其解析为散列,然后发送该散列,而不是JSON。

代码语言:javascript
复制
JSON.parse #parses a JSON into a Hash

您应该做相反的事情,并将一个哈希转换为JSON

有点像

代码语言:javascript
复制
data = {
  template_id: your_template_id # or pass a string
  personalizations: [
    ...
  ]
}

然后你打电话

代码语言:javascript
复制
data_json = data.to_json
response = sg.client.mail._("send").post(request_body: data_json)

然而,这并不能解释为什么app/views/my_mailer/confirmation_instructions.html.erb中的模板会被发送。因此,我认为您要么同时调用不同的mailer_method,要么根本不调用实际的confirmation_instructions方法。尝试确认您的SendGrid方法实际上是被调用的,并查看它返回的内容。当您发送哈希而不是字符串时,它应该在此之前返回某种错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56967786

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档