AddWatchersOnCorrespond: Difference between revisions
m (add category) |
(BUGFIX: add CreatorEmailAddr as lower case. Check for bounce addresses lower case.) |
||
Line 14: | Line 14: | ||
2022-12-06: Populate RealName from email header when creating new user. (RT inserts the user's email address in the "phrase" part of the From: header if RealName is empty. This fix prevents emails bouncing because a mail provider's anti-spoofing policy rejects mail with an email address in the "phrase" section of From:/Cc: headers. ) | 2022-12-06: Populate RealName from email header when creating new user. (RT inserts the user's email address in the "phrase" part of the From: header if RealName is empty. This fix prevents emails bouncing because a mail provider's anti-spoofing policy rejects mail with an email address in the "phrase" section of From:/Cc: headers. ) | ||
2023-05-03: (RobL) BUGFIX: add CreatorEmailAddr as lower case. Check for bounce addresses lower case. | |||
---- | ---- | ||
Line 46: | Line 48: | ||
# - including the transaction creator, and if it is an email, the sender and recipients of that email | # - including the transaction creator, and if it is an email, the sender and recipients of that email | ||
my %People; | my %People; | ||
my $CreatorEmailAddr = $self->TransactionObj->CreatorObj->EmailAddress; | my $CreatorEmailAddr = lc $self->TransactionObj->CreatorObj->EmailAddress; | ||
my $CreatorRealName = $self->TransactionObj->CreatorObj->RealName; | my $CreatorRealName = $self->TransactionObj->CreatorObj->RealName; | ||
$People{$CreatorEmailAddr}{RealName} = GetFullName($CreatorEmailAddr,$CreatorRealName); | $People{$CreatorEmailAddr}{RealName} = GetFullName($CreatorEmailAddr,$CreatorRealName); | ||
Line 76: | Line 78: | ||
foreach my $addr (sort keys %People) { | foreach my $addr (sort keys %People) { | ||
next if ($addr =~ /^(postmaster|root| | next if ($addr =~ /^(postmaster|root|mailer-daemon)\@/); | ||
my $User = RT::User->new( $RT::SystemUser ); | my $User = RT::User->new( $RT::SystemUser ); |
Latest revision as of 06:47, 3 May 2023
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 behaviour, but it is necessary for us.
- AddWatchersOnCorrespondDomains is a modified version of this Scrip which is more restrictive by domain.
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)
2022-12-06: Populate RealName from email header when creating new user. (RT inserts the user's email address in the "phrase" part of the From: header if RealName is empty. This fix prevents emails bouncing because a mail provider's anti-spoofing policy rejects mail with an email address in the "phrase" section of From:/Cc: headers. )
2023-05-03: (RobL) BUGFIX: add CreatorEmailAddr as lower case. Check for bounce addresses lower case.
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 my %People; my $CreatorEmailAddr = lc $self->TransactionObj->CreatorObj->EmailAddress; my $CreatorRealName = $self->TransactionObj->CreatorObj->RealName; $People{$CreatorEmailAddr}{RealName} = GetFullName($CreatorEmailAddr,$CreatorRealName); 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); # Get phrase from address header for full name: "Fred Bloggs" <fred@example.com> # (Extract Fred Bloggs to fullname.) Clean up. If nothing suitable then make something from email. my $fullname = GetFullName($addr,$addrobj->phrase); $People{$addr}{RealName} = $fullname; $RT::Logger->debug("$scrip: Ticket #$Id correspondence contains header - $h: $addr $fullname"); } } # 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 (sort keys %People) { next if ($addr =~ /^(postmaster|root|mailer-daemon)\@/); my $User = RT::User->new( $RT::SystemUser ); $User->LoadOrCreateByEmail( RealName => $People{$addr}{RealName}, EmailAddress => $addr, Comments => "Autocreated by $scrip", ); 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 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 $fullname (#$Principal)"); } else { $RT::Logger->error("$scrip: Failed to add new $type watcher to ticket #$Id: $addr (#$Principal) - $msg"); } } } sub GetFullName { # Get a nicely formatted name for RT RealName Field: # If fullname is blank, make something up from the # local_part of the email address: "fred.bloggs@..." -> "Fred Bloggs". # Do not allow fullname to contain "@". my ($addr,$fullname) = @_; my ($local_part,$domain) = split('@', $addr); if (($fullname eq '') || ($fullname =~ /\@/)) { $fullname = $local_part; $fullname =~ s/[\._-]/ /g; $fullname =~ s/(\w+)/\u$1/g; } $fullname =~ s/^[\"\']|[\"\']$//g; # strip leading/trailing " or ' $fullname =~ s/^\s+|\s+$//g; # strip leading/trailing spaces return $fullname; } return 1;
# vim:ft=perl: