diff options
-rw-r--r-- | lib/TgLib/Api.pm | 55 | ||||
-rwxr-xr-x | tgrecv | 52 | ||||
-rwxr-xr-x | tgsend | 42 | ||||
-rwxr-xr-x | tgserver | 12 |
4 files changed, 92 insertions, 69 deletions
diff --git a/lib/TgLib/Api.pm b/lib/TgLib/Api.pm new file mode 100644 index 0000000..3bbdde6 --- /dev/null +++ b/lib/TgLib/Api.pm @@ -0,0 +1,55 @@ +package TgLib::Api; + +use JSON qw<encode_json decode_json>; +use HTTP::Request; +use LWP::UserAgent; +use Data::Dumper; + +use parent 'Exporter'; +our @EXPORT = qw<new>; + +sub new { + my ($class, $token, $logger) = @_; + return bless { uri => "https://api.telegram.org/bot$token", + ua => LWP::UserAgent->new, + logger => $logger }, $class; +} + +sub get_updates { + my ($self, $timeout, $offset) = @_; + my $logger = $self->{'logger'}; + my $uri = "$self->{'uri'}/getUpdates?timeout=$timeout"; + $uri = $uri . "&offset=$offset" if $offset; + + my $req = HTTP::Request->new("GET", $uri); + $logger->debug("Request: " . Dumper($req)); + + my $resp = $self->{'ua'}->request($req); + $logger->debug("Response: " . Dumper($resp)); + + if ($resp->is_error()) { + die $resp->message; + } else { + return decode_json($resp->content)->{'result'}; + } +} + +sub send_message { + my ($self, $chat_id, $text) = @_; + my $logger = $self->{'logger'}; + my $uri = "$self->{'uri'}/sendMessage"; + my $content = encode_json {'chat_id' => $chat_id, 'text' => $text}; + + my $req = HTTP::Request->new("POST", $uri, + ["Content-Type", "application/json"], $content); + $logger->info("Sending to $chat_id:\n====\n$text\n====\n"); + $logger->debug(sprintf "Request:\n%s\n", Dumper($req)); + + my $resp = $self->{'ua'}->request($req); + $logger->debug(sprintf "Response:\n%s\n", Dumper($resp)); + if ($resp->is_error()) { + die $resp->message; + } +} + +1; @@ -7,23 +7,20 @@ # Dependencies: HTTP-Message, JSON ################################################################################ -$main::VERSION = "0.1.0"; +$main::VERSION = "0.1.1"; use Getopt::Long qw(:config auto_version); use Pod::Usage qw<pod2usage>; -use LWP::UserAgent; use Data::Dumper; - -use HTTP::Request; -use JSON qw<encode_json decode_json>; +use JSON qw<encode_json>; # Local modules use FindBin; use lib "$FindBin::Bin/lib"; use TgLib qw<fetch_token>; -use TgLib::Env qw<$HOME $CONFIG_HOME $CACHE_HOME>; require TgLib::Cache; require TgLib::Logger; +require TgLib::Api; my $TOKEN; my $OUTPUT; @@ -44,7 +41,7 @@ pod2usage(-verbose => $VERBOSE+1) if $HELP; my $logger = TgLib::Logger->new($VERBOSE); -# If token was not specified in CLI, get it from ENV/file +# Fetch token: CLI || env || file $TOKEN ||= fetch_token() or pod2usage(-message => "ERROR: Unable to get bot token ($!).\n", -verbose => 99, -sections => "AUTHENTICATION"); @@ -57,34 +54,23 @@ if ($AUTO_OFFSET && ! $OFFSET) { $OFFSET |= $cache->offset; } -my $ua = LWP::UserAgent->new; -my $uri = "https://api.telegram.org/bot$TOKEN/getUpdates?timeout=$TIMEOUT"; -$uri = $uri . "&offset=$OFFSET" if $OFFSET; -my $req = HTTP::Request->new("GET", $uri); -$logger->debug("Request: " . Dumper($req)); - -my $resp = $ua->request($req); -$logger->debug("Response: " . Dumper($resp)); -if ($resp->is_error()) { - die $resp->message; -} else { - my $out = STDOUT; - if ($OUTPUT) { - open($out, ">", $OUTPUT) or die "Cannot open $OUTPUT for writing: $!"; - } - my $results = decode_json($resp->content)->{'result'}; - - # Store new offset in cache - if ($AUTO_OFFSET && @$results) { - # Update cache: set offset to last update id +1 - $cache->offset($results->[-1]{'update_id'}+1); - $logger->debug(sprintf "Cached offset %s (--auto-offset)\n", $cache->offset); - $cache->save; - } - - print $out encode_json($results); +my $api = TgLib::Api->new($TOKEN, $logger); +my $updates = $api->get_updates($TIMEOUT, $OFFSET); + +my $out = STDOUT; +if ($OUTPUT) { + open($out, ">", $OUTPUT) or die "Cannot open $OUTPUT for writing: $!"; } +# Store new offset in cache (last update id +1) +if ($AUTO_OFFSET && @$updates) { + $cache->offset($updates->[-1]{'update_id'}+1); + $logger->debug(sprintf "Cached offset %s (--auto-offset)\n", $cache->offset); + $cache->save; +} + +print $out encode_json($updates); + __END__ @@ -7,28 +7,24 @@ # Dependencies: HTTP-Message, JSON ################################################################################ -$main::VERSION = "0.1.0"; +$main::VERSION = "0.1.1"; use Getopt::Long qw(:config auto_version); use Pod::Usage qw<pod2usage>; -use LWP::UserAgent; -use Data::Dumper; - -use HTTP::Request; -use JSON qw<encode_json>; # Local modules use FindBin; use lib "$FindBin::Bin/lib"; use TgLib qw<fetch_token>; -use TgLib::Env qw<$HOME $CONFIG_HOME $CACHE_HOME>; require TgLib::Logger; +require TgLib::Api; my $TOKEN; my $PRETEND; my $VERBOSE = 0; my $HELP; +# Parse CLI options GetOptions("token=s" => \$TOKEN, "pretend" => \$PRETEND, "verbose+" => \$VERBOSE, @@ -37,37 +33,23 @@ pod2usage(-verbose => $VERBOSE+1) if $HELP or ! @ARGV; my $logger = TgLib::Logger->new($VERBOSE); -# If token was not specified in CLI, get it from ENV/file +# Fetch token: CLI || env || file $TOKEN ||= fetch_token() or pod2usage(-message => "ERROR: Unable to get bot token ($!).\n", -verbose => 99, -sections => "AUTHENTICATION"); # Read text from stdin undef $/; -my $TEXT = <STDIN>; - -my $ua = LWP::UserAgent->new; -my $URI = "https://api.telegram.org/bot$TOKEN/sendMessage"; -sub send_message { - my $chat_id = shift; - my $content = encode_json {'chat_id' => $chat_id, 'text' => $TEXT}; - my $req = HTTP::Request->new("POST", $URI, - ["Content-Type", "application/json"], $content); - if ($VERBOSE || $PRETEND) { - $logger->info("Sending to $chat_id:\n====\n$TEXT\n====\n"); - $logger->debug(sprintf "Request:\n%s\n", Dumper($req)); - } - unless ($PRETEND) { - my $resp = $ua->request($req); - print STDERR "Response:\n", Dumper($resp), "\n" if $VERBOSE > 1; - if ($resp->is_error()) { - die $resp->message; - } - } +my $text = <STDIN>; + +# Send message to chats (or pretend to) +if ($PRETEND) { + $logger->info("(prentend) Sending to $_:\n====\n$text\n====\n") foreach @ARGV; +} else { + my $api = TgLib::Api->new($TOKEN, $logger); + $api->send_message($_, $text) foreach @ARGV; } -send_message($_) foreach @ARGV; - __END__ @@ -5,7 +5,7 @@ # Run `tgserver -h` for quick help, or `tgserver -h -v` for full manual. ################################################################################ -$main::VERSION = "0.1.0"; +$main::VERSION = "0.1.1"; use Getopt::Long qw(:config auto_version); use Pod::Usage qw<pod2usage>; @@ -18,6 +18,7 @@ use lib "$FindBin::Bin/lib"; use TgLib qw<fetch_token>; require TgLib::Logger; +require TgLib::Api; my $TOKEN; my $VERBOSE = 0; @@ -40,8 +41,8 @@ while (1) { foreach my $update (@{decode_json <$recv>}) { $logger->debug(sprintf "Update %s", Dumper($update)); my $text = $update->{'message'}{'text'}; - my $chatid = $update->{'message'}{'chat'}{'id'}; - $logger->info("Received update from chat $chatid\n"); + my $chat_id = $update->{'message'}{'chat'}{'id'}; + $logger->info("Received update from chat $chat_id\n"); use IPC::Open2 qw<open2>; my $pid = open2(my $progr, my $progw, "@ARGV"); @@ -53,9 +54,8 @@ while (1) { close($progr); if ($response) { - open(my $send, "|-", "$FindBin::Bin/tgsend --token $TOKEN $chatid"); - print $send $response; - close($send); + my $api = TgLib::Api->new($TOKEN, $logger); + $api->send_message($chat_id, $text, $response); } else { $logger->warn("Empty response, skipping\n"); } |