Remote notifications
This post explains how to get notifications (libnotify) from a remote system. Typically this is useful with an IRC client accessible through SSH.Prerequisites:
- A notification daemon! (dunst, xfce4-notifyd, etc.)
- socat
- notify-send
apt-get install socat libnotify-bin
On the client, modify the SSH configuration to introduce two elements:
- forward a TCP port,
- execute a local command.
Example entry for ~/.ssh/config:
Host remote-hostThe fowarded TCP port will be used to netcat notification messages to the local system.
Hostname remote-host.gandi.net
RemoteForward 12000 localhost:12000
PermitLocalCommand yes
LocalCommand socat -u tcp4-listen:12000,reuseaddr,fork,bind=127.0.0.1 exec:$HOME/.local/bin/notify-remote.sh 2>/dev/null &
socat is used to bind a port on the local system, it will take the notifcation messages, and write them to the executed shell script notify-remote.sh.
The shell script will then simply call notify-send to display a notification with the default notification daemon.
notify-remote.sh:
#!/bin/sh
delay="5000"
read line
summary="$line"
read line
msg="$line"
read line
if [ "$line" = "" ] && [ "$summary" != "" ]; then
[ -x "$(which notify-send)" ] && notify-send -u critical -t "$delay" -- "$summary" "$msg"
fi
Now it is possible to connect to the remote host and "write" notifications:
local$ ssh remote-host
remote-host$ echo -e 'SummarynBodynn' | nc 127.0.0.1 12000
Integrate into irssi
Copy the irssi script available bellow to get notifications from hilights, and private messages.
Once the script is copied, execute /script load rnotify.pl inside irssi.
~/.irssi/scripts/autorun/rnotify.pl:
# shamelessly copied from http://git.esaurito.net/?p=godog/bin.git;a=blob;f=rnotify.pl
use strict;
use Irssi;
use HTML::Entities;
use vars qw($VERSION %IRSSI);
$VERSION = "0.01";
%IRSSI = (
authors => 'Luke Macken, Paul W. Frields',
contact => 'lewk@csh.rit.edu, stickster@gmail.com',
name => 'rnotify',
description => 'Use libnotify to alert user to hilighted messages',
license => 'GNU General Public License',
url => 'http://lewk.org/log/code/irssi-notify',
);
Irssi::settings_add_str('misc', $IRSSI{'name'} . '_port', '12000');
Irssi::settings_add_bool('misc', $IRSSI{'name'} . '_if_away', 0);
sub is_port_owner {
my ($port, $uid) = @_;
my $wanted = sprintf("0100007F:%04X", $port);
# XXX linux-specific
open HANDLE, "< /proc/net/tcp" || return 0;
while(<HANDLE>){
# sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
my @splitted = split /s+/;
my $local = $splitted[2];
my $remote = $splitted[3];
my $uid = $splitted[8];
return 1 if $local eq $wanted and $uid == $<;
}
close HANDLE;
return 0;
}
sub notify {
my ($server, $summary, $message) = @_;
$message = HTML::Entities::encode($message);
$summary = HTML::Entities::encode($summary);
# echo escaping
$message =~ s/\/\\/g;
$summary =~ s/\/\\/g;
my $port = Irssi::settings_get_str($IRSSI{'name'} . '_port');
return if ! is_port_owner($port, $<);
# check for being away in every server?
return if $server->{usermode_away} &&
(Irssi::settings_get_bool($IRSSI{'name'} . '_if_away') == 0);
# XXX test for other means of doing TCP
#print("echo '$summaryn$messagenn' | /bin/nc 127.0.0.1 $port");
system("echo '$summaryn$messagenn' | /bin/nc 127.0.0.1 $port &");
#my $pid = open(FH, "|-");
#if( $pid ){
# print FH "$summaryn$messagenn";
# close(FH) || warn "exited $?";
#}else{
# exec("/bin/nc 127.0.0.1 $port") || warn "can't exec $!";
#}
}
sub print_text_notify {
my ($dest, $text, $stripped) = @_;
my $server = $dest->{server};
return if (!$server || !($dest->{level} & MSGLEVEL_HILIGHT));
my $sender = $stripped;
$sender =~ s/^<.([^>]+)>.+/1/ ;
$stripped =~ s/^<.[^>]+>.// ;
my $summary = "Message on $dest->{target}";
notify($server, $summary, $stripped);
}
sub message_private_notify {
my ($server, $msg, $nick, $address) = @_;
return if (!$server);
notify($server, "Private message from ".$nick, $msg);
}
sub dcc_request_notify {
my ($dcc, $sendaddr) = @_;
my $server = $dcc->{server};
return if (!$dcc);
notify($server, "DCC ".$dcc->{type}." request", $dcc->{nick});
}
Irssi::signal_add('print text', 'print_text_notify');
Irssi::signal_add('message private', 'message_private_notify');
Irssi::signal_add('dcc request', 'dcc_request_notify');
# vim: et
Remote notifications
This post explains how to get notifications (libnotify) from a remote system. Typically this is useful with an IRC client accessible through SSH.Prerequisites:
- A notification daemon! (dunst, xfce4-notifyd, etc.)
- socat
- notify-send
apt-get install socat libnotify-bin
On the client, modify the SSH configuration to introduce two elements:
- forward a TCP port,
- execute a local command.
Example entry for ~/.ssh/config:
Host remote-hostThe fowarded TCP port will be used to netcat notification messages to the local system.
Hostname remote-host.gandi.net
RemoteForward 12000 localhost:12000
PermitLocalCommand yes
LocalCommand socat -u tcp4-listen:12000,reuseaddr,fork,bind=127.0.0.1 exec:$HOME/.local/bin/notify-remote.sh 2>/dev/null &
socat is used to bind a port on the local system, it will take the notifcation messages, and write them to the executed shell script notify-remote.sh.
The shell script will then simply call notify-send to display a notification with the default notification daemon.
notify-remote.sh:
#!/bin/sh
delay="5000"
read line
summary="$line"
read line
msg="$line"
read line
if [ "$line" = "" ] && [ "$summary" != "" ]; then
[ -x "$(which notify-send)" ] && notify-send -u critical -t "$delay" -- "$summary" "$msg"
fi
Now it is possible to connect to the remote host and "write" notifications:
local$ ssh remote-host
remote-host$ echo -e 'Summary\nBody\n\n' | nc 127.0.0.1 12000
Integrate into irssi
Copy the irssi script available bellow to get notifications from hilights, and private messages.
Once the script is copied, execute /script load rnotify.pl inside irssi.
~/.irssi/scripts/autorun/rnotify.pl:
# shamelessly copied from http://git.esaurito.net/?p=godog/bin.git;a=blob;f=rnotify.pl
use strict;
use Irssi;
use HTML::Entities;
use vars qw($VERSION %IRSSI);
$VERSION = "0.01";
%IRSSI = (
authors => 'Luke Macken, Paul W. Frields',
contact => 'lewk@csh.rit.edu, stickster@gmail.com',
name => 'rnotify',
description => 'Use libnotify to alert user to hilighted messages',
license => 'GNU General Public License',
url => 'http://lewk.org/log/code/irssi-notify',
);
Irssi::settings_add_str('misc', $IRSSI{'name'} . '_port', '12000');
Irssi::settings_add_bool('misc', $IRSSI{'name'} . '_if_away', 0);
sub is_port_owner {
my ($port, $uid) = @_;
my $wanted = sprintf("0100007F:%04X", $port);
# XXX linux-specific
open HANDLE, "< /proc/net/tcp" || return 0;
while(<HANDLE>){
# sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
my @splitted = split /\s+/;
my $local = $splitted[2];
my $remote = $splitted[3];
my $uid = $splitted[8];
return 1 if $local eq $wanted and $uid == $<;
}
close HANDLE;
return 0;
}
sub notify {
my ($server, $summary, $message) = @_;
$message = HTML::Entities::encode($message);
$summary = HTML::Entities::encode($summary);
# echo \ escaping
$message =~ s/\\/\\\\/g;
$summary =~ s/\\/\\\\/g;
my $port = Irssi::settings_get_str($IRSSI{'name'} . '_port');
return if ! is_port_owner($port, $<);
# check for being away in every server?
return if $server->{usermode_away} &&
(Irssi::settings_get_bool($IRSSI{'name'} . '_if_away') == 0);
# XXX test for other means of doing TCP
#print("echo '$summary\n$message\n\n' | /bin/nc 127.0.0.1 $port");
system("echo '$summary\n$message\n\n' | /bin/nc 127.0.0.1 $port &");
#my $pid = open(FH, "|-");
#if( $pid ){
# print FH "$summary\n$message\n\n";
# close(FH) || warn "exited $?";
#}else{
# exec("/bin/nc 127.0.0.1 $port") || warn "can't exec $!";
#}
}
sub print_text_notify {
my ($dest, $text, $stripped) = @_;
my $server = $dest->{server};
return if (!$server || !($dest->{level} & MSGLEVEL_HILIGHT));
my $sender = $stripped;
$sender =~ s/^\<.([^\>]+)\>.+/\1/ ;
$stripped =~ s/^\<.[^\>]+\>.// ;
my $summary = "Message on $dest->{target}";
notify($server, $summary, $stripped);
}
sub message_private_notify {
my ($server, $msg, $nick, $address) = @_;
return if (!$server);
notify($server, "Private message from ".$nick, $msg);
}
sub dcc_request_notify {
my ($dcc, $sendaddr) = @_;
my $server = $dcc->{server};
return if (!$dcc);
notify($server, "DCC ".$dcc->{type}." request", $dcc->{nick});
}
Irssi::signal_add('print text', 'print_text_notify');
Irssi::signal_add('message private', 'message_private_notify');
Irssi::signal_add('dcc request', 'dcc_request_notify');
# vim: et