AddWatchersOnCorrespond

From Request Tracker Wiki
Revision as of 12:08, 3 February 2014 by 78.31.25.129 (talk) (fixed to work with RT4.2.2)
Jump to navigation Jump to search

AddWatchersOnCorrespond

This RT Scrip will add the person making the correspondence as a Watcher to the ticket if they are not already a Watcher, also, if the transaction originated from an email message, the script will scan the email headers and add all other recipients to the ticket as Watchers (if they are not yet Watchers). This can be used to complement the ParseNewMessageForTicketCcs SiteConfig option, which is part of the EmailInterface and does the same thing when tickets are created.

In our RT setup, we have a group named general which contains all admins for our site. If the user this Scrip is going to add as a Watcher to the ticket is also a member of the general group, then the Scrip will add them as an AdminCC Watcher instead of a CC Watcher. It should be fairly easy for others who do not need this feature to remove or modify this Scrip accordingly.

I wrote this Scrip to replace the patch we used to make to the RT Email Interface code, called ParseFollowupMessageForTicketCcs. Accordingly, it carries the same security warning about allowing basically anyone to add themselves to any ticket, simply by sending an appropriately formatted email. Some RT sites might not want this behavior, but it is necessary for us.

Changelog

2012-01-01: Fixed a bug in which the owner of the ticket would have been added as a Cc: for every reply he made. (HaimDimer)


Description: AddWatchersOnCorrespond

Condition: On Correspond

Action: User Defined

Template: Global template: Blank

Stage: TransactionBatch

Custom condition:

Custom action preparation code: return 1;

Custom action cleanup code:


# Get some info:
my $scrip = 'Scrip:AddWatchersOnCorrespond';
my $Transaction = $self->TransactionObj;
my $EmailAddr = $self->TransactionObj->CreatorObj->EmailAddress;
my $Queue = $self->TicketObj->QueueObj;
my $Ticket = $self->TicketObj;
my $Id = $self->TicketObj->id;

# Extract a list of people associated with this transaction:
#  - including the transaction creator, and if it is an email, the sender and recipients of that email message.
my @People = ($EmailAddr);
foreach my $h (qw(From To Cc)) {
    my $header = $Transaction->Attachments->First->GetHeader($h);
    my @addr = Mail::Address->parse($header);
    foreach my $addrobj (@addr) {
	my $addr = lc $RT::Nobody->UserObj->CanonicalizeEmailAddress($addrobj->address);
	# Ignore the specific addresses for this queue:
	next if lc $Queue->CorrespondAddress eq $addr;
	next if lc $Queue->CommentAddress eq $addr;
	# Ignore any email address that looks like one for ANY of our queues:
	next if RT::EmailParser->IsRTAddress($addr);
	$RT::Logger->debug("$scrip: Ticket #$Id correspondence contains header - $h: $addr");
	push @People, $addr;
    }
}

# Lookup the 'experts' (general) group to use below:
my $Experts = RT::Group->new($self->CurrentUser);
$Experts->LoadUserDefinedGroup('general');

# Now check if each user is already watching the ticket or queue:
foreach my $addr (@People) {
    my $User = RT::User->new($RT::SystemUser);
    $User->LoadOrCreateByEmail($addr);
    my $Name = $User->Name;
    my $Principal = $User->PrincipalId;
    if ( not ($Queue->IsWatcher(Type => 'Cc', PrincipalId => $Principal) or
	    $Queue->IsWatcher(Type => 'AdminCc', PrincipalId => $Principal) or
	    $Ticket->IsWatcher(Type => 'Cc', PrincipalId => $Principal) or
	    $Ticket->IsWatcher(Type => 'AdminCc', PrincipalId => $Principal) or
	    $Ticket->IsWatcher(Type => 'Requestor', PrincipalId => $Principal) or
	    $Ticket->IsOwner($User) )) {
	# If the user is a member of the experts group, then add them as an AdminCc, otherwise as a normal Cc:
	my $type = 'Cc';
	$type = 'AdminCc' if $Experts->HasMember($User->PrincipalObj);
	# Add the new watcher now and check for errors:
	my ($ret, $msg) = $Ticket->AddWatcher(Type  => $type, PrincipalId => $Principal);
	if ($ret) {
	    $RT::Logger->info("$scrip: New $type watcher added to ticket #$Id: $addr (#$Principal)");
	} else {
	    $RT::Logger->error("$scrip: Failed to add new $type watcher to ticket #$Id: $addr (#$Principal) - $msg");
	}
    }
}

return 1;

# vim:ft=perl: