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