我想在用户注册时通过Sendgrid发送交易邮件(我使用devise进行身份验证)。我在my_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帮助文档,而不是真正的理解):
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>):'
如果我将“ include”行注释掉,则会得到:
'TypeError (no implicit conversion of nil into String):' on the line: "sg = SendGrid..."
我使用宝石:sendgrid-ruby(5.3.0)
任何想法都将不胜感激-一段时间以来,我一直在尝试通过反复试验尝试正确的语法,最后承认我被卡住了。
UPDATE#1:
第一个问题是我使用了错误的API_KEY env。变量(从2个不同的帮助文档中复制):“ SENDGRID_API_KEY”(在代码中)与SENDGRID_APIKEY_GENERAL(在Heroku中设置)。固定。
更新#2:
注释掉“ include”行之后,我现在似乎正在收到JSON解析错误:
JSON::ParserError (416: unexpected token at 'token
所以我现在有2个问题:
(1)我希望“令牌”成为确认令牌变量,但未传递
(2)发送以下简单的“数据”内容(1行)不会引发错误,但是未选择Sendgrid中的适当模板:
data = JSON.parse('{
"template_id": "1111111-1111-1111-1111-111111111111"
}')
更新#3:
这是有关我的问题状态以及我现在所处位置的最新信息:
此代码工作正常(使用我尝试从其升级的Sendgrid v2):
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中的任何代码):>
#
# 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
一如既往,任何见识都值得赞赏。
答案 0 :(得分:0)
您不能include
使用方法中的模块。您必须将其包含在您的类中,因此在方法之外,例如
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_method,要么根本没有调用实际的Confirmation_instructions方法。尝试确认您确实调用了SendGrid方法,并查看其返回的内容。在发送哈希而不是字符串时,它应该已经返回了某种错误。
答案 1 :(得分:0)
对于任何试图使SendGrid v3 API与Ruby / Devise / Heroku一起使用并使用SendGrid的动态交易电子邮件的人,这些技巧可能会对您有所帮助。我花了一个星期使它工作,这些步骤(和我犯的错误)在各种文档中都没有明显体现:
生成SendGrid API密钥(在SendGrid网站上):生成密钥时,API密钥仅出现一次,允许您复制它,此后就不可见。稍后我看不到密钥,因此我在Heroku环境变量中错误地使用了“ API密钥ID”,而不是真正的API密钥。
确保在Heroku中为您提供密钥的名称(对我来说:“ SENDGRID_APIKEY_GENERAL”)与用于引用它的代码匹配,即sg = SendGrid :: API.new(api_key:ENV ['SENDGRID_APIKEY_GENERAL'])
要发送要在模板中替换的变量,请使用“ dynamic_template_data”而不是“ substitutions”。这应该在“个性化设置”部分中(请参见下面的代码示例)。
我发现通过在Heroku中使用环境变量(对我来说:'SENDGRID_TRANS_EMAIL_CONFIRM_TEMPLATE_ID')来引用Sendgrid动态模板ID很有用,这与在Ruby中进行硬编码(只是让我尝试使用不同的模板)而不是更改代码)。
在Ruby中的JSON字符串中使用变量的正确语法例如“ CONFIRM_TOKEN”:“'+ token +'”(请参见下面的代码示例)
请勿在名称中使用其他字符:即“ CONFIRM_TOKEN”有效,但“ -CONFIRM_TOKEN-”无效
在SendGrid上的事务电子邮件模板的HTML中,使用以下语法进行替换:{{CONFIRM_TOKEN}}
在SendGrid上创建事务模板时,您只能具有“设计”视图或“代码”视图,而不能同时具有这两个视图。创建模板时,您必须在开始时选择,之后不能再切换。
在“设计确认”操作中,将用户称为记录(例如电子邮件),称为record.email
Gemfile: gem'rails','5.2.2' 红宝石'2.6.1' gem'devise','4.6.1 ' gem'sendgrid-ruby','6.0.0'
这是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