Send rendered page as email

I feel like this is actually easy, but I haven't been able to attack it
from the right angle. A client wants "send to a friend" functionality that
will allow a user to enter an email address to send the page to, and the
app will send that rendered page in an email. The big issue I'm seeing is
making sure all the relative URLs (assets and links) get rendered as
absolute URLs.

Unsurprisingly, the pages should be rendered as if there were no session
and they are only GETs. I could use an external tool like wget or something
to hit the server and save a "portable" version, but that seems fragile.

Has anyone done this? Can anyone point me to a plugin or something?

Thanks,
--Greg

I did something similar once. I have a page that displays either an invoice or a receipt which has an option to email it to the recipient. I wanted the email to look just like the rendered page, so I used render_to_string to generate the output and then sent that in an html email. My code looks like this

@invoice = Invoice.find(blah blah blah)
output = render_to_string :template => 'invoice/display'
      
begin
  email = UserMailer.create_email_invoice(@invoice, output, :invoice)
  email.set_content_type('text/html')
  UserMailer.deliver(email)
  flash[:notice] = "Invoice #{@invoice.invoice_number} has been emailed to #{@invoice.customer.name} (#{@invoice.customer.email})."
rescue Exception => e
  flash[:color] = 'red'
  flash[:notice] = e.message
end

the "output" variable is passed to the UserMailer and get used as the body of the message. It's the same output that would get sent to the browser, but with one caveat. In the browser, you have the benefit of external CSS and Javascript files. In the HTML email, you have to include all of that (as far as I know anyway...maybe there is a way to do it).

Hope that helps a least a little.

Peace,
Phillip

> I feel like this is actually easy, but I haven't been able to attack
> it from the right angle. A client wants "send to a friend"
> functionality that will allow a user to enter an email address to send
> the page to, and the app will send that rendered page in an email. The
> big issue I'm seeing is making sure all the relative URLs (assets and
> links) get rendered as absolute URLs.
>
> Unsurprisingly, the pages should be rendered as if there were no
> session and they are only GETs. I could use an external tool like wget
> or something to hit the server and save a "portable" version, but that
> seems fragile.
>
> Has anyone done this? Can anyone point me to a plugin or something?

I did something similar once. I have a page that displays either an
invoice or a receipt which has an option to email it to the
recipient. I wanted the email to look just like the rendered page,
so I used render_to_string to generate the output and then sent that
in an html email. My code looks like this

@invoice = Invoice.find(blah blah blah)
output = render_to_string :template => 'invoice/display'
      
begin
  email = UserMailer.create_email_invoice(@invoice, output, :invoice)
  email.set_content_type('text/html')
  UserMailer.deliver(email)
  flash[:notice] = "Invoice #{@invoice.invoice_number} has been
emailed to #{@invoice.customer.name} (#{@invoice.customer.email})."
rescue Exception => e
  flash[:color] = 'red'
  flash[:notice] = e.message
end

the "output" variable is passed to the UserMailer and get used as the
body of the message. It's the same output that would get sent to the
browser, but with one caveat. In the browser, you have the benefit
of external CSS and Javascript files. In the HTML email, you have to
include all of that (as far as I know anyway...maybe there is a way
to do it).

Hope that helps a least a little.

Well, render_to_string is the obvious first step, but the problem is those
assets (and links). I don't think I mind the email loading the assets from
the server (most email programs will require the user to accept loading
images/assets from an external site, but that's fine), but I need a way for
those URLs to be fully-qualified. The HTML BASE tag might do it, but I'm
not sure. Time to test some email programs (including, ugh, Outlook).

Peace,
Phillip

--Greg

Ah, I see your dilemma. One possibility, though I think it would be a last resort, would be to write a helper to create an absolute URL for all of the resource related helpers (link_to, image_tag, etc). I'd like to think there is a simpler solution, though.

Peace,
Phillip

> Well, render_to_string is the obvious first step, but the problem is
> those assets (and links). I don't think I mind the email loading the
> assets from the server (most email programs will require the user to
> accept loading images/assets from an external site, but that's fine),
> but I need a way for those URLs to be fully-qualified. The HTML BASE
> tag might do it, but I'm not sure. Time to test some email programs
> (including, ugh, Outlook).
>
>> Peace,
>> Phillip
> --Greg
>

Ah, I see your dilemma. One possibility, though I think it would be
a last resort, would be to write a helper to create an absolute URL
for all of the resource related helpers (link_to, image_tag, etc).
I'd like to think there is a simpler solution, though.

I guess another possibility is using Hpricot to run through and make all
the URLs absolute. Not marvelously efficient, but I don't expect this to be
a high-volume site. I just have to hit every element and make every src and
href attribute absolute.

Peace,
Phillip

--Greg