Sendgrid v3无法与Rails my_mailer.rb一起使用 [英] Sendgrid v3 not working for me with 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:
-
生成SendGrid API密钥(在SendGrid网站上):生成密钥时,API密钥仅出现一次,允许您复制它,此后就不可见.稍后我看不到密钥,因此我在Heroku环境变量中错误地使用了"API密钥ID",而不是真正的API密钥.
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屋!