Anyone use Net::Twitter?

Ovid on 2008-06-16T20:00:50

I'm trying to use Net::Twitter with the following code:

#!/usr/bin/perl 

use strict;
use warnings;

use Net::Twitter;

# because LoudTwitter requires a user/pass ...

my %twitter = (
    username => 'OvidPerl',
    password => 'some_password',
);

my $twitter = Net::Twitter->new(%twitter);

my @timeline = $twitter->user_timeline;
use Data::Dumper;
print Dumper(\@timeline);

But I get the following error:

JSON text must be an object or array (but found number, string, true, false or null, use allow_nonref to allow this) at /Library/Perl/5.8.6/JSON/Any.pm line 377

That's from the following code:

sub user_timeline {
    my ( $self, $args ) = @_;

    my $url = $self->{apiurl} . "/statuses/user_timeline";
    $url .= (defined $args->{id}) ? "/" . $args->{id} . ".json" : ".json";

    if ((defined $args->{since}) || (defined $args->{count})) {
    $url .= "?";
    $url .= (defined $args->{since}) ? 'since=' . $args->{since} . "&" : "";
    $url .= (defined $args->{count}) ? 'count=' . $args->{count} : "";
    }
    my $req = $self->{ua}->get($url);
    $self->{response_code} = $req->code;
    $self->{response_message} = $req->message;
    return ($req->is_success) ?  JSON::Any->jsonToObj($req->content) : undef;

}

In debugging, I see that it's trying to get the correct URL, but the $req->content returns a ten digit integer instead of JSON, the same thing which is returned if I've failed to authenticate (but it returns a '200 OK' status, dang it). Has anyone made this work before? I've double-checked my password and have the latest versions of LWP::UserAgent and Net::Twitter installed.


Reducing it down to something easier to run ...

perigrin on 2008-06-16T21:40:46

This

perl -MData::Dumper -MNet::Twitter -sle'BEGIN{ print "$user => $pass" } print Dumper( Net::Twitter->new( user => $u, pass => $pass)->user_timeline() )' -- -user=perigrin -pass=ImSol33t

gives me the same error while

perl -MData::Dumper -MNet::Twitter -sle'BEGIN{ print "$user => $pass" } print Dumper( Net::Twitter->new( user => $u, pass => $pass)->user_timeline({count => 3) )' -- -user=perigrin -pass=StillL33t

does not (although it doesn't return usable data either). I’m suspecting twitter is having issues, but that’s a guess.

Re:Reducing it down to something easier to run ...

perigrin on 2008-06-16T22:34:02

lynx --dump --auth=perigrin:L33tInC http://www.twitter.com/statuses/user_timeline.json
dumps just an int too. so I'm gonna guess it's all failed.

broken?

link on 2008-06-16T21:42:03

I'd say something is up with twitter. friends_timeline requests are working fine and they return a superset of what user_timeline returns.

http://twitter.com/statuses/friends_timeline.json prompts for authentication in a browser but
http://twitter.com/statuses/user_timeline.json doesn't.

I'm stumped

ct on 2008-06-16T22:08:45

At the end of last week I gave up maintainership of Net::Twitter. Since the latest version available is still my code, I guess I've got some responsibility here.

I'm absolutely stumped. This has to be something on Twitter's side, though I can't think of how it's being triggered.

On the same box, perl doesn't work and wget does. Same URL, same auth, even the same useragent, which I hacked.

By documentation, user_timeline only returns the last 24 hours, but it's returning all for wget.

I wish I had a more intelligent, helpful answer for you, but this sort of moving target BS is one of the key reasons I've handed off the module. Twitter is a minefield. I'll make sure to let the new maintainer know, and I'll drop an email to the twitter API list, but this has to be twitterfail.

Re:I'm stumped

Ovid on 2008-06-16T22:56:30

Thanks for the update. I was going to file a bug report, but wanted to make sure I wasn't doing something stupid, first. I've filed a bug with Twitter. Hopefully I'll hear something, too.

Re:I'm stumped

link on 2008-06-16T23:02:59

Adding this at about line 50 or so in Twitter.pm fixes the problem in a messy kinda way.


use MIME::Base64;
$conf{ua}->default_header( "Authorization" => "Basic " . encode_base64( $conf{"username"} . ":" . $conf{"password"} ) );

Re:I'm stumped

ct on 2008-06-17T00:15:20

This is 100% twitterfail. The user_timeline API method is not returning the HTTP 401 response to challenge for authentication.

I've dropped a note to the API mailing list, Alex is usually pretty good at reading that and getting quick fixes in.

As I said earlier, this is the sort of thing that prompted me to transfer the module on to someone else.

Familiar

rjray on 2008-06-17T10:22:01

I use the module for the "cpan_linked" Twitter-bot that spools out CPAN upload notices with links to the page and (when findable) the Changelog. I've had a lot of problems that when examined closely were pretty clearly not the fault of Net::Twitter, but rather the, err, twits themselves.

For example, when the bot tries to send an update while Twitter is down, it gets a response of "500 Server Error".

In the message body.

The response code/message is not indicative of an error.

dunno if you had success with this

lachoy on 2008-07-08T18:46:29

But I found two things:

1) user_timeline() returns an arrayref, not an array (docs are unclear)

2) If you pass an ID explicitly to user_timeline() it seems to work, even if the ID is the same as the authenticating user and is therefore redundant. For instance, this works:

    my $username = 'cwinters';
    my $password = 'blah';
    my $tw = Net::Twitter->new( username => $username,
                                password => $password );
    my $items = $tw->user_timeline({ count => 10,
                                     id    => $username });
    foreach my $item ( @{ $items } ) {
        print "Item:\n", Dumper( $item ), "\n\n";
    }

But if I remove the 'id' parameter from user_timeline() it does not.