package Rest::Twitter; use base 'Rest'; use Data::Dumper; my $twitter_status_uri = "http://twitter.com/statuses/mentions.xml"; my $twitter_update_uri = "http://twitter.com/statuses/update.xml"; my $twitter_dm_uri = "http://twitter.com/direct_messages.xml"; my $twitter_dm_new_uri = "http://twitter.com/direct_messages/new.xml"; sub dm_post { my ($self, $user, $tweet) = @_; return unless $user && $tweet; $tweet =~ s/\s+/ /g; print ">>> D $user: $tweet\n"; return $self->rest_post($twitter_dm_new_uri, {text => $tweet, user => $user}); } sub tweet_post { my ($self, $tweet, $replyid) = @_; $tweet =~ s/\s+/ /g; print ">>> $tweet\n"; return $self->rest_post($twitter_update_uri, {status => $tweet, in_reply_to_status_id => $replyid}); } sub dm_get { my ($self) = @_; my $twitter_since_id = $self->since_id("dm"); my $dm_data = $self->rest_get($twitter_dm_uri, {since_id => $twitter_since_id}); # return (undef, undef) unless exists($tweet_data->{'status'}); # DEFAULT: plural behavior my $status = $dm_data->{'direct_message'}; # CATCH: singular behavior if (exists($status->{'id'})) { my $id = $status->{'id'}; $status = { $id => $status }; } my $dms = []; my $last_id = 0; foreach my $id (keys %{ $status }) { if ($id > $last_id) { $last_id = $id; } my $dm = $status->{$id}->{'text'}; my $user = $status->{$id}->{'sender_screen_name'}; push @$dms, {id => $id, tweet => $dm, user => $user, type => "dm"}; } if ($last_id > $twitter_since_id) { $self->since_id("dm", $last_id); } return $dms; } sub tweet_get { my ($self) = @_; my $twitter_since_id = $self->since_id("status"); my $tweet_data = $self->rest_get($twitter_status_uri, {since_id => $twitter_since_id}); return (undef, undef) unless exists($tweet_data->{'status'}); # DEFAULT: plural behavior my $status = $tweet_data->{'status'}; # CATCH: singular behavior if (exists($status->{'id'})) { my $id = $status->{'id'}; $status = { $id => $status }; } my $tweets = []; my $last_id = 0; foreach my $id (keys %{ $status }) { if ($id > $last_id) { $last_id = $id; } my $tweet = $status->{$id}->{'text'}; my $user = $status->{$id}->{'user'}->{'screen_name'}; push @$tweets, {id => $id, tweet => $tweet, user => $user, type => "tweet"}; } if ($last_id > $twitter_since_id) { $self->since_id("status", $last_id); } return $tweets; } sub since_id { my ($self, $key, $id) = @_; return unless $key; $self->{'since'} ||= {}; if ($id) { if ($self->{'since'}->{$key} < $id) { $self->{'since'}->{$key} = $id; $self->_since_id_write($key, $id); } } if (! exists($self->{'since'}->{$key})) { $self->{'since'}->{$key} = $self->_since_id_read($key); } return $self->{'since'}->{$key}; } sub _since_id_read { my ($self, $key) = @_; my $file = $self->_since_id_file($key); open LAST, $file; my $line = $self->trim(); close LAST; return $line; } sub _since_id_write { my ($self, $key, $id) = @_; my $file = $self->_since_id_file($key); open LAST, ">$file"; print LAST $id."\n"; close LAST; } sub _since_id_file { my ($self, $key) = @_; my $tmp_dir = "../tmp"; my $file = $tmp_dir."/twitter-".$self->user."-".$key; for ($tmp_dir, $file) { die ("can't find $_") unless -e $_; } return $file; } 1;