Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tracking Code Into a PDF or PostScript File

Is there a way to track when a PDF is opened? Perhaps by embedding some script into the pdf itself?

I saw the question below, and I suppose the answer is "no" for javascript, but I am wondering if this is possible at all.

Google analytics tracking code insert in pdf file

like image 376
speedplane Avatar asked Nov 11 '11 21:11

speedplane


People also ask

Can you put a tracker in a PDF?

Yes, but you need a licensing system to identify the user, and the ability to lock a PDF to a device so you have certainty of who you are tracking.

What is the difference between PostScript and PDF?

PDF is one of the more widely supported successors to PS files for both web and print. However, PDF is a display format that doesn't edit very easily while PostScript is a printer control language that broadens print possibilities because of its ability to communicate design requirements within its code.

How do I make a PostScript PDF?

How to convert a PS to a PDF file? Choose the PS file that you want to convert. Select PDF as the the format you want to convert your PS file to. Click "Convert" to convert your PS file.

Is PostScript better than PDF?

PDF is considered more advanced than PostScript; a PDF file is actually a PostScript file that has been taken a little further. A RIP has interpreted the file and made it into clearly defined objects that you can see on the screen as visual objects, rather than just code.


1 Answers

The PDF standard includes support for JavaScript but as @Wes Hardaker pointed out, not every PDF reader supports it. However, sometimes some is better than none.

Here's Adobe's official Acrobat JavaScript Scripting Guide. What's probably most interesting to you is the doc object which has a method called getURL(). To use it you'd just call:

app.doc.getURL('http://www.google.com/');

Bind that event to the document's open event and you've got a tracker. I'm not too familiar with creating events from within Adobe Acrobat but from code its pretty easy. The code below is a full working VS2010 C# WinForms app that uses the open source library iTextSharp (5.1.1.0). It creates a PDF and adds the JavaScript to the open event.

Some notes: Adobe Acrobat and Reader will both warn the user whenever a document accesses an external resource. Most other PDF readers will probably do the same. This is very annoying so for this reason alone it shouldn't be done. Personally I don't care if someone tracks my document opens, I just don't want to get a prompt every time. Second, just to reiterate, this code works for Adobe Acrobat and Adobe Reader, probably as far back as at least V6, but may or may not work in other PDF readers. Third, there's no safe way to uniquely identify the user. Doing so would require you to create and store some equivalent of a "cookie" which would require you writing to the user's file system which would be considered unsafe. This means that you could only detect the number of opens, not unique opens. Fourth, this might not be legal everywhere. Some jurisdictions require that you notify users if you are tracking them and provide for a way for them to see what information you are collecting.

But with all of the above, I can't not give an answer just because I don't like it.

using System;
using System.Text;
using System.Windows.Forms;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //File that we will create
            string OutputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Events.pdf");

            //Standard PDF creation setup
            using (FileStream fs = new FileStream(OutputFile, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                using (Document doc = new Document(PageSize.LETTER))
                {
                    using (PdfWriter writer = PdfWriter.GetInstance(doc, fs))
                    {
                        //Open our document for writing
                        doc.Open();

                        //Create an action that points to the built-in app.doc object and calls the getURL method on it
                        PdfAction act = PdfAction.JavaScript("app.doc.getURL('http://www.google.com/');", writer);

                        //Set that action as the documents open action
                        writer.SetOpenAction(act);

                        //We need to add some content to this PDF to be valid
                        doc.Add(new Paragraph("Hello"));

                        //Close the document
                        doc.Close();
                    }
                }
            }

            this.Close();
        }
    }
}
like image 81
Chris Haas Avatar answered Oct 30 '22 03:10

Chris Haas