Goku Goku - 1 year ago 85
Perl Question

Perl read a file and send e-mail

I have a log file of below format

D12345 joe@gmail.com
C67890 mary@gmail.com
B45678 don@gmail.com
A12309 joe@gmail.com
F45670 mary@gmail.com
F45470 joe@gmail.com

Currently I'm able to send e-mail to everyone with below e-mail body content

your Product id: $product_id

($product_id is D12345, A12309, F45470 , C67890, F45670)

Problem is 'N' e-mails are sent to an user if their e-mail id is present N times in the log file.

Example :
2 e-mails are sent to mary@gmail.com and 3 e-mails are sent to joe@gmail.com

I want to send only one e-mail to the users but having all their product ids, if single e-mail id occurs multiple times in the output file, like

your Product ids: C67890, F45670 to mary@gmail.com


your Product ids: D12345, A12309, F45470 to joe@gmail

My current code snippet

open my $fh, '<', "output.txt" or die "could not open file: $!";
while (my $line = <$fh>) {
my ($product_id, $to_email) = $line =~ /(\w\d+)\t(\S+)/;

my $MailFrom = 'myemail@domain.com';
my $subject = "PRODUCT ID DETAILS";
my $message = "your Product ids: $product_id";

%mail = (
To => $to_email,
From => $MailFrom,
Subject => $subject,
Message => $message

$mail{Smtp} = 'mail.myorg.com';

sendmail(%mail)or die $Mail::Sendmail::error;
close $fh;

Suggestions are really appreciated. Thanks in advance.

Answer Source

You must aggregate the information from the log file into a hash before sending the mails

Here's some example code which dumps the %mail hash instead of calling sendmail so that you can see the results

use strict;
use warnings 'all';

use Data::Dump;

my %users;

    open my $fh, '<', "output.txt" or die "could not open file: $!";

    while ( <$fh> ) { 
        my ($prod, $user) = split;
        push @{ $users{$user} }, $prod;

# Convert arrays of product codes into comma-separated strings
$_ = join ', ', @$_ for values %users;

while ( my ($user, $prods) = each %users ) {

    my %mail = (
        To      => $user,
        From    => 'myemail@domain.com',
        Subject => 'PRODUCT ID DETAILS',
        Message => "Your product IDs: $prods",
        Smtp    => 'mail.myorg.com',

    dd \%mail

    #sendmail(%mail) or die $Mail::Sendmail::error;


  From => "myemail\@domain.com",
  Message => "Your product IDs: D12345, A12309, F45470",
  Smtp => "mail.myorg.com",
  Subject => "PRODUCT ID DETAILS",
  To => "joe\@gmail.com",
  From => "myemail\@domain.com",
  Message => "Your product IDs: B45678",
  Smtp => "mail.myorg.com",
  Subject => "PRODUCT ID DETAILS",
  To => "don\@gmail.com",
  From => "myemail\@domain.com",
  Message => "Your product IDs: C67890, F45670",
  Smtp => "mail.myorg.com",
  Subject => "PRODUCT ID DETAILS",
  To => "mary\@gmail.com",
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download