We think a lot of article sharing on FT.com is ‘dark’, i.e. untracked, perhaps just the text of the article, or the URL, not using our sharing features. This is nicely discussed in a post in theatlantic by Alexis Madrigal, “Dark Social: We Have the Whole History of the Web Wrong”. We guessed that we could both encourage sharing and get better data on what was being shared by allowing users to share just by copy and pasting the URL of the page, while still allowing the recipient free access through our paywall.
We know that when a non-subscriber clicks on a link to an FT article and is unexpectedly greeted with the paywall barrier, it can be a major turn-off. So if it’s true that people commonly share just by copying URLs, we have subscribers who can see content sharing the address of that content with people who are then unable to see it.
We do provide a tool we call ‘gift article’ that allows paying subscribers to share full content with non-subscribers a limited number of times per month. But it makes sense that users much prefer that which is familiar and simple, ideally frictionless, and it is hard to beat copy+pasting the article url from the browser’s address bar into an email. Can we make that work and retain the ‘gifting’ behaviour?
We worked with two stakeholders: Deniz Genc (of B2B, our corporate content sales team), and Matt Chadburn (of Next FT, the rapidly maturing replacement for the existing ft.com). As usual, two sprint reviews per week and an objective to ship something pronto.
We also wanted to demonstrate that we could:
- not fatally break our paywall business model
- handle all the current ‘official’ sharing and gifting functionality, dark sharing, etc
- handle all the use cases that our B2B colleagues had identified but were not currently catered for, and
- open up new opportunities for our B2B colleagues to identify interesting usage patterns and opportunities for new products/subscription models, etc.
We decided to build a fully-working proof of concept to enable a subscriber (who we’ll call a sharer) to ‘spend’ their gift article credits (10 per month, by default) by copying the URL of the article they are viewing into an email (or IM, Tweet, blog post, presentation slide, PDF etc). Any recipients (up to a limit), whether subscribed, signed in, or anonymous, would be able to click on that link and immediately get to see the article in full with no further nagging or obstruction from the site. Perhaps there might be a nice little message saying “with compliments from Person X or Company Y”. The sharer’s article credits would be checked for and decremented only when a recipient attempted to view the article.
If a second person (or more than the number allowed by that share action) was to click on the shared link, they would be greeted with a polite message informing them that the share credit for that article has already been used up, or possibly just the regular paywall barrier message.
Taking it further, we would give the sharer flexibility to control how many recipients they wanted to allow on a share-by-share basis, allowing a specified or unlimited number of recipients. ‘Unlimited’ in this case, would be constrained by the number of gift credits held by the sharer which they could top up, for a fee, or wait for the next month’s free allocation.
Creating a share code
In order for an article URL to be tied back to the sharer, we needed to personalise it. For simplicity, we settled on simple parameter appended to the standard article URL.
sharecode needed the following characteristics
- Stateless. We need to generate a sharecode for every article view but most views of articles will not result in sharing, so the sharecode should be cheap to generate and should not need to be stored
- Not stupidly long/scary (a common user behaviour is to strip perceived ‘cruft’ from urls when sharing).
- Include the following data:
- the sharer, so we can debit the appropriate user’s gift credit balance
- the article, so that the
sharecodecannot not be simply transferred to a different article and remain valid
- a unique identifier for the action, so that a sharer could, potentially, send out shareable URLs for the same article to different users with different share conditions attached.
- the context of sharing (where the URL was obtained: from the address bar, from a dedicated share dialog, etc)
- Hard to exploit, so that we don’t open up the site to free/untracked access
Since there is no database of all the sharecodes which have been constructed, this means we can’t simply use a nice short identifier that we can look up later, and we do have to encode the full sharing context into the share code. We built a share code generator service. This is open source, so rather than relying on security through obscurity we are happy to have anyone let us know if there are weaknesses.
sharecode is built from:
- details of the share event
- sharer UUID (obtained from the user session),
- timestamp (when the sharecode is first generated)
- the permitted maximum number of shares of this article (default is 1)
- the context (copied from the address bar, or via the ‘share’ dialog in the page)
- article UUID
- a secret key
We strip the hyphens from the sharer UUID, and append the timestamp, the max shares, and the context, to form a fixed-length string of share details.
We generate a cryptographic signature of the share details string with the article UUID briefly appended. To form the
sharecode, the first 8 characters of the signature are appended to the share details string. There is no need to include the article UUID in the actual
sharecode because we have that in the URL itself.
At this stage, we have a share code which is hard to modify without corrupting it. However, the contents of the sharecode are clearly readable, exposing the sharer’s UUID and sundry details. So one further step is taken to render the sharecode hard(er) to read: a seeded shuffle, using the secret key and article UUID as the seed.
And now, at last, we have the sharecode. This is appended to the article URL to produce a URL which can be shared with anyone, enabling them to view the article, whether subscribed or not.
(minus hyphens) User UUID = ABCDEFG123 Share Timestamp = 1446809468 Max Article Shares = 0001 Context = 1 Share details = ABCD123EFG144680946800011 Article UUID = 5562d69c-83b5-11e5-8095-ed1a37d1e096 (full) Signature = a4f5d3e2. . . . . . . (8 chars of) Signature = a4f5d3e2 <-- Nearly there (unshuffled) Sharecode = ABCD123EFG144680946800011a4f5d3e2 <-- This is it!
Decrypting a share code
We simply reverse the process described above.
- obtain the sharecode and article UUID from the URL
- unshuffle the sharecode
- extract the signature string to get the share details string
- regenerate a signature using the share details string and the article UUID
- compare the two signatures and complain if they differ
Assuming the signatures agree, we should have a fair degree of confidence that
- the sharecode has not been tampered with, and so specifies the correct share details
- it is attached to the correct article
We extended an existing Origami component, o-share, which already knows about the various social sharing sites, to append the sharecode to the article URL, and allow the power-sharer to refine the maximum number of ‘gifted’ shares of the URL. This will be hidden behind a flag; only FT staff and selected external clients will be able to generate share codes during the experiment.
The share code generator service was hosted on Heroku (receiving requests from the o-share component), generating both the default share URL which appears in the browser bar and the user-configured variants when they click on the “Share” link.
We also needed a ‘share store’, a database of gift credit balances, and a record of redemptions, so that we can make judgements about whether a shared URL is still valid for access. This is another simple Heroku-hosted postgres DB with API which records each redemption of a shared url, keeping track of the gift credits of each user, and the remaining credits for each URL they shared (and has been received), decrementing them as appropriate.
Finally, we needed a hook in our main access/authorisation logic (internally known as ‘pre-flight’), which calls the share store to determine whether an attempt to redeem a sharecode-adorned link should succeed.
The full authorisation sequence is:
The ability to create shareable URLs is masked by a flag, so we can do a controlled release of the experiment. Initially, we opened it up to FT B2B sales staff, who have expressed in very forceful terms their need to be able to give their prospective clients easy access the wonders of FT in order to convince them to buy a subscription. But the flag system allows the experiment to be extended easily to larger numbers of users or even our entire audience.
Regardless of who has created a shareable url, once it is created it can be consumed by anyone. It will be interesting to see how far this goes. We developed some reporting of sharing activity as we work out the kind of questions the business and sharers want answers to regarding the creation and consumption of their shared articles.
What do you see with URL Sharing?
When a signed-in subscriber views an article, the URL in the address bar gains a sharecode after 5 seconds. This pause has two intentions
- if you spend less than 5 seconds on an article you’re unlikely to want to share it, so we may as well reduce load on the generator service
- the appearance of the sharecode should hopefully draw the subscriber’s attention to the new feature
The sharer can either copy the default shareable URL direct from the address bar, or interact with the new ‘Share’ dialog to construct a tailor-made shareable URL. The share dialog has a link to a help page.
The recipient, ideally a non-subscriber (and represented here by viewing the shared URL in Chrome’s Incognito mode), receives an email containing the shareable URL, and clicks on the URL. Assuming there are sufficient gift credits with the sharer and the article, the recipient goes straight to the article and can read it in its entirety, with a subtle extra message indicating this was as the result of the sharer being generous.
If a second recipient attempts to view the same shareable URL, they do not get to see the article, and are presented with the paywall instead: