Rt-askForFeedback
Jump to navigation
Jump to search
Installation
1. Create a Global "Custom Field" with the Name: "Reminder4Stalled".
2. Place this script somewhere on a server:
#!/usr/bin/perl -w # This Script bases on: # http://requesttracker.wikia.com/wiki/RtUnifiedreminder ############################################### ### Author: Pascal Wagenhofer / Q-X GmbH, Switzerland ### Email: wagenhofer@q-x.ch ### Date: 07/15/2013 ############################################### ### This script is provided "as it is" and comes without any warranty. Use it, modify ### it or do whatever you want with it. ############################################### ### Feedback is always welcome at wagenhofer@q-x.ch ############################################### ### INSTALLATION ### ### Read http://requesttracker.wikia.com/wiki/Rt-askForFeedback # RT3 reminder script # One big reminder report about ALL tickets that are getting to be too long since LastUpdated # Sends multipart HTML + plaintext email, so HTML capable mail readers can click links # Many pieces cannibalized from the other reminder scripts in the wiki. # You will run this script from cron as a user with perms to read the RT_SiteConfig.pm config file # Crontab would look like this to run twice a day, at 10:15am and 3:15pm ## send unified remind email twice per day #15 10 * * * /home/crystalfontz/scripts/rt_reminder2cust.pl # This Script bases on: # http://requesttracker.wikia.com/wiki/RtUnifiedreminder ### Configuration # Location of RT3's libs -- Change this to where yours are use lib ("/usr/share/request-tracker3.8/lib", "/usr/local/share/request-tracker3.8/lib", "/usr/local/rt/lib"); # Address emails should originate from my($from) = 'Ticket Sys <your@mail.ticketsys.com>'; # maximum number of seconds since LastUpdated, beyond which the ticket will be reported my %max_untouched_ages = ( "stalled" => 60 * 60 * 24 * 3, # 3 days before warn about stalled "2beclosed" => 60 * 60 * 24 * 3, # 3 days before warn about stalled ); # Queues to operate on. Default is all # my @goodqueues = qw[ThisQueue ThatQueue]; # to look only in specific queues, uncomment this line and comment the next one my @goodqueues = (); # leave like this to look in all queues # Queues to skip. Default is none. Use either @goodqueues or @badqueues, not both. # my @badqueues = qw[ ]; # If you have no queues to exclude, uncomment this line and comment the next one #my @badqueues = qw[Ignoreme IgnoreAnother]; # To exclude certain queues, list them here and comment line above my($debug) = 0; # nonzero will print plaintext report to STOUT instead of emailing it # The length at which lines for plaintext mail will be truncated. 78, or thereabouts looks # best for most people. Setting to 0 will stop lines being truncated. my($linelen) = 78; # has no effect on HTML mail #Enter here the path/url for the REST-API of Request Tracker my($apiurl) = "https://your.url.tld/rt3/REST/1.0/"; my($username) = "username"; #Username to access RT3 (needs to have rights to update CF in the appropriate Queue(s) my($password) = "password"; #Password of the above username my($agentname) = "Your LWP::Agent-Name"; #Mail-Section my $plainbody = "your Body of the E-Mail (Plaintext)"; my $subjectline = "Your subject of the e-mail to the customer"; #Example: "[TicketSys #$ticketNumber] $subject" ### Code use strict; use Carp; use MIME::Lite; use URI::Escape; use LWP; # Pull in the RT stuff package RT; use RT::Interface::CLI qw(CleanEnv GetCurrentUser GetMessageContent loc); CleanEnv(); # Clean our the environment RT::LoadConfig(); # Load the RT configuration RT::Init(); # Initialise RT use RT::Date; use RT::Queue; use RT::Queues; use RT::Tickets; my $max_age = 0; my $user = new RT::User($RT::SystemUser); # Define an RT User variable my $tickets = new RT::Tickets($RT::SystemUser); # Used to store Ticket search results my $date = new RT::Date($RT::SystemUser); # Define a date variable (used for comparisions) my $now = new RT::Date($RT::SystemUser); # get current time $now->SetToNow(); # Limit the ticket search to new and open only. $tickets->LimitCustomField( CUSTOMFIELD => 'Reminder4Stalled', OPERATOR => '!=', VALUE => '1' ); $tickets->LimitStatus(VALUE => 'stalled'); my $searchqueue = ; if($#goodqueues != -1) { $tickets->_OpenParen(); foreach my $queue (@goodqueues) { $tickets->LimitQueue(VALUE => $queue, OPERATOR => '='); } $tickets->_CloseParen(); $searchqueue = " AND (Queue = '". join("' OR Queue = '", @goodqueues) ."')"; } elsif($#badqueues != -1) { foreach my $queue (@badqueues) { $tickets->LimitQueue(VALUE => $queue, OPERATOR => '!='); } $searchqueue = " AND Queue != '". join("' AND Queue != '", @badqueues) ."'"; } $tickets->OrderByCols( {FIELD => 'Status', ORDER => 'ASC'}, {FIELD => 'queue', ORDER => 'ASC'}, {FIELD => 'Priority', ORDER => 'DESC'}, {FIELD => 'LastUpdated', ORDER => 'ASC'}, ); # We might not want to print the message if there are no tickets my($printmsg) = 0; my $j = 0; my $bgcolor = ; my $last_status = ; my $status_title = ; my $count_by_status = 0; my $searchURL = ; # Loop through tickets for reminder while (my $Ticket = $tickets->Next) { # Compare Dates to see if LastUpdated date is old enough to report $max_age = $max_untouched_ages{$Ticket->Status} || 0; my $max_age_2resolve = $max_untouched_ages{'2beclosed'} || 0; $date->Set(Format => "ISO", Value => $Ticket->LastUpdated); if ($now->Unix - $date->Unix < $max_age) { next; } # skip it if too young $j++; $user->Load($Ticket->Owner); use LWP; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->agent($agentname); my $uri = $apiurl; my $access_user = $username; my $access_password = $password; my $ticketNumber = $Ticket->{values}->{'id'}; my @customermail = ""; my $response = $ua->post($uri."ticket/$ticketNumber/edit", ['user' => $access_user, 'pass' => $access_password, 'content' => 'CF.{Reminder4Stalled}: 1']); if ($response->is_success) { if($Ticket->Status ne $last_status) { $last_status = $Ticket->Status; $count_by_status = 0; # reset on every difft status # get a date object that can give us the datetime cutoff for this query $date->SetToNow(); } # Use our own date formatting routine my($updated) = &formatDate($Ticket->LastUpdatedObj->Unix); my($subject) = $Ticket->Subject ? $Ticket->Subject : "(No subject)"; my($queue) = substr($Ticket->QueueObj->Name, 0, 7); my($line) = sprintf "%5d %-7s %3d %-13s %-7s %-6s %-30s", $Ticket->Id, $Ticket->Status, $Ticket->Priority, $updated, $queue, $user->Name, $subject; # Truncate lines if required if($linelen) { $line = substr($line, 0, $linelen); } # ---- GET ALL REQUESTORS my $response = $ua->post($uri."ticket/$ticketNumber", ['user' => $access_user, 'pass' => $access_password]); if ($response->is_success) { my $html = $response->decoded_content; my @array1=split(/\n/,$html); my @array2=split(/Requestors: (.*)/,$array1[11]); if ($#array2 > 1) { @customermail=split(m/\ (.*)/,$array2[1]); } else { @customermail=$array2[1]; } # ----- END GET ALL REQUESTORS my $receiviers = ""; my $sendto = $array2[1]; my $subjecttot = $subjectline; my $msg = MIME::Lite->new(From => $from, To => join(',', $sendto), Subject => $subjecttot, Type => 'text/plain', Charset => 'utf8', Data => $plainbody); if ($debug) { print "Would send E-Mail for Ticket #".$ticketNumber."\n"; } else { $msg->send; } } } } $tickets = new RT::Tickets($RT::SystemUser); # Used to store Ticket search results $tickets->LimitCustomField( CUSTOMFIELD => 'Reminder4Stalled', OPERATOR => '=', VALUE => '1' ); $searchqueue = ; if($#goodqueues != -1) { $tickets->_OpenParen(); foreach my $queue (@goodqueues) { $tickets->LimitQueue(VALUE => $queue, OPERATOR => '='); } $tickets->_CloseParen(); $searchqueue = " AND (Queue = '". join("' OR Queue = '", @goodqueues) ."')"; } elsif($#badqueues != -1) { foreach my $queue (@badqueues) { $tickets->LimitQueue(VALUE => $queue, OPERATOR => '!='); } $searchqueue = " AND Queue != '". join("' AND Queue != '", @badqueues) ."'"; } $tickets->OrderByCols( {FIELD => 'Status', ORDER => 'ASC'}, {FIELD => 'queue', ORDER => 'ASC'}, {FIELD => 'Priority', ORDER => 'DESC'}, {FIELD => 'LastUpdated', ORDER => 'ASC'}, ); # We might not want to print the message if there are no tickets ($printmsg) = 0; $j = 0; $bgcolor = ; $last_status = ; $status_title = ; $count_by_status = 0; $searchURL = ; # Loop through tickets to close while (my $Ticket = $tickets->Next) { # Compare Dates to see if LastUpdated date is old enough to report $max_age = $max_untouched_ages{$Ticket->Status} || 0; my $max_age_2resolve = $max_untouched_ages{'2beclosed'} || 0; $date->Set(Format => "ISO", Value => $Ticket->LastUpdated); if ($now->Unix - $date->Unix < $max_age_2resolve) { next; } # skip it if too young $j++; $user->Load($Ticket->Owner); if($Ticket->Status ne $last_status) { $last_status = $Ticket->Status; $count_by_status = 0; # reset on every difft status # get a date object that can give us the datetime cutoff for this query $date->SetToNow(); } # Use our own date formatting routine my ($updated) = &formatDate($Ticket->LastUpdatedObj->Unix); my ($subject) = $Ticket->Subject ? $Ticket->Subject : "(No subject)"; my ($queue) = substr($Ticket->QueueObj->Name, 0, 7); my ($line) = sprintf "%5d %-7s %3d %-13s %-7s %-6s %-30s", $Ticket->Id, $Ticket->Status, $Ticket->Priority, $updated, $queue, $user->Name, $subject; if ($debug) { print "Would close Ticket ".$Ticket->Id."\n\n"; } else { $Ticket->Resolve(); } } # Disconnect before we finish off $RT::Handle->Disconnect(); exit 0; # Formats a date like: Thu 10-07-03 # Designed to be consice yet useful sub formatDate() { my($unixtime) = @_; my(@days) = ( "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ); # Return an empty string if we haven't been given a time return "" if $unixtime <= 0; my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($unixtime); return sprintf "%s %02d-%02d-%02d", $days[$wday], $mon+1, $mday, $year%100; }
3. install a Cronjob on your server (see script head)
4. Now, we need to setup a new Scrip to reset the "Reminder4Stalled"-Field in case of Correspondance. Create a new Scrip in the Global-Section which looks like this:
Description: "Set Reminder4Stalled = 0"
Condition: "On Correspondance"
Action: "User defined"
Template: "Global Template: empty"
Phase: "TransactionCreate"
User Defined Condition:
return 1;
User Defined Action Preparation Code:
my $ticket = $self->TicketObj; my $cf_obj = RT::CustomField->new($RT::SystemUser); my $cf_name = "Reminder4Stalled"; my $cf_value = "0"; $cf_obj->LoadByName( Name => $cf_name ); $RT::Logger->debug( "Loaded \$cf_obj->Name = ". $cf_obj->Name() ."\n" ); $ticket->AddCustomFieldValue( Field=>$cf_obj, Value=>$cf_value, RecordTransaction=>0 );
User Defined Post Action Code:
return 1;