package App::ImapNotify; use v5.24; use strict; use warnings; our $VERSION = "0.01"; use App::ImapNotify::ImapClient; use App::ImapNotify::Notifier; use Carp; use Function::Parameters; use Log::Any qw($log); =encoding utf-8 =head1 NAME App::ImapNotify - It's new $module =head1 SYNOPSIS use App::ImapNotify; =head1 DESCRIPTION App::ImapNotify is a 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 LICENSE Copyright (C) Florian Pritz. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHOR Florian Pritz Ebluewind@xinu.atE =cut method new($class: $config, $deps = {}) { $deps->{imap_client} //= App::ImapNotify::ImapClient->new({$config->%{qw(host port log_id username password keepalive_timeout)}}); $deps->{notifier} //= App::ImapNotify::Notifier->new(); return $class->new_no_defaults($config, $deps); } method new_no_defaults($class: $config, $deps = {}) { my $self = {}; bless $self, $class; $self->{config} = $config; $self->{deps} = $deps; return $self; } method loop() { #my $imap = $self->{deps}->{imap_client}->connect($self->{config}->@{qw(host port log_id)}); #$imap->login($self->{config}->@{qw(username password)}); my $imap = $self->{deps}->{imap_client}; $imap->select($self->{config}->{mailboxes}->@[0]); $imap->send_command("notify set (selected (MessageExpunge MessageNew (uid body.peek[header.fields (from to subject)]))) (mailboxes (".join(' ', $self->{config}->{mailboxes}->@*).") (MessageNew MessageExpunge MailboxName))"); $log->info("Waiting for notify events"); while (my $line = $imap->readline_timeout()) { $log->tracef("Got line: '%s'", $line); if ($line =~ m/^\* .* FETCH /) { my $message = $imap->handle_fetch($line); $self->_notify($message); next; } if ($line =~ m/^\* STATUS (?[^ ]+) \(MESSAGES \d+ UIDNEXT (?\d+) UNSEEN \d+\)/) { $log->debugf("Got status change: '%s'", $line); my $mailbox = $+{mailbox}; my $uid = $+{uidnext} - 1; #$imap2->select($mailbox); #my $message = $imap2->send_command("uid fetch $uid (body.peek[header.fields (from to subject)])"); $imap->select($mailbox); my $message = $imap->send_command("uid fetch $uid (body.peek[header.fields (from to subject)])"); pop @{$message}; $self->_notify($message); next; } next if $line =~ /\* \d+ RECENT/; next if $line =~ /\* \d+ EXISTS/; next if $line =~ /\* \d+ EXPUNGE/; confess(sprintf("Got unexpected line: '%s'", $line)); } } method _notify($message) { $log->debugf("Got data for notification: %s", $message); my $fields = {}; my $current_field; return if $message->@* == 0; for my $line ($message->@*) { if ($line =~ m/^(?