Difference between revisions of "RtReminderMails"

From Request Tracker Wiki
Jump to navigation Jump to search
(prob with sendmail?)
m (10 revisions imported)
 
(4 intermediate revisions by the same user not shown)
Line 3: Line 3:
Note - it requires the [http://search.cpan.org/~stbey/Date-Calc-5.4/Calc.pod Date::Calc] and [http://search.cpan.org/dist/Getopt-Long/ Getopt::Long] perl modules.
Note - it requires the [http://search.cpan.org/~stbey/Date-Calc-5.4/Calc.pod Date::Calc] and [http://search.cpan.org/dist/Getopt-Long/ Getopt::Long] perl modules.


  <nowiki>
 
        #!/usr/bin/perl
 
        #
  <code>   #!/usr/bin/perl
        # This script outputs all reminders that are due within the next e.g. 2 days
    #
        # and mails the result to the corresponding owners. christian <ch AT westend.com>
    # This script outputs all reminders that are due within a configurable period
        #####
    # of time and mails the result to the corresponding owners.
        # FING - UdelaR
    #####
        # Modified by Mario A. del Riego <delriego AT fing DOT edu DOT uy>
    # Original Author: FING - UdelaR
        # Modified by Gary Greene <ggreene AT minervanetworks DOT com>
    # Modified: christian <ch AT westend.com>
        # Restructured to allow cleaner execution flow
    # Modified: Mario A. del Riego <delriego AT fing DOT edu DOT uy>
        # Removed taint check as it does not work currently
    # Modified: Gary Greene <ggreene AT minervanetworks DOT com>
        # Fixed an old variable dont defined
    #####
        # Changed mail format (ticket id added)
    # * 2015.12.11 - Gary Greene <ggreene AT minervanetworks DOT com>
        # Getopt added for parameters: --debug --reminder --ticket --interval and --help
    # - Turn taint back OFF. RT::I18N still causes perl to complain about insecure dependencies.
        # File: http://www.fing.edu.uy/~delriego/RT_Reminder.pl
    #
        # v 1.5
    # * 2015.12 - Gary Greene <ggreene AT minervanetworks DOT com>
       
    # - Bring code up to speed with the RT 4.2 API
        package RT;
    # - Turn taint back on. Seems to work after clearing out old API usage.
       
    #
        use strict;
    # * Old ChangeLog entries
        use warnings;
    # - Restructured to allow cleaner execution flow
        use Getopt::Long;
    # - Removed taint check as it does not work currently
        use Data::Dumper;
    # - Fixed an old variable not defined
        use Date::Calc qw(Today Add_Delta_Days);
    # - Changed mail format (ticket id added)
        use RT::Interface::CLI qw(CleanEnv GetMessageContent loc);
    # - Getopt added for parameters: --debug --reminder --ticket --interval and
       
    #  --help
        # Show reminders that are due between today and the day after tomorrow.
    #####
        ## Bug fixed by sean <smahan (works for) smwm.com>
    # NEW HOME: http://requesttracker.wikia.com/wiki/RtReminderMails v 2015.12
        my $CONFIG_DUE_DAYS = 2;
    #    and up
        # The mail "From" address.
    # OLD HOME: File: http://www.fing.edu.uy/~delriego/RT_Reminder.pl v 1.5
        my $CONFIG_FROM = 'rt-helpdesk@minervanetworks.com';
    #####
        # The mail "To" address if the Reminder *or* Ticket owner is Nobody.
   
        my $CONFIG_TO_NOBODY = 'blackhole@minervanetworks.com';
    package RT;
        # The mail "Subject" line.
   
        my $CONFIG_SUBJECT = 'RT Reminder';
    use strict;
       
    use warnings;
        # Send mail to REMINDER OWNER
    use Getopt::Long;
        my $ReminderOwner;
    use Date::Calc qw(Today Add_Delta_Days);
        # Send mail to TICKER OWNER
   
        my $TicketOwner;
    use RT::Interface::CLI qw(loc);
        # Only show the mails for debugging
   
        my $debug = 0;
    # Show reminders that are due between today and the day after tomorrow.
        my $interval = undef;
    ## Bug fixed by sean <smahan (works for) smwm.com>
       
    my $CONFIG_DUE_DAYS = 2;
        my $help;
    # The mail "From" address.
       
    my $CONFIG_FROM = 'EMAIL_ADDRESS@SOMEPLACE.TLD';
        sub usage {
    # The mail "To" address if the Reminder *or* Ticket owner is Nobody.
            print "rt-reminders.pl - A script to send alerts for reminders in the RT system.\n";
    my $CONFIG_TO_NOBODY = 'NO_REPLY_EMAIL_ADDRESS@SOMEPLACE.TLD';
            print "Contributed by several members of the RT community.\n";
    # The mail "Subject" line.
            print "Under the same license as RT itself.\n";
    my $CONFIG_SUBJECT = 'RT Reminder';
            print "-------------------------------------------------------------------------\n\n";
   
            print "--reminder|-r        Send mail to the reminder's owner\n";
    # Send mail to REMINDER OWNER
            print "--ticket|-t          Send mail to the ticket's owner\n";
    my $ReminderOwner;
            print "--interval|-i <int>  Days left to end time (default < $CONFIG_DUE_DAYS)\n";
    # Send mail to TICKER OWNER
            print "--debug|-d          Only show mails to send for debugging\n";
    my $TicketOwner;
            print "--help|-h            This help!\n\n";
    # Only show the mails for debugging
            exit;
    my $debug = 0;
        }
    my $interval = undef;
       
   
        sub main {
    my $help;
            unless (defined($ReminderOwner) || defined($TicketOwner)) {
    my $VERSION = '2015.12.11';
        usage();
   
            }
    sub version {
       
        print "rt-reminders.pl - A script to send alerts for reminders in the RT system.\n";
            # RT API boilerplate +++++++++++++++++
        print "Contributed by several members of the RT community.\n";
            # Clean our the environment
        print "Under the same license as RT itself.\n";
            CleanEnv();
        print "-------------------------------------------------------------------------\n\n";
            # Load the RT configuration
        print "  rt-reminders.pl version: $VERSION\n";
            RT::LoadConfig();
    }
            # Initialise RT
   
            RT::Init();
    sub usage {
       
        print "rt-reminders.pl - A script to send alerts for reminders in the RT system.\n";
            # Load rest of the RT stuff (seems to go after initialization)
        print "Contributed by several members of the RT community.\n";
            use RT::Date;
        print "Under the same license as RT itself.\n";
            use RT::Queue;
        print "-------------------------------------------------------------------------\n\n";
            use RT::Tickets;
        print "--reminder|-r        Send mail to the reminder's owner\n";
            use RT::Action::SendEmail;
        print "--ticket|-t          Send mail to the ticket's owner\n";
            # END RT API boilerplate +++++++++++++
        print "--interval|-i <int>  Days left to end time (default < $CONFIG_DUE_DAYS)\n";
       
        print "--debug|-d          Only show mails to send for debugging\n";
            if (! defined($interval)) {
        print "--help|-h            This help!\n\n";
                $interval = $CONFIG_DUE_DAYS;
        print "--version|-v        Show version information.\n";
    }
   
    sub main {
        unless (defined($ReminderOwner) || defined($TicketOwner)) {
            usage();
        }
       
        # RT API boilerplate +++++++++++++++++
        # Load the RT configuration
        RT::LoadConfig();
        # Initialise RT
        RT::Init();
       
        # Load rest of the RT stuff (seems to go after initialization)
        use RT::Date;
        use RT::Queue;
        use RT::Tickets;
        use RT::Action::SendEmail;
        # END RT API boilerplate +++++++++++++
       
        if (! defined($interval)) {
            $interval = $CONFIG_DUE_DAYS;
        }
       
        # Calculate date boundaries.
        my ($dy,$dm,$dd) = Today();
        my $d_now  = sprintf('%04d-%02d-%02d 00:00:00', $dy, $dm, $dd);
        my $d_then = sprintf('%04d-%02d-%02d 23:59:59', Add_Delta_Days($dy, $dm, $dd, $interval));
       
        # Fetch list of matching tickets.
        my $tickets = RT::Tickets->new($RT::SystemUser);
        $tickets->FromSQL(
                  'Type = "reminder" AND '.
                  '(Status = "new" OR Status = "open") AND '.
                  'Due >= "'.$d_now.'" AND '.
                  'Due <= "'.$d_then.'"');
        $tickets->OrderBy(FIELD => 'Due', ORDER => 'DESC');
       
        # Format result and group by e-mail address.
        my %rcpts = ();
        while (my $ticket = $tickets->Next) {
            my $out;
           
            # Format:
            # "Reminder: <subject_reminder> ([RT #<TicketID> <TicketSubject>])
            #      Due: <left_hour> hours"
           
            my $t = RT::Ticket->new($RT::SystemUser);
            $t->Load($ticket->RefersTo->First->LocalTarget);
           
            $out = sprintf(
                    "Reminder: %s ([RT #%s] %s )\n" .
                    "    Due: %s\n\n",
                    $ticket->Subject, $ticket->RefersTo->First->LocalTarget,
                    $t->Subject, loc($ticket->DueObj->AgeAsString));
           
            my $tmp_rcpt_reminder = undef;
            if ($ReminderOwner) {
                # Push reminder to array of distinct e-mail addresses for this ticket.
                $tmp_rcpt_reminder = $ticket->OwnerObj->EmailAddress || $CONFIG_TO_NOBODY;
                if (! defined($rcpts{$tmp_rcpt_reminder})) {
                    $rcpts{$tmp_rcpt_reminder} = ""
                }
                $rcpts{ $tmp_rcpt_reminder } .= $out;
             }
             }
       
              
             # Calculate date boundaries.
             if ($TicketOwner) {
             my ($dy,$dm,$dd) = Today();
                 # Notify ticket owner or "nobody" if ticket is unowned
            my $d_now  = sprintf('%04d-%02d-%02d 00:00:00', $dy, $dm, $dd);
                 my $tmp_rcpt_ticket  = $t->OwnerObj->EmailAddress || $CONFIG_TO_NOBODY;
            my $d_then = sprintf('%04d-%02d-%02d 23:59:59', Add_Delta_Days($dy, $dm, $dd, $interval));
                if (defined($CONFIG_TO_NOBODY) && $tmp_rcpt_ticket ne $tmp_rcpt_reminder) {
       
                     $rcpts{$tmp_rcpt_ticket} .= $out;
            # Fetch list of matching tickets.
            my $tickets = RT::Tickets->new($RT::SystemUser);
            $tickets->FromSQL(
                      'Type = "reminder" AND '.
                      '(Status = "new" OR Status = "open") AND '.
                      'Due >= "'.$d_now.'" AND '.
                      'Due <= "'.$d_then.'"');
            $tickets->OrderBy(FIELD => 'Due', ORDER => 'DESC');
       
            # Format result and group by e-mail address.
            my %rcpts = ();
            while (my $ticket = $tickets->Next) {
                my $out;
       
                 # Format:
                # "Reminder: <subject_reminder> ([RT #<TicketID> <TicketSubject>])
                #      Due: <left_hour> hours"
       
                my $t = RT::Ticket->new($RT::SystemUser);
                $t->Load($ticket->RefersTo->First->LocalTarget);
       
                $out = sprintf(
                        "Reminder: %s ([RT #%s] %s )\n" .
                        "    Due: %s\n\n",
                        $ticket->Subject, $ticket->RefersTo->First->LocalTarget,
                        $t->Subject, loc($ticket->DueObj->AgeAsString));
       
                 my $tmp_rcpt_reminder = undef;
                if ($ReminderOwner) {
                    # Push reminder to array of distinct e-mail addresses for this ticket.
                    $tmp_rcpt_reminder = $ticket->OwnerObj->EmailAddress || $CONFIG_TO_NOBODY;
                    if (! defined($rcpts{$tmp_rcpt_reminder})) {
                        $rcpts{$tmp_rcpt_reminder} = ""
                    }
                     $rcpts{ $tmp_rcpt_reminder } .= $out;
                 }
                 }
       
                if ($TicketOwner) {
                    # Notify ticket owner or "nobody" if ticket is unowned
                    my $tmp_rcpt_ticket  = $t->OwnerObj->EmailAddress || $CONFIG_TO_NOBODY;
                    if (defined($CONFIG_TO_NOBODY) && $tmp_rcpt_ticket ne $tmp_rcpt_reminder) {
                        $rcpts{$tmp_rcpt_ticket} .= $out;
            }
        }
             }
             }
       
        }
            # Iterate over each of the tickets and send the email
       
            foreach my $rcpt (keys %rcpts) {
        # Iterate over each of the tickets and send the email
                my $mail = "From: $CONFIG_FROM\n".
        foreach my $rcpt (keys %rcpts) {
                          "To: $rcpt\n".
            my $mail = "From: $CONFIG_FROM\n".
                          "Subject: $CONFIG_SUBJECT\n\n".
                      "To: $rcpt\n".
                          $rcpts{$rcpt};
                      "Subject: $CONFIG_SUBJECT\n\n".
                if ($debug) {
                      $rcpts{$rcpt};
                    print $mail . "\n";
            if ($debug) {
                } else {
                print $mail . "\n";
                    # FIXME: Is there no proper RT library for this?
            } else {
                    no warnings;
                # FIXME: Is there no proper RT library for this?
                    open(MAIL, "| $RT::SendmailPath $RT::SendmailBounceArguments $RT::SendmailArguments") or die("open  sendmail: $!");
                no warnings;
                    use warnings;
                open(MAIL, "| $RT::SendmailPath $RT::SendmailBounceArguments $RT::SendmailArguments")
                    print(MAIL $mail) or die("print sendmail: $!");
                  or die("open  sendmail: $!");
                    close(MAIL) or die("close sendmail: $!");
                use warnings;
                }
                print(MAIL $mail) or die("print sendmail: $!");
                close(MAIL) or die("close sendmail: $!");
             }
             }
        }
        }
       
    }
        GetOptions(
   
            'r|reminder' => \$ReminderOwner,
    GetOptions(
            't|ticket' => \$TicketOwner,
        'r|reminder' => \$ReminderOwner,
            'd|debug' => \$debug,
        't|ticket' => \$TicketOwner,
            'i|interval=i' => \$interval,
        'd|debug' => \$debug,
            'h|help' => sub { usage() }
        'i|interval=i' => \$interval,
        ) or usage();
        'h|help' => sub { usage(); exit 0; },
       
        'v|version' => sub { version(); exit 0; }
        # while having a main isn't required in Perl, this cleans up and organizes the flow of the code....
    ) or usage();
        main();
    main();
        </nowiki>
</code>
 
 


'''2015-01-15 danny70437'''
'''2015-01-15 danny70437'''
Modified script to run unter debian with perl installed in /opt/perl like this:
Modified script to run unter debian with perl installed in /opt/perl like this:
  <nowiki>
 
      #/!/opt/perl/bin/perl
  <code>   #/!/opt/perl/bin/perl
      use lib "/opt/rt4/lib";
    use lib "/opt/rt4/lib";
      ...
    ...
      open(MAIL,  
    open(MAIL,  
         "| $RT::SendmailPath $RT::SendmailBounceArguments $RT::SendmailArguments -- $rcpt")  
         "| $RT::SendmailPath $RT::SendmailBounceArguments $RT::SendmailArguments -- $rcpt")  
        or die("open  sendmail: $!");
            or die("open  sendmail: $!");
    </nowiki>
</code>

Latest revision as of 16:36, 6 April 2016

This is a small cron script that sends daily emails about reminders that will be due in the next 48h to the owner of the original ticket as well as the owner of the reminder.

Note - it requires the Date::Calc and Getopt::Long perl modules.


   #!/usr/bin/perl
   #
   # This script outputs all reminders that are due within a configurable period
   # of time and mails the result to the corresponding owners.
   #####
   # Original Author: FING - UdelaR
   # Modified: christian 
   # Modified: Mario A. del Riego 
   # Modified: Gary Greene 
   #####
   # * 2015.12.11 - Gary Greene 
   # - Turn taint back OFF. RT::I18N still causes perl to complain about insecure dependencies.
   #
   # * 2015.12 - Gary Greene 
   # - Bring code up to speed with the RT 4.2 API
   # - Turn taint back on. Seems to work after clearing out old API usage.
   #
   # * Old ChangeLog entries
   # - Restructured to allow cleaner execution flow
   # - Removed taint check as it does not work currently
   # - Fixed an old variable not defined
   # - Changed mail format (ticket id added)
   # - Getopt added for parameters: --debug --reminder --ticket --interval and
   #   --help
   #####
   # NEW HOME: http://requesttracker.wikia.com/wiki/RtReminderMails v 2015.12
   #    and up
   # OLD HOME: File: http://www.fing.edu.uy/~delriego/RT_Reminder.pl v 1.5
   #####
   
   package RT;
   
   use strict;
   use warnings;
   use Getopt::Long;
   use Date::Calc qw(Today Add_Delta_Days);
   
   use RT::Interface::CLI qw(loc);
   
   # Show reminders that are due between today and the day after tomorrow.
   ## Bug fixed by sean 
   my $CONFIG_DUE_DAYS = 2;
   # The mail "From" address.
   my $CONFIG_FROM = 'EMAIL_ADDRESS@SOMEPLACE.TLD';
   # The mail "To" address if the Reminder *or* Ticket owner is Nobody.
   my $CONFIG_TO_NOBODY = 'NO_REPLY_EMAIL_ADDRESS@SOMEPLACE.TLD';
   # The mail "Subject" line.
   my $CONFIG_SUBJECT = 'RT Reminder';
   
   # Send mail to REMINDER OWNER
   my $ReminderOwner;
   # Send mail to TICKER OWNER
   my $TicketOwner;
   # Only show the mails for debugging
   my $debug = 0;
   my $interval = undef;
   
   my $help;
   my $VERSION = '2015.12.11';
   
   sub version {
       print "rt-reminders.pl - A script to send alerts for reminders in the RT system.\n";
       print "Contributed by several members of the RT community.\n";
       print "Under the same license as RT itself.\n";
       print "-------------------------------------------------------------------------\n\n";
       print "  rt-reminders.pl version: $VERSION\n";
   }
   
   sub usage {
       print "rt-reminders.pl - A script to send alerts for reminders in the RT system.\n";
       print "Contributed by several members of the RT community.\n";
       print "Under the same license as RT itself.\n";
       print "-------------------------------------------------------------------------\n\n";
       print "--reminder|-r        Send mail to the reminder's owner\n";
       print "--ticket|-t          Send mail to the ticket's owner\n";
       print "--interval|-i   Days left to end time (default < $CONFIG_DUE_DAYS)\n";
       print "--debug|-d           Only show mails to send for debugging\n";
       print "--help|-h            This help!\n\n";
       print "--version|-v         Show version information.\n";
   }
   
   sub main {
       unless (defined($ReminderOwner) || defined($TicketOwner)) {
           usage();
       }
       
       # RT API boilerplate +++++++++++++++++
       # Load the RT configuration
       RT::LoadConfig();
       # Initialise RT
       RT::Init();
       
       # Load rest of the RT stuff (seems to go after initialization)
       use RT::Date;
       use RT::Queue;
       use RT::Tickets;
       use RT::Action::SendEmail;
       # END RT API boilerplate +++++++++++++
       
       if (! defined($interval)) {
           $interval = $CONFIG_DUE_DAYS;
       }
       
       # Calculate date boundaries.
       my ($dy,$dm,$dd) = Today();
       my $d_now  = sprintf('%04d-%02d-%02d 00:00:00', $dy, $dm, $dd);
       my $d_then = sprintf('%04d-%02d-%02d 23:59:59', Add_Delta_Days($dy, $dm, $dd, $interval));
       
       # Fetch list of matching tickets.
       my $tickets = RT::Tickets->new($RT::SystemUser);
       $tickets->FromSQL(
                  'Type = "reminder" AND '.
                  '(Status = "new" OR Status = "open") AND '.
                  'Due >= "'.$d_now.'" AND '.
                  'Due <= "'.$d_then.'"');
       $tickets->OrderBy(FIELD => 'Due', ORDER => 'DESC');
       
       # Format result and group by e-mail address.
       my %rcpts = ();
       while (my $ticket = $tickets->Next) {
           my $out;
           
           # Format:
           # "Reminder:  ([RT # ])
           #       Due:  hours"
           
           my $t = RT::Ticket->new($RT::SystemUser);
           $t->Load($ticket->RefersTo->First->LocalTarget);
           
           $out = sprintf(
                   "Reminder: %s ([RT #%s] %s )\n" .
                   "     Due: %s\n\n",
                   $ticket->Subject, $ticket->RefersTo->First->LocalTarget,
                   $t->Subject, loc($ticket->DueObj->AgeAsString));
           
           my $tmp_rcpt_reminder = undef;
           if ($ReminderOwner) {
               # Push reminder to array of distinct e-mail addresses for this ticket.
               $tmp_rcpt_reminder = $ticket->OwnerObj->EmailAddress || $CONFIG_TO_NOBODY;
               if (! defined($rcpts{$tmp_rcpt_reminder})) {
                   $rcpts{$tmp_rcpt_reminder} = ""
               }
               $rcpts{ $tmp_rcpt_reminder } .= $out;
           }
           
           if ($TicketOwner) {
               # Notify ticket owner or "nobody" if ticket is unowned
               my $tmp_rcpt_ticket   = $t->OwnerObj->EmailAddress || $CONFIG_TO_NOBODY;
               if (defined($CONFIG_TO_NOBODY) && $tmp_rcpt_ticket ne $tmp_rcpt_reminder) {
                   $rcpts{$tmp_rcpt_ticket} .= $out;
               }
           }
       }
       
       # Iterate over each of the tickets and send the email
       foreach my $rcpt (keys %rcpts) {
           my $mail = "From: $CONFIG_FROM\n".
                      "To: $rcpt\n".
                      "Subject: $CONFIG_SUBJECT\n\n".
                      $rcpts{$rcpt};
           if ($debug) {
               print $mail . "\n";
           } else {
               # FIXME: Is there no proper RT library for this?
               no warnings;
               open(MAIL, "| $RT::SendmailPath $RT::SendmailBounceArguments $RT::SendmailArguments")
                 or die("open  sendmail: $!");
               use warnings;
               print(MAIL $mail) or die("print sendmail: $!");
               close(MAIL) or die("close sendmail: $!");
           }
       }
   }
   
   GetOptions(
       'r|reminder' => \$ReminderOwner,
       't|ticket' => \$TicketOwner,
       'd|debug' => \$debug,
       'i|interval=i' => \$interval,
       'h|help' => sub { usage(); exit 0; },
       'v|version' => sub { version(); exit 0; }
   ) or usage();
   main();


2015-01-15 danny70437 Modified script to run unter debian with perl installed in /opt/perl like this:

   #/!/opt/perl/bin/perl
   use lib "/opt/rt4/lib";
   ...
   open(MAIL, 
       "| $RT::SendmailPath $RT::SendmailBounceArguments $RT::SendmailArguments -- $rcpt") 
           or die("open  sendmail: $!");