Skip to content

Instantly share code, notes, and snippets.

@holly
Last active July 22, 2021 14:40
Show Gist options
  • Save holly/be57b6cee0a8c9407e946d47ace71b00 to your computer and use it in GitHub Desktop.
Save holly/be57b6cee0a8c9407e946d47ace71b00 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use autodie;
use feature qw(say);
use File::Spec;
use FindBin qw($Script $Bin);
use LINE::Notify::Simple;
use Getopt::Long qw(:config posix_default no_ignore_case gnu_compat);
use YAML;
use Net::IMAP::Client;
use Email::MIME;
use HTML::FormatText;
use Encode;
our $VERSION = '1.0';
our $AUTHOR = 'holly';
our $CONFIG_FILE = File::Spec->catfile($ENV{HOME}, ".imap2line.yml");
our $LINE_NOTIFY_FORMAT = <<BODY;
Date: %s
Subject: %s
%s
BODY
my ($config_file, $help, $version);
GetOptions(
"config-file|c=s" => \$config_file,
"help|h" => \$help,
"version|v" => \$version,
);
if ($help) {
help();
exit;
}
if ($version) {
version();
exit;
}
if (!defined $config_file) {
$config_file = $CONFIG_FILE;
}
my $config = read_config_file($config_file);
my $imap = Net::IMAP::Client->new(%{$config->{imap}});
if (!$imap) {
die "Could not connect to IMAP server";
}
$imap->login or die 'Login failed: ' . $imap->last_error;
my $line = LINE::Notify::Simple->new( { access_token => $config->{line}->{access_token} } );
foreach my $folder (@{$config->{imap}->{folders}}){
$imap->select($folder);
my $messages = $imap->search("ALL", "^DATE");
foreach my $msg_id (@{$messages}) {
my $data = parse_mail_body($imap->get_rfc822_body($msg_id));
my $res = $line->notify(sprintf $LINE_NOTIFY_FORMAT, $data->{date}, $data->{subject}, $data->{body} );
printf "line request: %s %s\n", $msg_id, encode("UTF-8", $data->{subject});
if ($res->is_success) {
$imap->store($msg_id, '\\Deleted');
#$imap->add_flags($msg_id, '\\Deleted');
#$imap->delete_message($msg_id);
} else {
say "ERROR:" . $res->message;
}
$imap->expunge;
}
}
$imap->logout;
exit;
sub parse_mail_body {
my $data = shift;
my $parsed = Email::MIME->new($data);
my $date = $parsed->header('Date');
my $subject = $parsed->header('Subject');
my $body = "";
$parsed->walk_parts(sub {
my $part = shift;
return if $part->subparts;
my $content_type = $part->content_type;
if (!defined $content_type || $content_type =~ m{text/plain}i) {
$body = $part->body_str;
} elsif($content_type =~ m{text/html}i) {
$body = HTML::FormatText->format_string($part->body_str);
}
});
return { date => $date, subject => $subject, body => $body };
}
sub read_config_file {
my $config_file = shift;
open my $fh, "<", $config_file;
my $data = do { local $/ = undef; <$fh> };
close $fh;
return YAML::Load($data);
}
sub help {
print <<EOL;
Usage: $Script [option]...
-c, --config_file YAML file. file is written imap server/user/pass and line token.
default: \$HOME/.imap2line.yaml
-h, --help display this help and exit.
-v, --version output version information and exit.
EOL
}
sub version {
print <<EOL;
$Script $VERSION
Written by $AUTHOR.
EOL
}
=pod
=head1 config sample
=head2 default path
$HOME/.imap2line.yml
=head2 content
imap:
server: your.imap.server
port: 993
ssl: 1
ssl_verify_peer: 1
user: your_name
pass: your_pass
folders:
- .folder1
- .folder2
line:
access_token: your_line_token
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment