Making a Simple Tweet to Download System

Demo Download

Twitter is undoubtedly a hugely popular social network. One of the keys to its success is its simple and powerful API, which opens the doors to countless novel ways for you to use the service.

One of these uses is allowing your visitors to "pay with a tweet". Namely you take something that you would otherwise offer for free (like an ebook, mp3 or other kind of digital media), and make it available to users only after they tweet about your website. It is a great way to promote your products and get noticed, and it doesn't cost anything to your visitors.

Building such functionality is not as hard as you might think. Twitter made it even easier with their Web Intents - a dead simple way to integrate the platform in your website. In this tutorial we will build a jQuery plugin around that API, and activate a download button once the user tweets. So lets get started!

The HTML

First we will need a simple web page to hold the example together.

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />

        <title>Tweet to Download | Tutorialzine Demo</title>

        <!-- Our CSS stylesheet file -->
        <link rel="stylesheet" href="assets/css/styles.css" />

        <!--[if lt IE 9]>
          <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
        <![endif]-->
    </head>

    <body>

        <header>
            <h1>Tweet to Download</h1>
            <h2><a href="https://tutorialzine.com/2011/05/tweet-to-download-jquery/">&laquo; Back to Tutorialzine</a></h2>
        </header>

        <section id="container">
            <p>The button below is activated<br />only* after you tweet. <a href="#" id="tweetLink">Try it.</a></p>
            <a href="#" class="downloadButton">Download</a>
        </section>

        <footer>*Not exactly. Read more in the tutorial..</footer>

        <img src="assets/img/twitter_bird.png" alt="Twitter Bird" />

        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
        <script src="assets/js/jquery.tweetAction.js"></script>
        <script src="assets/js/script.js"></script>

    </body>
</html>

We are using some of the HTML5 tags - header, section and footer, to logically separate the page in three parts. Our #container section holds two anchor elements.

The first link - #tweetLink, is going to trigger the plugin and display a popup holding a Twitter submission form. The second - #downloadButton, is styled as a button and its href attribute is set to that of the file we are offering for download, once the user tweets.

At the bottom of the file, before the closing body tag, we have the usual set of JavaScript includes - version 1.6 of the jQuery library, the tweetAction.js plugin we will be writing in a moment, and script.js, which listens for clicks on the links and triggers the plugin.

Lets move to the jQuery section of this tutorial.

tweet-to-download-jquery-plugin.jpg

The jQuery

As you can see from the Web Intents documentation, it can be described as a popup based interface for interacting with Twitter. You just need to load a specific intent URL in a popup window and pass GET parameters with the text of the tweet, Twitter username and more, depending on the intent. This will produce a form which with which the user can publish a new tweet, reply or follow you.

Lets put this together in a jQuery plugin that handles it for us:

jquery.tweetAction.js

(function($){

    var win = null;

    $.fn.tweetAction = function(options,callback){

        // Default parameters of the tweet popup:

        options = $.extend({
            url:window.location.href
        }, options);

        return this.click(function(e){

            if(win){
                // If a popup window is already shown,
                // do nothing;
                e.preventDefault();
                return;
            }

            var width   = 550,
                height  = 350,
                top     = (window.screen.height - height)/2,
                left    = (window.screen.width - width)/2; 

            var config = [
                'scrollbars=yes','resizable=yes','toolbar=no','location=yes',
                'width='+width,'height='+height,'left='+left, 'top='+top
            ].join(',');

            // Opening a popup window pointing to the twitter intent API:
            win = window.open('http://twitter.com/intent/tweet?'+$.param(options),
                        'TweetWindow',config);

            // Checking whether the window is closed every 100 milliseconds.
            (function checkWindow(){

                try{
                    // Opera raises a security exception, so we
                    // need to put this code in a try/catch:

                    if(!win || win.closed){
                        throw "Closed!";
                    }
                    else {
                        setTimeout(checkWindow,100);
                    }
                }
                catch(e){
                    // Executing the callback, passed
                    // as an argument to the plugin.

                    win = null;
                    callback();
                }

            })();

            e.preventDefault();
        });

    };
})(jQuery);

To open a popup window with window.open(), we need to pass a list of comma-delimited parameters. These include which address bars are to be shown, and the dimensions and position of the window.

After we open http://twitter.com/intent/tweet we check the closed attribute of the window every 100 ms by running the checkWindow() function with a setTimeout(). This is the only way we can know that the popup has been closed, as browsers prevent any kind of cross-domain interactions. When the popup is closed, a callback function, passsed as the second argument of the function, is executed.

twitter-intent-share.jpg

You can see how we use this plugin below:

script.js

$(document).ready(function(){

    // Using our tweetAction plugin. For a complete list with supported
    // parameters, refer to http://dev.twitter.com/pages/intents#tweet-intent

    $('#tweetLink').tweetAction({
        text:       'How to make a simple Tweet to Download system',
        url:        'https://tutorialzine.com/2011/05/tweet-to-download-jquery/',
        via:        'tutorialzine',
        related:    'tutorialzine'
    },function(){

        // Callback function. Triggered when the user closes the pop-up window:

        $('a.downloadButton')
                .addClass('active')
                .attr('href','tweet_to_download.zip');

    });

});

In the fragment above we trigger the tweetAction plugin on the #tweetLink anchor. When it clicked, we will display a popup window, which, when closed, will trigger the callback. This is where we enable the button and set its href attribute to that of the file.

The CSS

The only thing we are left to do, is throw in some fancy CSS styles. I am going to present only some of the more interesting declarations here. You can see the rest in assets/css/styles.css.

We are using multiple backgrounds for the html element. The background images are displayed one beneath the other, starting with the topmost image - bg_gradient.jpg.

html{
    /* CSS3 Multiple backgrounds with a fallback */

    background-color:#e4e4e4;
    background:url('../img/bg_gradient.jpg') no-repeat center center,url('../img/bg_tile.jpg');
}

body{
    color:#888;
    padding:10px;
    min-height:600px;
    font:14px/1.3 'Segoe UI',Arial, sans-serif;
    text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.7);
}

Further down we have the styling of the twitter bird icon. I am using the > character to denote that this will affect only images that are direct children of body.

body > img{
    /* The twitter illustration */

    margin:50px auto 0;
    display:block;
}

Finally we have the #container section. With the help of the :before/:after pseudo elements, we display subtle shadows above and below the container.

#container{
    width:450px;
    height:300px;
    padding:10px;
    text-align:center;
    margin:0 auto;
    position:relative;
    background-color:#fff;
    display:block;

    -moz-border-radius:10px;
    -webkit-border-radius:10px;
    border-radius:10px;
}

#container:before,
#container:after{

    /* Adding subtle shadows with before/after elements */

    content:'.';
    text-indent:-99999px;
    overflow:hidden;
    display:block;
    height:12px;
    width:470px;
    background:url('../img/shadows.png') no-repeat center top;
    position:absolute;
    left:0;
    top:-12px;
}

#container:after{
    top:auto;
    bottom:-12px;
    background-position:center bottom;
}

These two pseudo elements share almost all of their code, so I've defined them as a group. The :after element is also styled separately, but only the styles that differ are redefined.

With this our Pay with a Tweet experiment is complete!

But wait! This doesn't work!

And you are entirely correct. As you can see from the code (and confirm from the demo), we assume that closing the popup window equals a published tweet. It does not.

As this is a cross domain interaction, there is no way to subscribe for when a tweet is actually published. The only way to do this would be to use Twitter's more complex @Anywhere API, but even then people could just hotlink to your file.

Does it even matter? The real purpose of this technique is to give people an incentive to tweet about your product/service, something that a lot of folks would love to do just for the feeling of receiving your "members-only" download.

Bootstrap Studio

The revolutionary web design tool for creating responsive websites and apps.

Learn more

Related Articles

Raul Riera

This is what Angry Birds Seasons does anyway. They ask you to tweet to unlock some levels, but you don't need to actually tweet, just press that link... I find it useful enough

Michael Trachsel

Like always unbelievably great! Thanks for this.

I like it!
Really nice way of spreading your work - even though people can get around it :)

Nice tut! I was looking for this!

This is a really cool tutorial! I don't actually see myself using this as that I would lose people from downloading my products. But, still very cool, helps to expand Twitter API notices.

e11world

This is pretty sweet and useful! I only wonder how one should use this because there are still many people who don't have twitter so this may not work in all cases. Still, great job!!

Jared Erickson

really cool idea! although you can still download it if you click the tweet button and close the dialog that pop ups... so you actually dont "have" to tweet to receive the file

Excellent job, as always!

May I suggest, however, that a better way of doing this would be through a service like tweetmeme whereby you can activate the button only if the person actually tweets the message, rather than just click on the tweet button. I don't know how to do it myself, but I've seen such applications and I think they might be getting more exposure because of that extra check.

Поздрави!

Martin Angelov

There are actually specialized "Pay with a tweet" services that address this issue and make it difficult to download the file without tweeting. So if you absolutely need to prevent downloads without tweets, you can sign up with one of them. Of course nothing beets making it yourself :)

Just like what Mladen said, the button will be activate when you click on the Tweet link whether you tweeted the link or not. I know that the tweet part is just a favor or a payback in most cases, but is there any way to make it a must?
Cheers

Martin Angelov

Like I said in my reply to Mladen, there are websites that offer this service for a nominal fee. However, this would involve people having to authorize these apps and it would complicate the process (especially for beginners). This is also the case if you decide to use the @Anywhere API as I said in the article.

Judging from my twitter feed, I don't think that it would be worth the extra mile - after all you don't want to force people into anything, and you were going to offer the file for free anyway.

Atroxide

I agree to a certain extent but I could see it actually being cool to have an option to "Buy for 99 cents" or "Tweet it for free", where you actually have a product that costs money but allow them to advertise your product and get it for free, would be interesting to see some statistics if someone would try this if anyone would actually still buy the app.

A better way would be to send a direct message to people, that tweet to your website with a password. Or use an twitter auth to send the message and create a special link for this member.

Thanks for the article i find it really useful i may use it in any of my future projects..:D

Would be great if you can show us the same thing for Facebook share or Like-button??

Im with this guy! I totaly think you should show us how to make that with facebook like button due to the fact that there's much more people with facebook profiles rather than tweeter..

Oh snap... this is brilliant!

I was reading a post about using competitions to increase your tweets and followers the other day. This would be ideal for making your users tweet before they click to enter, or something along these lines.

Amazing again...

Marcello Romanelli

This is really a great tutorial! Thanks guys!

Its very good and useful but one problem though .. when you click try it twitter login window will open .. no need to sign up or anything just close window and download button will be active

Wow very nice! Is it can tweak to use with facebook? I mean Share to download?

its not working

I have this on my site and some people on Macs have told me it doesn't work.

Just confirmed that all Mac users can't download.

This doesn't work for users on Macs. Any way to fix this?

VenomVendor

Can This be done for Facebook or any other Social Websites..???

VenomVendor

I have Edited the same code lil bit which can be used for Facebook, It's like Share to View This can be downloaded from Github

Hi,

I was thinking when I saw this, that's great! Exactly what I need. But then, when clicking the try link and then closing the window without posting to twitter, the download link still became available. That makes this quite useless if you ask me.

How can this be fixed?

ganghack

How To Make it for Facebook ?

This is a bug, or are made specifically for the demo?

If you click on Try it, pops up a login window Twitter.
But if you do not log on, simply close the window - the following links to download to become available. Why not?

And how to implement this method, the user's choice: Facebook, Google + Twitter, Vkontakte?

Azhari Subroto

Really good work.

Actually, the download button will be downloadable after you close the pop out window although you don't twit it yet...
Can you guys improve this script.

Deltina Hay

This is a great tutorial, Martin! I have not implemented it yet, but I agree with you that folks should be given an option to tweet or not, given the open nature of the social web. If folks want an opt-in only solution, they should use a form.

I am researching this topic for my next book on the "new rules of" search optimization and the importance of social signals. Which brings me to my next point: Where the heck are your share buttons?! This is great content that folks want to share. I would love to see a share on Twitter, Facebook, Google Plus, Pinterest option...

Deltina

thibault

Great post! Someone have an example or script with the anywhere API?

Great script Martin, just what I've been looking for :)

Hariharakumar

In the demo the download button got activated even before the tweet got posted. Actually to say I did not tweet, but simply clicked on the link and closed the tweet window that appeared and the download button got activated.

You must check the code once again for this to work correctly.