use strict; use warnings; use Irssi; use vars qw($VERSION %IRSSI %config); use LWP::UserAgent; use Scalar::Util qw(looks_like_number); $VERSION = '0.0.3'; %IRSSI = ( authors => 'Kevin Siml', contact => '[email protected]', name => 'pushsafer', description => 'Push hilights and private messages when away by the pushsafer.com API', license => 'BSD', url => 'https://www.pushsafer.com', changed => "2018-08-21" ); my $pushsafer_ignorefile; sub cmd_help { my $out = <<'HELP_EOF'; PUSHIGNORE LIST PUSHIGNORE ADD PUSHIGNORE REMOVE The mask matches in the format ident@host. Notice that no-ident responses puts a tilde in front of the ident. Examples: Will match [email protected] but *not* [email protected]. /PUSHIGNORE ADD foo@*.bar.de Use the list-command to show a list of ignores and the number in front combined with remove to delete that mask. /PUSHIGNORE REMOVE 2 For a list of available settings, run: /set pushsafer HELP_EOF chomp $out; Irssi::print($out, MSGLEVEL_CLIENTCRAP); } sub read_settings { $pushsafer_ignorefile = Irssi::settings_get_str('pushsafer_ignorefile'); } sub debug { return unless Irssi::settings_get_bool('pushsafer_debug'); my $text = shift; my @caller = caller(1); Irssi::print('From '.$caller[3].': '.$text); } sub send_push { my $private_key = Irssi::settings_get_str('pushsafer_key'); if (!$private_key) { debug('Missing Pushsafer.com private or alias_key.'); return; } debug('Sending notification.'); my ($channel, $text) = @_; my $resp = LWP::UserAgent->new()->post( 'https://www.pushsafer.com/api', [ k => $private_key, m => $text, d => Irssi::settings_get_str('pushsafer_device'), s => Irssi::settings_get_str('pushsafer_sound'), i => Irssi::settings_get_str('pushsafer_icon'), c => Irssi::settings_get_str('pushsafer_iconcolor'), v => Irssi::settings_get_str('pushsafer_vibration'), u => Irssi::settings_get_str('pushsafer_url'), ut => Irssi::settings_get_str('pushsafer_urltitle'), l => Irssi::settings_get_str('pushsafer_time2live'), pr => Irssi::settings_get_str('pushsafer_priority'), re => Irssi::settings_get_str('pushsafer_retry'), ex => Irssi::settings_get_str('pushsafer_expire'), cr => Irssi::settings_get_str('pushsafer_confirm'), a => Irssi::settings_get_str('pushsafer_answer'), ao => Irssi::settings_get_str('pushsafer_answeroptions'), af => Irssi::settings_get_str('pushsafer_answerforce'), t => $channel ] ); if ($resp->is_success) { debug('Notification successfully sent.'); } else { debug('Notification not sent: '.$resp->decoded_content); } } sub msg_pub { my ($server, $data, $nick, $address, $target) = @_; my $safeNick = quotemeta($server->{nick}); if(check_ignore_channels($target)) { return; } if(check_ignore($address) || check_away($server)) { return; } if ($data =~ /$safeNick/i) { debug('Got pub msg.'); send_push($target, $nick.': '.Irssi::strip_codes($data)); } } sub msg_print_text { my ($dest, $text, $stripped) = @_; my $server = $dest->{server}; my $target = $dest->{target}; return if (!$server || !($dest->{level} & MSGLEVEL_HILIGHT)); if(check_ignore_channels($target)) { return; } if(check_away($server)) { return; } debug('Got nick highlight'); $stripped =~ s/^\s+|\s+$//g; send_push($target, $stripped); } sub msg_pri { my ($server, $data, $nick, $address) = @_; if(check_ignore($address) || check_away($server)) { return; } debug('Got priv msg.'); send_push('Priv, '.$nick, Irssi::strip_codes($data)); } sub msg_kick { my ($server, $channel, $nick, $kicker, $address, $reason) = @_; if(check_ignore($address) || check_away($server)) { return; } if ($nick eq $server->{nick}) { debug('Was kicked.'); send_push('Kicked: '.$channel, 'Was kicked by: '.$kicker.'. Reason: '.Irssi::strip_codes($reason)); } } sub msg_test { my ($data, $server, $item) = @_; $data =~ s/^([\s]+).*$/$1/; my $orig_debug = Irssi::settings_get_bool('pushsafer_debug'); Irssi::settings_set_bool('pushsafer_debug', 1); debug("Sending test message :" . $data); send_push("Test Message", Irssi::strip_codes($data)); Irssi::settings_set_bool('pushsafer_debug', $orig_debug); } # check our away status & pushsafer_only_if_away. returns 0 if it's ok to send a message. sub check_away { my ($server) = @_; my $msg_only_if_away = Irssi::settings_get_bool('pushsafer_only_if_away'); if ($msg_only_if_away && $server->{usermode_away} != '1') { debug("Only sending messages if we're marked as away, and we're not"); return 1; } return 0; } sub check_ignore { return 0 unless(Irssi::settings_get_bool('pushsafer_ignore')); my @ignores = read_file(); return 0 unless(@ignores); my ($mask) = @_; foreach (@ignores) { $_ =~ s/\./\\./g; $_ =~ s/\*/.*?/g; if ($mask =~ m/^$_$/i) { debug('Ignore matches, not pushing.'); return 1; } } return 0; } sub check_ignore_channels { my ($target) = @_; my @ignore_channels = split(' ', Irssi::settings_get_str('pushsafer_ignorechannels')); return 0 unless @ignore_channels; if (grep {lc($_) eq lc($target)} @ignore_channels) { debug("$target set as ignored channel."); return 1; } return 0; } sub ignore_handler { my ($data, $server, $item) = @_; $data =~ s/\s+$//g; Irssi::command_runsub('pushignore', $data, $server, $item); } sub ignore_unknown { cmd_help(); Irssi::signal_stop(); # Don't print 'no such command' error. } sub ignore_list { my @data = read_file(); if (@data) { my $i = 1; my $out; foreach(@data) { $out .= $i++.". $_\n"; } chomp $out; Irssi::print($out, MSGLEVEL_CLIENTCRAP); } } sub ignore_add { my ($data, $server, $item) = @_; $data =~ s/^([\s]+).*$/$1/; return Irssi::print("No hostmask given.", MSGLEVEL_CLIENTCRAP) unless($data ne ""); my @ignores = read_file(); push(@ignores, $data); write_file(@ignores); Irssi::print("Successfully added '$data'.", MSGLEVEL_CLIENTCRAP); } sub ignore_remove { my($num, $server, $item) = @_; $num =~ s/^(\d+).*$/$1/; return Irssi::print("List-number is needed when removing", MSGLEVEL_CLIENTCRAP) unless(looks_like_number($num)); my @ignores = read_file(); # Index out of range return Irssi::print("Number was out of range.", MSGLEVEL_CLIENTCRAP) unless(scalar(@ignores) >= $num); delete $ignores[$num-1]; write_file(@ignores); } sub write_file { read_settings(); my $fp; if (!open($fp, ">", $pushsafer_ignorefile)) { Irssi::print("Error opening ignore file", MSGLEVEL_CLIENTCRAP); return; } print $fp join("\n", @_); close $fp; } sub read_file { read_settings(); my $fp; if (-e $pushsafer_ignorefile) { if (!open($fp, "<", $pushsafer_ignorefile)) { Irssi::print("Error opening ignore file", MSGLEVEL_CLIENTCRAP); return; } } my @out; while (<$fp>) { chomp; next if $_ eq ''; push(@out, $_); } close $fp; return @out; } Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_key', ''); Irssi::settings_add_bool($IRSSI{'name'}, 'pushsafer_debug', 0); Irssi::settings_add_bool($IRSSI{'name'}, 'pushsafer_ignore', 1); Irssi::settings_add_bool($IRSSI{'name'}, 'pushsafer_only_if_away', 0); Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_ignorefile', Irssi::get_irssi_dir().'/pushsafer_ignores'); Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_ignorechannels', ''); # Check the Pushsafer.com API > https://www.pushsafer.com/en/pushapi for replacing params Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_sound', '21'); Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_device', ''); Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_icon', '25'); Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_iconcolor', '25'); Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_vibration', '0'); Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_url', ''); Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_urltitle', ''); Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_time2live', ''); Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_priority', ''); Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_retry', ''); Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_expire', ''); Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_confirm', ''); Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_answer', ''); Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_answeroptions', ''); Irssi::settings_add_str($IRSSI{'name'}, 'pushsafer_answerforce', ''); Irssi::command_bind('help pushignore', \&cmd_help); Irssi::command_bind('pushignore help', \&cmd_help); Irssi::command_bind('pushignore add', \&ignore_add); Irssi::command_bind('pushignore remove', \&ignore_remove); Irssi::command_bind('pushignore list', \&ignore_list); Irssi::command_bind('pushignore', \&ignore_handler); Irssi::command_bind('pushtest', \&msg_test); Irssi::signal_add_first("default command pushignore", \&ignore_unknown); #Irssi::signal_add_last('message public', 'msg_pub'); Irssi::signal_add_last('print text', 'msg_print_text'); Irssi::signal_add_last('message private', 'msg_pri'); Irssi::signal_add_last('message kick', 'msg_kick'); Irssi::print('%Y>>%n '.$IRSSI{name}.' '.$VERSION.' loaded.'); if (!Irssi::settings_get_str('pushsafer_key')) { Irssi::print('%Y>>%n '.$IRSSI{name}.' Pushsafer.com private or alias key is not set, set it with /set pushsafer_key YourPrivateOrAliasKey'); }