--- /dev/null
+#! /usr/bin/perl -w
+
+use strict;
+use warnings;
+use utf8;
+
+## IMPORTANT ##
+# When Net::Twitter::Lite encounters a Twitter API error or a network error,
+# it throws a Net::Twitter::Lite::Error object.
+# You can catch and process these exceptions by using eval blocks and testing $@
+## from http://search.cpan.org/perldoc?Net::Twitter::Lite#ERROR_HANDLING
+use Net::Twitter::Lite;
+use FindBin qw($Bin);
+use YAML::Tiny;
+use Data::Dumper;
+use Encode;
+
+my $help = sub {
+ die <<EOM;
+usage: $0 [text_file_to_tweet]
+EOM
+};
+if ($ARGV[0] && ($ARGV[0] eq '--help' || $ARGV[0] eq '-h') ) {
+ &{$help};
+}
+
+my $file = $ARGV[0] || 'update.log';
+my $conf = loadconf("$Bin/config.yml");
+if (! defined $conf) {
+ die "$0: cannot parse config file.";
+}
+
+my $bot = login($conf);
+if (! $bot->authorized) {
+ die "$0: this client is not yet authorized.";
+}
+
+open TWEET, $file or die "$0: cannot open file: $file";
+eval {
+ my $update = "";
+ my $res;
+ foreach my $line (<TWEET>) {
+ chomp $line;
+ $update .= $line;
+ }
+ if (length $update) {
+ $update = decode('utf8', $update);
+ $res = $bot->update($update);
+ }
+
+ foreach my $line (split /\n/, Dumper $res) {
+ if ($line =~ /undef/) { next; }
+ print STDERR $line, "\n";
+ }
+ if (ref $res) {
+ my $status = $res;
+ my $text = "";
+ $text .= "(". $status->{id} . ") ";
+ $text .= ($status->{user}{name}) ? $status->{user}{name} : $status->{from_user};
+ $text .= " [" . $status->{created_at} . "]";
+ $text .= " ". $status->{text};
+ $text =~ s/\n//;
+ print encode('sjis', $text), "\n";
+ }
+};
+if ($@) {
+ evalrescue($@);
+}
+
+
+sub loadconf {
+ # load configration data from yaml formatted file
+ # param => scalar string of filename
+ # ret => hash object of yaml data
+
+ my $file = shift @_;
+
+ my $yaml = YAML::Tiny->read($file);
+
+ if ($!) {
+ warn "$0: '$file' $!";
+ }
+
+ return $yaml->[0];
+}
+
+sub login {
+ # make Net::Twitter::Lite object and login
+ # param => hash object of configration
+ # ret => Net::Twitter::Lite object
+
+ my $conf = shift @_;
+
+ my $bot = Net::Twitter::Lite->new(
+ consumer_key => $conf->{consumer_key},
+ consumer_secret => $conf->{consumer_secret},
+ );
+
+ $bot->access_token($conf->{access_token});
+ $bot->access_token_secret($conf->{access_token_secret});
+
+ return $bot;
+}
+
+sub evalrescue {
+ # output error message at eval error
+
+ use Scalar::Util qw(blessed);
+
+ if (blessed $@ && $@->isa('Net::Twitter::Lite::Error')) {
+ warn $@->error;
+ if ($@->twitter_error) {
+ my %twitter_error = %{$@->twitter_error};
+ map {
+ $twitter_error{"$_ => "} = $twitter_error{$_} . "\n";
+ delete $twitter_error{$_}
+ } keys %twitter_error;
+ warn join("", %twitter_error);
+ }
+ }
+ else {
+ warn $@;
+ }
+}