Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Sendgrid v3不适用于rails my_mailer.rb_Ruby On Rails_Ruby_Devise_Sendgrid_Sendgrid Api V3 - Fatal编程技术网

Ruby on rails Sendgrid v3不适用于rails my_mailer.rb

Ruby on rails Sendgrid v3不适用于rails my_mailer.rb,ruby-on-rails,ruby,devise,sendgrid,sendgrid-api-v3,Ruby On Rails,Ruby,Devise,Sendgrid,Sendgrid Api V3,我想在用户注册时通过Sendgrid发送事务性邮件(我使用Desive进行身份验证)。我在我的_mailer.rb中使用SMTP可以很好地工作,如下所示: def confirmation_instructions(record, token, opts={}) # SMTP header for Sendgrid - v2 # headers["X-SMTPAPI"]= { # "sub": { # "-CONFIRM_TOKEN-": [

我想在用户注册时通过Sendgrid发送事务性邮件(我使用Desive进行身份验证)。我在我的_mailer.rb中使用SMTP可以很好地工作,如下所示:

  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帮助文档,与真正的理解相反):

现在我收到了错误消息:
'NoMethodError(对于#的未定义方法'include'):'

如果我注释掉“包含”行,我会得到:
“TypeError(没有将nil隐式转换为字符串):”行上:“sg=SendGrid…”

我使用Gem:sendgrid ruby(5.3.0)

如果有任何想法,我都会很感激的——我已经试着通过反复试验找到正确的语法有一段时间了,最后我承认我被卡住了

更新#1:
第一个问题是我使用了错误的API_密钥环境。变量(从两个不同的帮助文档复制):“SENDGRID\u API\u密钥”(代码中)与SENDGRID\u APIKEY\u常规(在Heroku中设置)。固定的

更新#2:
注释掉“include”行后,我现在似乎得到了一个JSON解析错误:

JSON::ParserError(416:token处的意外令牌

因此,我目前的两个问题是:
(1) 我希望“token”是确认令牌变量,但它没有被传递

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

data = JSON.parse('{
  "template_id": "1111111-1111-1111-1111-111111111111"    
}')
更新#3:
以下是我问题的最新状态以及我现在的困境:

这段代码运行良好(使用Sendgrid v2,我正试图从中升级):

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


像往常一样,任何洞察都是值得的。

你不能在方法中包含模块。你必须在你的类中包含它,所以在方法之外,比如

class SomethingMailer
  require 'sendgrid-ruby'
  include SendGrid

  def confirmation_instructions(record, token, opts={})
    ...
  end
end
对于第三个更新问题:

您不是在发送JSON,而是在创建JSON,然后将其解析为哈希,然后发送该哈希,而不是JSON

JSON.parse #parses a JSON into a Hash
您应该做相反的事情,并将哈希转换为JSON

差不多

data = {
  template_id: your_template_id # or pass a string
  personalizations: [
    ...
  ]
}
然后你打电话

data_json = data.to_json
response = sg.client.mail._("send").post(request_body: data_json)

但是,这并不能解释为什么会发送
app/views/my_mailer/confirmation_instructions.html.erb
中的模板。因此,我认为您可能在同一时间调用了不同的mailer_方法,或者根本没有调用实际的confirmation_instructions方法。请尝试确认您发送的grid方法实际上被称为nd查看它返回的内容。当您发送哈希而不是字符串时,它应该返回某种错误。

您不能在方法中包含模块。您必须在类中包含模块,因此在方法之外,例如

class SomethingMailer
  require 'sendgrid-ruby'
  include SendGrid

  def confirmation_instructions(record, token, opts={})
    ...
  end
end
对于第三个更新问题:

您不是在发送JSON,而是在创建JSON,然后将其解析为哈希,然后发送该哈希,而不是JSON

JSON.parse #parses a JSON into a Hash
您应该做相反的事情,并将哈希转换为JSON

差不多

data = {
  template_id: your_template_id # or pass a string
  personalizations: [
    ...
  ]
}
然后你打电话

data_json = data.to_json
response = sg.client.mail._("send").post(request_body: data_json)

但是,这并不能解释为什么会发送
app/views/my_mailer/confirmation_instructions.html.erb
中的模板。因此,我认为您可能在同一时间调用了不同的mailer_方法,或者根本没有调用实际的confirmation_instructions方法。请尝试确认您发送的grid方法实际上被称为nd查看它返回的内容。当您发送散列而不是字符串时,它应该返回某种错误。

对于试图让SendGrid v3 API与Ruby/Desive/Heroku一起工作并使用SendGrid的动态事务性电子邮件的人,这些提示可能会帮助您。我花了一周的时间来让它工作,以及这些步骤(&我犯的错误)在各种文件中不明显:

  • 生成SendGrid API密钥(在SendGrid网站上):生成密钥时,API密钥只出现一次,允许您复制它,从那时起它就不可见。由于我以后看不到密钥,我在Heroku环境变量中错误地使用了“API密钥ID”,而不是真正的API密钥

  • 确保您在Heroku中为密钥指定的名称(对我来说:“SENDGRID\u APIKEY\u GENERAL”)与用于引用它的代码匹配,即sg=SENDGRID::API.new(API\u key:ENV['SENDGRID\u APIKEY\u GENERAL'])

  • 要发送要在模板中替换的变量,请使用“dynamic_template_data”而不是“substitutions”。这应该在“personalizations”部分中(参见下面的代码示例)

  • 我发现在Heroku中使用环境变量引用Sendgrid动态模板ID(对我来说:“Sendgrid\u TRANS\u EMAIL\u CONFIRM\u template\u ID”)非常有用,而不是在Ruby中进行硬编码(只允许我试验不同的模板,而不是更改代码)

  • 在Ruby中,在JSON字符串中使用变量的正确语法为“CONFIRM_TOKEN”:“+TOKEN+”(参见下面的代码示例)

  • 请勿在名称中使用其他字符:即“确认令牌”有效,但“-确认令牌”无效

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

  • 在SendGrid上创建事务性模板时,只能具有“设计”视图或“代码”视图,而不能同时具有这两个视图。创建模板时必须在开始时选择,并且不能在之后切换

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

  • Gemfile:gem'rails','5.2.2'ruby'2.6.1'