Twitter Opens up OAuth, Where's Perl?

March 23, 2009 14:03:00
by Pankaj Jain

Twitter opened up their OAuth implementation last week. It's a much welcome aspect of working with Twitter's API since we're planning on implementing some functionality into Semblr that uses Twitter. Hence, understanding OAuth and prototyping it's use was important for us.My problem with Twitter's implementation is that the documentation is sparse and there isn't a single example in Perl or Java. Maybe these two languages aren't cool enough to warrant examples but to me, they're important because they're all I know. I spent some time over the last few days trying to implement OAuth for Twitter in my Perl scripts. The example below is a bit messy but it works.It will create a few temp files, request a token for you, ask you to go to the URL printed to authorize the application. When you've authorized the application, run the script again and it will allow you to submit a status update.

`#! /usr/local/bin/perl

$Author: pankaj $

$Date: 2009-03-22 23:46:27 +0530 (Sun, 22 Mar 2009) $

Author: Pankaj Jain

Copyright: Teknatus Solutions LLC

################################################################################################################################ use Modern::Perl; use Carp; use Net::OAuth; use Data::Random qw(rand_chars); use LWP::UserAgent; use Data::Dumper; use JSON::Any;

main();

sub main{ my $ua = LWP::UserAgent->new;

my $consumer_key = 'sdBwlvTkpZr7eiCmB0Evig';
my $consumer_secret = 'asSINZmwnxwIfLwmdNvVBW7OSVzFOWj4mjJeDDaA';
my %tokens = getTokens();

requestToken(consumer_key => $consumer_key,
             consumer_secret => $consumer_secret,
             %tokens,
             ua => $ua);

my $message = "This is a Perl Net::OAuth test for twitter!";
my $foo = {status => $message};
my $url = 'https://twitter.com/statuses/update.json';
if (defined $message && $message ne "") {
    my $request = Net::OAuth->request("protected resource")->new(
        consumer_key => $consumer_key,
        consumer_secret => $consumer_secret,
        request_url => $url,
        request_method => 'POST',
        signature_method => 'HMAC-SHA1',
        timestamp => time,
        nonce => join('', rand_chars(size=>16, set=>'alphanumeric')),
        token => $tokens{token},
        token_secret => $tokens{secret},
        extra_params => $foo,
    );
    $request->sign;
    say Dumper($request);
    my $response = $ua->post($request->to_url);
    say Dumper($response);
    my $response_code    = $response->code;
    my $response_message = $response->message;
    my $response_error   = $response->content;
    if ($response->is_success) {
        my $retval = eval { JSON::Any->jsonToObj( $response->content ) };
        if ( !defined $retval ) {
            say "TWITTER RETURNED SUCCESS BUT PARSING OF THE RESPONSE FAILED - " . $response->content;
        }
    } else {
        say $response_code;
    }
    exit;
}

}

sub requestToken { my %args = @_; if (defined $args{consumer_key} && defined $args{consumer_secret} && !defined $args{access_token} && !defined $args{access_secret} && !defined $args{token} && !defined $args{token_secret}) { my $token; my $secret; my $request = Net::OAuth->request("consumer")->new( consumer_key => $args{consumer_key}, consumer_secret => $args{consumer_secret}, request_url => 'https://twitter.com/oauth/request_token', request_method => 'GET', signature_method => 'HMAC-SHA1', timestamp => time, nonce => join('', rand_chars(size=>16, set=>'alphanumeric')) ); $request->sign; my $res = $args{ua}->get($request->to_url); # Post message to the Service Provider if ($res->is_success) { my $response = Net::OAuth->response('request token')->from_post_body($res->content); print "Got Request Token ", $response->token, "n"; $token = $response->token; print "Got Request Token Secret ", $response->token_secret, "n"; $secret = $response->token_secret; if (defined $token) { my $auth_url = "https://twitter.com/oauth/authorize?oauth_token=" . $token; my $message = "Please visit $auth_url and authorize this application to access your twitter account. You may revoke access at any time you wish.n"; say $message . "n"; open(TMP,">/tmp/request_token.txt"); say TMP $token . "|" . $secret; close TMP; exit; } } else { die "Something went wrong"; } } elsif (defined $args{access_token} && defined $args{access_secret} && defined $args{consumer_key} && defined $args{consumer_secret} && !defined $args{token} && !defined $args{token_secret}) { my $auth_req = Net::OAuth->request("access token")->new( consumer_key => $args{consumer_key}, consumer_secret => $args{consumer_secret}, token => $args{access_token}, token_secret => $args{access_secret}, request_url => 'http://twitter.com/oauth/access_token', request_method => 'POST', signature_method => 'HMAC-SHA1', timestamp => time, nonce => join('', rand_chars(size=>16, set=>'alphanumeric')) ); $auth_req->sign(); my $res2 = $args{ua}->post($auth_req->to_url); # Post message to the Service Provider if (!$res2->is_success) { die 'Could not get an Access Token: ' . $res2->status_line . ' ' . $res2->content; } else { open(TF, ">$ENV{HOME}/.teknatus/.twitter_token"); my $response = Net::OAuth->response('access token')->from_post_body($res2->content); print STDERR "Got Access Token ", $response->token, "n"; my $access_tok = $response->token; print STDERR "Got Access Token Secret ", $response->token_secret, "n"; my $access_secret = $response->token_secret; say TF $access_tok . "|" .$access_secret; close TF; unlink("/tmp/request_token.txt") if (-e "/tmp/request_token.txt"); } exit; } }

sub getTokens { my %args = @; my %tokens; my $tokenFile = $ENV{HOME} ."/.teknatus/.twitter_token"; my $reqTokenFile = "/tmp/request_token.txt"; if (-e $tokenFile ) { open (TF, "<$tokenFile"); while() { chop($); next if ( $_ =~ /^s?$/); my @tmp = split(/|/, $); $tokens{token} = $tmp[0]; $tokens{secret} = $tmp[1]; } close TF; } if (-e $reqTokenFile) { open (TF, "<$reqTokenFile"); while() { chop($); next if ( $_ =~ /^s?$/); my @tmp = split(/|/, $_); $tokens{access_token} = $tmp[0]; $tokens{access_secret} = $tmp[1];

    }
    close TF;
}
return %tokens;

}

1;`


Pankaj Jain Profile picture

© 2025, Pankaj Jain
My personal writing Follow me on X