Прикрепить креветки pdf к электронной почте
Я искал целую вечность и до сих пор не могу этого понять,
В настоящее время я использую prawn gem
и хочу иметь возможность присоединить pdf
к email
в моем invoice controllers
create action
. В настоящее время я могу ссылаться на сгенерированный pdf с моей страницы invoices/show
через http://localhost:3000/invoices/297.pdf
, но я не могу понять, как прикрепить этот pdf к электронной почте.
В настоящее время я нигде не храню сгенерированный PDF, и мой почтовый ящик выглядит так
Мейлер
class InvoiceMailer < ActionMailer::Base
default :from => "notifications@example.com"
def invoice_email(user)
@user = user
mail(:to => user.email, :subject => "Invoice Recieved")
end
end
И мой InvoicesController Создать Действие
{...}
respond_to do |format|
if @invoice.save
InvoiceMailer.invoice_email(@invoice.user).deliver
format.html { redirect_to invoice_url(@invoice, back_path:
{...}
Как я могу добавить свой счет-фактуру в качестве приложения к этому почтовому ящику? Нужно ли мне хранить счет-фактуру где-то, прежде чем я смогу его отправить?
2 ответа:
То, как вы это делаете, зависит от того, сколько времени занимает генерация PDF и/или сколько нагрузки она помещает на ваш сервер, и заботитесь ли вы об этом. В моем случае я создавал PDF-файлы из пользовательского контента, и я видел, что некоторые времена создания PDF увеличились в диапазоне 30+ секунд. Решение этой проблемы становится проблемой выполнения задания где-то еще и кэширования (будь то БД или облачное хранилище).
@toddmetheny совершенно прав, предлагая облачное хранилище для всех, кроме самых простых решений. Он получает больше интересно, если вы размещаете что-то вроде Heroku с эфемерным хранилищем, или если вы отделяете создание PDF от отправки электронной почты от запросов пользователей (например, от Heroku again, web dynos vs worker dynos). Вы можете сгенерировать PDF-файл в локальный временный файл, но этот временный файл может отсутствовать к тому времени, когда вам нужно будет прочитать его в почтовом средстве, работающем на "работнике".
Действительно простой вариант
В вашей почтовой программе вы можете сгенерировать PDF в локальный файл, прочитать его обратно в память, затем прикрепите его:
def invoice_email(user) @user = user attachments['filename_for_user.pdf'] = generate_pdf_content mail(:to => user.email, :subject => "Invoice Recieved") end private # I had troubles trying to get Prawn to generate 'in memory' # so just write to, then read, then unlink a tempfile def generate_pdf_content pdf = some_method_that_generates_a_prawn_pdf_object Tempfile.create do |f| pdf.render_file f f.flush File.read(f) end end
Я предлагаю вам начать здесь, чтобы получить вещи работает.
Более сложный вариант
Когда-нибудь вы можете захотеть отделить работу, которая генерирует PDF (что может занять много времени) от заданий, которые отправляют электронную почту, которые обычно намного быстрее. Я делаю это так: создаю задание, которое генерирует PDF в локальный Темпфайл, затем загружает этот файл в хранилище S3 и записывает идентификатор объекта S3 (я делаю это в своей базе данных, вы можете просто сделать это в качестве атрибута работы вы толкаетесь).
По завершении этого задания создается новое задание почтовой службы. Задание mailer (которое может выполняться на другом сервере) загружает PDF-файл из хранилища S3 в локальный файл, а затем добавляет его к электронной почте, как и простой вариант выше.
Вам понадобится url-адрес, с которым вы можете работать. Любое решение облачного хранилища-это вариант, если вы не хотите хранить его в своей базе данных.
Вот некоторые важные сведения о добавлении вложений в почтовые программы из направляющих rails на action mailer :
2.3.1 Добавление Вложений
Action Mailer позволяет очень легко добавлять вложения.
Передайте имя файла, содержимое и действие почтовой программы, и Почтовая жемчужина автоматически угадает тип mime_type, установит кодирование и создание вложения.
attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
Когда метод mail будет запущен, он отправит составное электронное письмо с вложением, должным образом вложенным с верхним уровнем, являющимся составным / смешанным, и первой частью, являющейся составным / альтернативным, содержащим обычный текст и сообщения электронной почты HTML.