#!/usr/bin/env perl use v5.24; use warnings; use strict; use App::ImapNotify; use Function::Parameters; use Log::Any::Adapter; use Log::Log4perl qw(:easy); use MCE::Hobo; use Path::Tiny; use TOML qw(from_toml); =head1 NAME imap-notify.pl - Simple notification script using IMAP NOTIFY =head1 SYNOPSIS imap-notify.pl [options] Options: --debug =head1 DESCRIPTION Simple notification script using IMAP NOTIFY. Note that it is very simple and implements a custom IMAP client with very limited features. Mostly a proof of concept and personal script. =head1 CONFIGURATION To configure the script create a file called $XDG_CONFIG_HOME/imap-notify/config.toml. You should create an array called "watches" with the following settings: =over =item log_id String to identify a particular connection in the debug log. =item host Hostname or IP of the server to connect to. =item port Port to connect to. =item username Username to use to authenticate. =item passwordeval Command that is run by the script and that outputs the password that will be used to authenticate on stdout. =item mailboxes Array of mailbox names to watch. =back =head2 Example Configuration [[watches]] log_id = "first-server" host = "mail.first-server.localdomain" port = 993 username = "my-username" passwordeval = "getpw-single my-username-password" mailboxes = ["INBOX", "INBOX.Postmaster", "Other.Mailbox"] [[watches]] log_id = "second-server" host = "imap.second.localdomain" port = 993 username = "user@second.localdomain" passwordeval = "getpw-single user@second.localdomain" mailboxes = ["INBOX"] =head1 SEE ALSO L =cut my $config = from_toml(path(($ENV{XDG_CONFIG_HOME} // $ENV{HOME}."/.config")."/imap-notify/config.toml")->slurp); Log::Log4perl->easy_init($ERROR); if ($ARGV[0] // "" eq "--debug") { Log::Log4perl->easy_init($TRACE); #Log::Any::Adapter->set("Stderr", log_level => "trace"); } else { Log::Log4perl->easy_init($INFO); } Log::Any::Adapter->set('Log4perl'); #$IO::Socket::SSL::DEBUG = 4; my @workers; for my $single_conf ($config->{watches}->@*) { $single_conf->{password} = `$single_conf->{passwordeval}`; push @workers, mce_async { my $app = App::ImapNotify->new($single_conf); $app->loop_reconnect(); } } map {$_->join()} @workers; fun trim($string) { $string =~ s/^\s+//; $string =~ s/\s+$//; return $string; }