Sendgrid v3 не работает для меня с рельсами my_mailer.rb - PullRequest
0 голосов
/ 10 июля 2019

Я хочу отправить транзакционную почту через 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..."

Я использую Gem: sendgrid-ruby (5.3.0)

Любые идеи приветствуются - я пытаюсь найти правильный синтаксис пробными на какое-то время ошибка и, наконец, я признаю, что застрял.

ОБНОВЛЕНИЕ № 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 строка) содержимое 'data' не выдает ошибку, но соответствующий шаблон в Sendgrid не выбран:

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

UPDATE # 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 / translation_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

Как всегда, любое понимание приветствуется.

Ответы [ 2 ]

0 голосов
/ 12 июля 2019

Для тех, кто пытается настроить API SendGrid v3 для работы с Ruby / Devise / Heroku и использовать динамические транзакционные электронные письма SendGrid, эти советы могут вам помочь.Я потратил неделю, чтобы заставить это работать, и эти шаги (и ошибки, которые я сделал) не были очевидны в различной документации:

  1. Создание ключа API SendGrid (на веб-сайте SendGrid): при созданииключ, ключ API появляется только один раз, позволяя вам скопировать его, с тех пор он становится невидимым.Поскольку позже я не смог увидеть ключ, я по ошибке использовал «идентификатор ключа API» в моих переменных среды Heroku, а не истинный ключ API.

  2. Убедитесь, что имя, которое вы даете ключуHeroku (для меня: «SENDGRID_APIKEY_GENERAL») соответствует коду, который вы используете для ссылки на него, т.е. sg = SendGrid :: API.new (api_key: ENV ['SENDGRID_APIKEY_GENERAL'])

  3. для отправкипеременные, которые должны быть заменены в шаблоне, используют «dynamic_template_data», а не «замены».Это должно быть в разделе «персонализации» (см. Пример кода ниже).

  4. Я нашел полезным сослаться на идентификатор динамического шаблона Sendgrid с помощью переменной среды в Heroku (для меня: 'SENDGRID_TRANS_EMAIL_CONFIRM_TEMPLATE_ID') в отличие от жесткого программирования в Ruby (просто позволил мне экспериментировать с различными шаблонами, а не с изменением кода).

  5. Правильный синтаксис для использования переменной в строке JSON в Ruby, например, "CONFIRM_TOKEN": "'+ token +'" (см. Пример кода ниже)

  6. Не используйте другие символы в имени: т.е. «CONFIRM_TOKEN» работал, но «-CONFIRM_TOKEN-» не работал

  7. В HTML-шаблоне транзакционной электронной почты на SendGridиспользуйте этот синтаксис для подстановки: {{CONFIRM_TOKEN}}

  8. При создании транзакционного шаблона в SendGrid вы можете иметь только представление «дизайн» или представление «код», но не оба.Вы должны выбрать в начале при создании шаблона и не можете переключаться после.

  9. В действии devise Подтверждение_инструкции обращайтесь к пользователю как к записи (например, к электронной почте), как record.email

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

Вот мой успешный код ruby, который у меня есть в 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
0 голосов
/ 10 июля 2019

Вы не можете 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 одновременно, либо вообще не вызываете свой фактический метод translation_instructions. Попытайтесь подтвердить, что вы действительно вызвали методы SendGrid, и посмотрите, что он возвращает. Он должен был вернуть какую-то ошибку раньше, когда вы посылали хеш вместо строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...