init III
This commit is contained in:
157
Perl OTRS/Kernel/System/PostMaster/DestQueue.pm
Normal file
157
Perl OTRS/Kernel/System/PostMaster/DestQueue.pm
Normal file
@@ -0,0 +1,157 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::DestQueue;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::Queue',
|
||||
'Kernel::System::SystemAddress',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
# get parser object
|
||||
$Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject!";
|
||||
|
||||
# Get communication log object.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub GetQueueID {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# get email headers
|
||||
my %GetParam = %{ $Param{Params} };
|
||||
|
||||
# check possible to, cc and resent-to emailaddresses
|
||||
my $Recipient = '';
|
||||
RECIPIENT:
|
||||
for my $Key (qw(Resent-To Envelope-To To Cc Delivered-To X-Original-To)) {
|
||||
|
||||
next RECIPIENT if !$GetParam{$Key};
|
||||
|
||||
if ($Recipient) {
|
||||
$Recipient .= ', ';
|
||||
}
|
||||
|
||||
$Recipient .= $GetParam{$Key};
|
||||
}
|
||||
|
||||
# get system address object
|
||||
my $SystemAddressObject = $Kernel::OM->Get('Kernel::System::SystemAddress');
|
||||
|
||||
# get addresses
|
||||
my @EmailAddresses = $Self->{ParserObject}->SplitAddressLine( Line => $Recipient );
|
||||
|
||||
# check addresses
|
||||
EMAIL:
|
||||
for my $Email (@EmailAddresses) {
|
||||
|
||||
next EMAIL if !$Email;
|
||||
|
||||
my $Address = $Self->{ParserObject}->GetEmailAddress( Email => $Email );
|
||||
|
||||
next EMAIL if !$Address;
|
||||
|
||||
# lookup queue id if recipiend address
|
||||
my $QueueID = $SystemAddressObject->SystemAddressQueueID(
|
||||
Address => $Address,
|
||||
);
|
||||
|
||||
if ($QueueID) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => ref($Self),
|
||||
Value => "Match email: $Email to QueueID $QueueID (MessageID:$GetParam{'Message-ID'})!",
|
||||
);
|
||||
|
||||
return $QueueID;
|
||||
}
|
||||
|
||||
# Address/Email not matched with any that is configured in the system
|
||||
# or any error occured while checking it.
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => ref($Self),
|
||||
Value => "No match for email: $Email (MessageID:$GetParam{'Message-ID'})!",
|
||||
);
|
||||
}
|
||||
|
||||
# If we get here means that none of the addresses in the message is defined as a system address
|
||||
# or an error occured while checking it.
|
||||
|
||||
my $Queue = $Kernel::OM->Get('Kernel::Config')->Get('PostmasterDefaultQueue');
|
||||
my $QueueID = $Kernel::OM->Get('Kernel::System::Queue')->QueueLookup(
|
||||
Queue => $Queue,
|
||||
);
|
||||
|
||||
if ($QueueID) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => ref($Self),
|
||||
Value => "MessageID:$GetParam{'Message-ID'} to 'PostmasterDefaultQueue' ( QueueID:${QueueID} ).",
|
||||
);
|
||||
|
||||
return $QueueID;
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => ref($Self),
|
||||
Value => "Couldn't get QueueID for 'PostmasterDefaultQueue' (${Queue}) !",
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => ref($Self),
|
||||
Value => "MessageID:$GetParam{'Message-ID'} to QueueID:1!",
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub GetTrustedQueueID {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# get email headers
|
||||
my %GetParam = %{ $Param{Params} };
|
||||
|
||||
return if !$GetParam{'X-OTRS-Queue'};
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::DestQueue',
|
||||
Value => "Existing X-OTRS-Queue header: $GetParam{'X-OTRS-Queue'} (MessageID:$GetParam{'Message-ID'})!",
|
||||
);
|
||||
|
||||
# get dest queue
|
||||
return $Kernel::OM->Get('Kernel::System::Queue')->QueueLookup(
|
||||
Queue => $GetParam{'X-OTRS-Queue'},
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
246
Perl OTRS/Kernel/System/PostMaster/Filter.pm
Normal file
246
Perl OTRS/Kernel/System/PostMaster/Filter.pm
Normal file
@@ -0,0 +1,246 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::Filter;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::System::DB',
|
||||
'Kernel::System::Log',
|
||||
);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Kernel::System::PostMaster::Filter
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
All postmaster database filters
|
||||
|
||||
=head1 PUBLIC INTERFACE
|
||||
|
||||
=head2 new()
|
||||
|
||||
Don't use the constructor directly, use the ObjectManager instead:
|
||||
|
||||
my $PMFilterObject = $Kernel::OM->Get('Kernel::System::PostMaster::Filter');
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
=head2 FilterList()
|
||||
|
||||
get all filter
|
||||
|
||||
my %FilterList = $PMFilterObject->FilterList();
|
||||
|
||||
=cut
|
||||
|
||||
sub FilterList {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# get database object
|
||||
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
||||
|
||||
return if !$DBObject->Prepare(
|
||||
SQL => 'SELECT f_name FROM postmaster_filter',
|
||||
);
|
||||
|
||||
my %Data;
|
||||
while ( my @Row = $DBObject->FetchrowArray() ) {
|
||||
$Data{ $Row[0] } = $Row[0];
|
||||
}
|
||||
|
||||
return %Data;
|
||||
}
|
||||
|
||||
=head2 FilterAdd()
|
||||
|
||||
add a filter
|
||||
|
||||
$PMFilterObject->FilterAdd(
|
||||
Name => 'some name',
|
||||
StopAfterMatch => 0,
|
||||
Match = [
|
||||
{
|
||||
Key => 'Subject',
|
||||
Value => '^ADV: 123',
|
||||
},
|
||||
...
|
||||
],
|
||||
Not = [
|
||||
{
|
||||
Key => 'Subject',
|
||||
Value => '1',
|
||||
},
|
||||
...
|
||||
],
|
||||
Set = [
|
||||
{
|
||||
Key => 'X-OTRS-Queue',
|
||||
Value => 'Some::Queue',
|
||||
},
|
||||
...
|
||||
],
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub FilterAdd {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for (qw(Name StopAfterMatch Match Set)) {
|
||||
if ( !defined $Param{$_} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $_!"
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# get database object
|
||||
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
||||
|
||||
my @Not = @{ $Param{Not} || [] };
|
||||
|
||||
for my $Type (qw(Match Set)) {
|
||||
|
||||
my @Data = @{ $Param{$Type} };
|
||||
|
||||
for my $Index ( 0 .. ( scalar @Data ) - 1 ) {
|
||||
|
||||
return if !$DBObject->Do(
|
||||
SQL =>
|
||||
'INSERT INTO postmaster_filter (f_name, f_stop, f_type, f_key, f_value, f_not)'
|
||||
. ' VALUES (?, ?, ?, ?, ?, ?)',
|
||||
Bind => [
|
||||
\$Param{Name}, \$Param{StopAfterMatch}, \$Type,
|
||||
\$Data[$Index]->{Key}, \$Data[$Index]->{Value}, \$Not[$Index]->{Value},
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 FilterDelete()
|
||||
|
||||
delete a filter
|
||||
|
||||
$PMFilterObject->FilterDelete(
|
||||
Name => '123',
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub FilterDelete {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for (qw(Name)) {
|
||||
if ( !defined $Param{$_} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $_!"
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# get database object
|
||||
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
||||
|
||||
return if !$DBObject->Do(
|
||||
SQL => 'DELETE FROM postmaster_filter WHERE f_name = ?',
|
||||
Bind => [ \$Param{Name} ],
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 FilterGet()
|
||||
|
||||
get filter properties, returns HASH ref Match and Set
|
||||
|
||||
my %Data = $PMFilterObject->FilterGet(
|
||||
Name => '132',
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub FilterGet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for (qw(Name)) {
|
||||
if ( !defined $Param{$_} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $_!"
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# get database object
|
||||
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
||||
|
||||
return if !$DBObject->Prepare(
|
||||
SQL =>
|
||||
'SELECT f_type, f_key, f_value, f_name, f_stop, f_not'
|
||||
. ' FROM postmaster_filter'
|
||||
. ' WHERE f_name = ?'
|
||||
. ' ORDER BY f_key, f_value',
|
||||
Bind => [ \$Param{Name} ],
|
||||
);
|
||||
|
||||
my %Data;
|
||||
while ( my @Row = $DBObject->FetchrowArray() ) {
|
||||
push @{ $Data{ $Row[0] } }, {
|
||||
Key => $Row[1],
|
||||
Value => $Row[2],
|
||||
};
|
||||
$Data{Name} = $Row[3];
|
||||
$Data{StopAfterMatch} = $Row[4];
|
||||
|
||||
if ( $Row[0] eq 'Match' ) {
|
||||
push @{ $Data{Not} }, {
|
||||
Key => $Row[1],
|
||||
Value => $Row[5],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return %Data;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 TERMS AND CONDITIONS
|
||||
|
||||
This software is part of the OTRS project (L<https://otrs.org/>).
|
||||
|
||||
This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
the enclosed file COPYING for license information (GPL). If you
|
||||
did not receive this file, see L<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
108
Perl OTRS/Kernel/System/PostMaster/Filter/CMD.pm
Normal file
108
Perl OTRS/Kernel/System/PostMaster/Filter/CMD.pm
Normal file
@@ -0,0 +1,108 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::Filter::CMD;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Kernel::System::VariableCheck qw(:all);
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::Log',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
# get parser object
|
||||
$Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject!";
|
||||
|
||||
# Get communication log object.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# get config options
|
||||
my %Config;
|
||||
my @Set;
|
||||
if ( $Param{JobConfig} && ref( $Param{JobConfig} ) eq 'HASH' ) {
|
||||
%Config = %{ $Param{JobConfig} };
|
||||
|
||||
if ( IsArrayRefWithData( $Config{Set} ) ) {
|
||||
@Set = @{ $Config{Set} };
|
||||
}
|
||||
elsif ( IsHashRefWithData( $Config{Set} ) ) {
|
||||
|
||||
for my $Key ( sort keys %{ $Config{Set} } ) {
|
||||
push @Set, {
|
||||
Key => $Key,
|
||||
Value => $Config{Set}->{$Key},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# check CMD config param
|
||||
if ( !$Config{CMD} ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::CMD',
|
||||
Value => "Need CMD config option in PostMaster::PreFilterModule job!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# execute prog
|
||||
my $TmpFile = $Kernel::OM->Get('Kernel::Config')->Get('TempDir') . "/PostMaster.Filter.CMD.$$";
|
||||
|
||||
## no critic
|
||||
if ( open my $Prog, '|-', "$Config{CMD} > $TmpFile" ) {
|
||||
## use critic
|
||||
print $Prog $Self->{ParserObject}->GetPlainEmail();
|
||||
close $Prog;
|
||||
}
|
||||
|
||||
if ( -s $TmpFile ) {
|
||||
open my $In, '<', $TmpFile; ## no critic
|
||||
my $Ret = <$In>;
|
||||
close $In;
|
||||
|
||||
# set new params
|
||||
for my $SetItem (@Set) {
|
||||
my $Key = $SetItem->{Key};
|
||||
my $Value = $SetItem->{Value};
|
||||
|
||||
$Param{GetParam}->{$Key} = $Value;
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Notice',
|
||||
Key => 'Kernel::System::PostMaster::Filter::CMD',
|
||||
Value =>
|
||||
"Set param '$Key' to '$Value' because of '$Ret' (Message-ID: $Param{GetParam}->{'Message-ID'})",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
unlink $TmpFile;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
266
Perl OTRS/Kernel/System/PostMaster/Filter/Decrypt.pm
Normal file
266
Perl OTRS/Kernel/System/PostMaster/Filter/Decrypt.pm
Normal file
@@ -0,0 +1,266 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::Filter::Decrypt;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Kernel::System::EmailParser;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::Crypt::PGP',
|
||||
'Kernel::System::Crypt::SMIME',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# Allocate new hash for object.
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
# Get parser object.
|
||||
$Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject!";
|
||||
|
||||
# get communication log object and MessageID
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# Check needed stuff.
|
||||
for my $Needed (qw(JobConfig GetParam)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::Decrypt',
|
||||
Value => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Try to get message & encryption method.
|
||||
my $Message;
|
||||
my $ContentType;
|
||||
my $EncryptionMethod = '';
|
||||
|
||||
if ( $Param{GetParam}->{Body} =~ /\A[\s\n]*^-----BEGIN PGP MESSAGE-----/m ) {
|
||||
$Message = $Param{GetParam}->{Body};
|
||||
$ContentType = $Param{GetParam}->{'Content-Type'} || '';
|
||||
$EncryptionMethod = 'PGP';
|
||||
}
|
||||
elsif ( $Param{GetParam}->{'Content-Type'} =~ /application\/(x-pkcs7|pkcs7)-mime/i ) {
|
||||
$EncryptionMethod = 'SMIME';
|
||||
$ContentType = $Param{GetParam}->{'Content-Type'} || '';
|
||||
}
|
||||
else {
|
||||
CONTENT:
|
||||
for my $Content ( @{ $Param{GetParam}->{Attachment} } ) {
|
||||
if ( $Content->{Content} =~ /\A[\s\n]*^-----BEGIN PGP MESSAGE-----/m ) {
|
||||
$Message = $Content->{Content};
|
||||
$ContentType = $Content->{ContentType} || '';
|
||||
$EncryptionMethod = 'PGP';
|
||||
last CONTENT;
|
||||
}
|
||||
elsif ( $Content->{Content} =~ /^-----BEGIN PKCS7-----/ ) {
|
||||
$Message = $Content->{Content};
|
||||
$ContentType = $Param{GetParam}->{'Content-Type'} || '';
|
||||
$EncryptionMethod = 'SMIME';
|
||||
last CONTENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $EncryptionMethod eq 'PGP' ) {
|
||||
|
||||
# Try to decrypt body with PGP.
|
||||
$Param{GetParam}->{'X-OTRS-BodyDecrypted'} = $Self->_DecryptPGP(
|
||||
Body => $Message,
|
||||
ContentType => $ContentType,
|
||||
%Param
|
||||
) || '';
|
||||
|
||||
# Return PGP decrypted content if encryption is PGP.
|
||||
return $Param{GetParam}->{'X-OTRS-BodyDecrypted'} if $Param{GetParam}->{'X-OTRS-BodyDecrypted'};
|
||||
}
|
||||
elsif ( $EncryptionMethod eq 'SMIME' ) {
|
||||
|
||||
# Try to decrypt body with SMIME.
|
||||
$Param{GetParam}->{'X-OTRS-BodyDecrypted'} = $Self->_DecryptSMIME(
|
||||
Body => $Self->{ParserObject}->{Email}->as_string(),
|
||||
ContentType => $ContentType,
|
||||
%Param
|
||||
) || '';
|
||||
|
||||
# Return SMIME decrypted content if encryption is SMIME
|
||||
return $Param{GetParam}->{'X-OTRS-BodyDecrypted'} if $Param{GetParam}->{'X-OTRS-BodyDecrypted'};
|
||||
}
|
||||
else {
|
||||
$Param{GetParam}->{'X-OTRS-BodyDecrypted'} = '';
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub _DecryptPGP {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $DecryptBody = $Param{Body} || '';
|
||||
my $ContentType = $Param{ContentType} || '';
|
||||
|
||||
# Check if PGP is active
|
||||
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
||||
|
||||
if ( !$ConfigObject->Get('PGP') ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::Decrypt',
|
||||
Value => "PGP is not activated",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# Check for PGP encryption
|
||||
if (
|
||||
$DecryptBody !~ m{\A[\s\n]*^-----BEGIN PGP MESSAGE-----}i
|
||||
&& $ContentType !~ m{application/pgp}i
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
# PGP crypt object
|
||||
my $CryptObject = $Kernel::OM->Get('Kernel::System::Crypt::PGP');
|
||||
|
||||
if ( !$CryptObject ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::Decrypt',
|
||||
Value => "Not possible to create crypt object",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# Try to decrypt.
|
||||
my %Decrypt = $CryptObject->Decrypt( Message => $DecryptBody );
|
||||
|
||||
return if !$Decrypt{Successful};
|
||||
|
||||
my $ParserObject = Kernel::System::EmailParser->new( %{$Self}, Email => $Decrypt{Data} );
|
||||
$DecryptBody = $ParserObject->GetMessageBody();
|
||||
|
||||
if ( $Param{JobConfig}->{StoreDecryptedBody} ) {
|
||||
$Param{GetParam}->{Body} = $DecryptBody;
|
||||
}
|
||||
|
||||
# Return content if successful
|
||||
return $DecryptBody;
|
||||
}
|
||||
|
||||
sub _DecryptSMIME {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $DecryptBody = $Param{Body} || '';
|
||||
my $ContentType = $Param{ContentType} || '';
|
||||
|
||||
# Check if SMIME is active
|
||||
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
||||
|
||||
if ( !$ConfigObject->Get('SMIME') ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::Decrypt',
|
||||
Value => "SMIME is not activated",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# Check for SMIME encryption
|
||||
if (
|
||||
$DecryptBody !~ m{^-----BEGIN PKCS7-----}i
|
||||
&& $ContentType !~ m{application/(x-pkcs7|pkcs7)}i
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
# SMIME crypt object
|
||||
my $CryptObject = $Kernel::OM->Get('Kernel::System::Crypt::SMIME');
|
||||
|
||||
if ( !$CryptObject ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::Decrypt',
|
||||
Value => "Not possible to create crypt object",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
my $IncomingMailAddress;
|
||||
for my $Email (qw(From)) {
|
||||
|
||||
my @EmailAddressOnField = $Self->{ParserObject}->SplitAddressLine(
|
||||
Line => $Self->{ParserObject}->GetParam( WHAT => $Email ),
|
||||
);
|
||||
|
||||
for my $EmailAddress (@EmailAddressOnField) {
|
||||
$IncomingMailAddress = $Self->{ParserObject}->GetEmailAddress(
|
||||
Email => $EmailAddress,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
my @PrivateList = $CryptObject->PrivateSearch(
|
||||
Search => $IncomingMailAddress,
|
||||
);
|
||||
|
||||
my %Decrypt;
|
||||
PRIVATESEARCH:
|
||||
for my $PrivateFilename (@PrivateList) {
|
||||
|
||||
# Try to decrypt
|
||||
%Decrypt = $CryptObject->Decrypt(
|
||||
Message => $DecryptBody,
|
||||
SearchingNeededKey => 1,
|
||||
Filename => $PrivateFilename->{Filename},
|
||||
);
|
||||
|
||||
# Stop loop if successful
|
||||
last PRIVATESEARCH if ( $Decrypt{Successful} );
|
||||
}
|
||||
|
||||
return if !$Decrypt{Successful};
|
||||
|
||||
my $ParserObject = Kernel::System::EmailParser->new(
|
||||
%{$Self},
|
||||
Email => $Decrypt{Data},
|
||||
);
|
||||
$DecryptBody = $ParserObject->GetMessageBody();
|
||||
|
||||
if ( $Param{JobConfig}->{StoreDecryptedBody} ) {
|
||||
$Param{GetParam}->{Body} = $DecryptBody;
|
||||
$Param{GetParam}->{'Content-Type'} = 'text/html';
|
||||
}
|
||||
|
||||
# Return content if successful
|
||||
return $DecryptBody;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,69 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::Filter::DetectAttachment;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::System::Log',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# Allocate new hash for object.
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
$Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject";
|
||||
|
||||
# Get communication log object and MessageID.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# Check needed stuff.
|
||||
for my $Needed (qw(JobConfig GetParam)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::DetectAttachment',
|
||||
Value => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Get attachments.
|
||||
my @Attachments = $Self->{ParserObject}->GetAttachments();
|
||||
|
||||
my $AttachmentCount = 0;
|
||||
for my $Attachment (@Attachments) {
|
||||
if (
|
||||
defined $Attachment->{ContentDisposition}
|
||||
&& length $Attachment->{ContentDisposition}
|
||||
)
|
||||
{
|
||||
$AttachmentCount++;
|
||||
}
|
||||
}
|
||||
|
||||
$Param{GetParam}->{'X-OTRS-AttachmentExists'} = ( $AttachmentCount ? 'yes' : 'no' );
|
||||
$Param{GetParam}->{'X-OTRS-AttachmentCount'} = $AttachmentCount;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,82 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::Filter::DetectBounceEmail;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Sisimai::Data;
|
||||
use Sisimai::Message;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::Log',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
$Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject";
|
||||
|
||||
# Get communication log object.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# Ensure that the flag X-OTRS-Bounce doesn't exist if we didn't analysed it yet.
|
||||
delete $Param{GetParam}->{'X-OTRS-Bounce'};
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => ref($Self),
|
||||
Value => 'Checking if is a Bounce e-mail.',
|
||||
);
|
||||
|
||||
my $BounceMessage = Sisimai::Message->new( data => $Self->{ParserObject}->GetPlainEmail() );
|
||||
|
||||
return 1 if !$BounceMessage;
|
||||
|
||||
my $BounceData = Sisimai::Data->make( data => $BounceMessage );
|
||||
|
||||
return 1 if !$BounceData || !@{$BounceData};
|
||||
|
||||
my $MessageID = $BounceData->[0]->messageid();
|
||||
|
||||
return 1 if !$MessageID;
|
||||
|
||||
$MessageID = sprintf '<%s>', $MessageID;
|
||||
|
||||
$Param{GetParam}->{'X-OTRS-Bounce'} = 1;
|
||||
$Param{GetParam}->{'X-OTRS-Bounce-OriginalMessageID'} = $MessageID;
|
||||
$Param{GetParam}->{'X-OTRS-Bounce-ErrorMessage'} = $Param{GetParam}->{Body};
|
||||
$Param{GetParam}->{'X-OTRS-Loop'} = 1;
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => ref($Self),
|
||||
Value => sprintf(
|
||||
'Detected Bounce for e-mail "%s"',
|
||||
$MessageID,
|
||||
),
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,243 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::Filter::ExternalTicketNumberRecognition;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::State',
|
||||
'Kernel::System::Ticket',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
# get communication log object and MessageID
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# checking mandatory configuration options
|
||||
for my $Option (qw(NumberRegExp DynamicFieldName SenderType IsVisibleForCustomer)) {
|
||||
if ( !defined $Param{JobConfig}->{$Option} && !$Param{JobConfig}->{$Option} ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::ExternalTicketNumberRecognition',
|
||||
Value => "Missing configuration for $Option for postmaster filter.",
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Filter::ExternalTicketNumberRecognition',
|
||||
Value => "Starting filter '$Param{JobConfig}->{Name}'",
|
||||
);
|
||||
|
||||
# check if sender is of interest
|
||||
return 1 if !$Param{GetParam}->{From};
|
||||
|
||||
if ( defined $Param{JobConfig}->{FromAddressRegExp} && $Param{JobConfig}->{FromAddressRegExp} )
|
||||
{
|
||||
|
||||
if ( $Param{GetParam}->{From} !~ /$Param{JobConfig}->{FromAddressRegExp}/i ) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
my $NumberRegExp = $Param{JobConfig}->{NumberRegExp};
|
||||
|
||||
# search in the subject
|
||||
if ( $Param{JobConfig}->{SearchInSubject} ) {
|
||||
|
||||
# try to get external ticket number from email subject
|
||||
my @SubjectLines = split /\n/, $Param{GetParam}->{Subject};
|
||||
LINE:
|
||||
for my $Line (@SubjectLines) {
|
||||
if ( $Line =~ m{$NumberRegExp}ms ) {
|
||||
$Self->{Number} = $1;
|
||||
last LINE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $Self->{Number} ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Filter::ExternalTicketNumberRecognition',
|
||||
Value => "Found number: '$Self->{Number}' in subject",
|
||||
);
|
||||
}
|
||||
else {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Filter::ExternalTicketNumberRecognition',
|
||||
Value => "No number found in subject: '" . join( '', @SubjectLines ) . "'",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# search in the body
|
||||
if ( $Param{JobConfig}->{SearchInBody} ) {
|
||||
|
||||
# split the body into separate lines
|
||||
my @BodyLines = split /\n/, $Param{GetParam}->{Body};
|
||||
|
||||
# traverse lines and return first match
|
||||
LINE:
|
||||
for my $Line (@BodyLines) {
|
||||
if ( $Line =~ m{$NumberRegExp}ms ) {
|
||||
|
||||
# get the found element value
|
||||
$Self->{Number} = $1;
|
||||
last LINE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# we need to have found an external number to proceed.
|
||||
if ( !$Self->{Number} ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Filter::ExternalTicketNumberRecognition',
|
||||
Value => "Could not find external ticket number => Ignoring",
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Filter::ExternalTicketNumberRecognition',
|
||||
Value => "Found number $Self->{Number}",
|
||||
);
|
||||
}
|
||||
|
||||
# is there a ticket for this ticket number?
|
||||
my %Query = (
|
||||
Result => 'ARRAY',
|
||||
Limit => 1,
|
||||
UserID => 1,
|
||||
);
|
||||
|
||||
# check if we should only find the ticket number in tickets with a given state type
|
||||
if ( defined $Param{JobConfig}->{TicketStateTypes} && $Param{JobConfig}->{TicketStateTypes} ) {
|
||||
|
||||
$Query{StateTypeIDs} = [];
|
||||
my @StateTypeIDs;
|
||||
|
||||
# if StateTypes contains semicolons, use that for split,
|
||||
# otherwise split on spaces (for compat)
|
||||
if ( $Param{JobConfig}->{TicketStateTypes} =~ m{;} ) {
|
||||
@StateTypeIDs = split ';', $Param{JobConfig}->{TicketStateTypes};
|
||||
}
|
||||
else {
|
||||
@StateTypeIDs = split ' ', $Param{JobConfig}->{TicketStateTypes};
|
||||
}
|
||||
|
||||
STATETYPE:
|
||||
for my $StateType (@StateTypeIDs) {
|
||||
|
||||
next STATETYPE if !$StateType;
|
||||
|
||||
my $StateTypeID = $Kernel::OM->Get('Kernel::System::State')->StateTypeLookup(
|
||||
StateType => $StateType,
|
||||
);
|
||||
|
||||
if ($StateTypeID) {
|
||||
push @{ $Query{StateTypeIDs} }, $StateTypeID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# dynamic field search condition
|
||||
$Query{ 'DynamicField_' . $Param{JobConfig}->{'DynamicFieldName'} } = {
|
||||
Equals => $Self->{Number},
|
||||
};
|
||||
|
||||
# get ticket object
|
||||
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
||||
|
||||
# search tickets
|
||||
my @TicketIDs = $TicketObject->TicketSearch(%Query);
|
||||
|
||||
# get the first and only ticket id
|
||||
my $TicketID = shift @TicketIDs;
|
||||
|
||||
# ok, found ticket to deal with
|
||||
if ($TicketID) {
|
||||
|
||||
# get ticket number
|
||||
my $TicketNumber = $TicketObject->TicketNumberLookup(
|
||||
TicketID => $TicketID,
|
||||
UserID => 1,
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Filter::ExternalTicketNumberRecognition',
|
||||
Value => "Found ticket $TicketNumber open for external number $Self->{Number}. Updating.",
|
||||
);
|
||||
|
||||
# get config object
|
||||
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
||||
|
||||
# build subject
|
||||
my $TicketHook = $ConfigObject->Get('Ticket::Hook');
|
||||
my $TicketHookDivider = $ConfigObject->Get('Ticket::HookDivider');
|
||||
$Param{GetParam}->{Subject} .= " [$TicketHook$TicketHookDivider$TicketNumber]";
|
||||
|
||||
# set sender type and article type.
|
||||
$Param{GetParam}->{'X-OTRS-FollowUp-SenderType'} = $Param{JobConfig}->{SenderType};
|
||||
$Param{GetParam}->{'X-OTRS-FollowUp-IsVisibleForCustomer'} = $Param{JobConfig}->{IsVisibleForCustomer};
|
||||
|
||||
# also set these parameters. It could be that the follow up is rejected by Reject.pm
|
||||
# (follow-ups not allowed), but the original article will still be attached to the ticket.
|
||||
$Param{GetParam}->{'X-OTRS-SenderType'} = $Param{JobConfig}->{SenderType};
|
||||
$Param{GetParam}->{'X-OTRS-IsVisibleForCustomer'} = $Param{JobConfig}->{IsVisibleForCustomer};
|
||||
|
||||
}
|
||||
else {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Filter::ExternalTicketNumberRecognition',
|
||||
Value => "Creating new ticket for external ticket '$Self->{Number}'",
|
||||
);
|
||||
|
||||
# get the dynamic field name and description from JobConfig, set as headers
|
||||
my $TicketDynamicFieldName = $Param{JobConfig}->{'DynamicFieldName'};
|
||||
$Param{GetParam}->{ 'X-OTRS-DynamicField-' . $TicketDynamicFieldName } = $Self->{Number};
|
||||
|
||||
# set sender type and article type
|
||||
$Param{GetParam}->{'X-OTRS-SenderType'} = $Param{JobConfig}->{SenderType};
|
||||
$Param{GetParam}->{'X-OTRS-IsVisibleForCustomer'} = $Param{JobConfig}->{IsVisibleForCustomer};
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,163 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::Filter::FollowUpArticleVisibilityCheck;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::CustomerUser',
|
||||
'Kernel::System::Ticket',
|
||||
'Kernel::System::Ticket::Article',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
# get parser object
|
||||
$Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject!";
|
||||
|
||||
# Get communication log object.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# This filter is not needed if there is no TicketID.
|
||||
return 1 if !$Param{TicketID};
|
||||
|
||||
# check needed stuff
|
||||
for (qw(JobConfig GetParam UserID)) {
|
||||
if ( !$Param{$_} ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::FollowUpArticleVisibilityCheck',
|
||||
Value => "Need $_!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Only run if we have a follow-up article with SenderType 'customer'.
|
||||
# It could be that follow-ups have a different SenderType like 'system' for
|
||||
# automatic notifications. In these cases there is no need to hide them.
|
||||
# See also bug#10182 for details.
|
||||
if (
|
||||
!$Param{GetParam}->{'X-OTRS-FollowUp-SenderType'}
|
||||
|| $Param{GetParam}->{'X-OTRS-FollowUp-SenderType'} ne 'customer'
|
||||
)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
my %Ticket = $Kernel::OM->Get('Kernel::System::Ticket')->TicketGet(
|
||||
TicketID => $Param{TicketID},
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
# Check if it is a known customer, otherwise use email address from CustomerUserID field of the ticket.
|
||||
my %CustomerData = $Kernel::OM->Get('Kernel::System::CustomerUser')->CustomerUserDataGet(
|
||||
User => $Ticket{CustomerUserID},
|
||||
);
|
||||
my $CustomerEmailAddress = $CustomerData{UserEmail} || $Ticket{CustomerUserID};
|
||||
|
||||
# Email sender address
|
||||
my $SenderAddress = $Param{GetParam}->{'X-Sender'};
|
||||
|
||||
# Email Reply-To address for forwarded emails
|
||||
my $ReplyToAddress;
|
||||
if ( $Param{GetParam}->{ReplyTo} ) {
|
||||
$ReplyToAddress = $Self->{ParserObject}->GetEmailAddress(
|
||||
Email => $Param{GetParam}->{ReplyTo},
|
||||
);
|
||||
}
|
||||
|
||||
# check if current sender is customer (do nothing)
|
||||
if ( $CustomerEmailAddress && $SenderAddress ) {
|
||||
return 1 if lc $CustomerEmailAddress eq lc $SenderAddress;
|
||||
}
|
||||
|
||||
my @References = $Self->{ParserObject}->GetReferences();
|
||||
|
||||
my $ArticleObject = $Kernel::OM->Get('Kernel::System::Ticket::Article');
|
||||
|
||||
# Get all internal email articles sent by agents.
|
||||
my @MetaArticleIndex = $ArticleObject->ArticleList(
|
||||
TicketID => $Param{TicketID},
|
||||
CommunicationChannel => 'Email',
|
||||
SenderType => 'agent',
|
||||
IsVisibleForCustomer => 0,
|
||||
);
|
||||
return 1 if !@MetaArticleIndex;
|
||||
|
||||
my $ArticleBackendObject = $ArticleObject->BackendForChannel( ChannelName => 'Email' );
|
||||
|
||||
# check if current sender got an internal forward
|
||||
my $IsInternalForward;
|
||||
ARTICLE:
|
||||
for my $MetaArticle ( reverse @MetaArticleIndex ) {
|
||||
|
||||
my $Article = {
|
||||
$ArticleBackendObject->ArticleGet( %{$MetaArticle} )
|
||||
};
|
||||
|
||||
# check recipients
|
||||
next ARTICLE if !$Article->{To};
|
||||
|
||||
# check based on recipient addresses of the article
|
||||
my @ToEmailAddresses = $Self->{ParserObject}->SplitAddressLine(
|
||||
Line => $Article->{To},
|
||||
);
|
||||
my @CcEmailAddresses = $Self->{ParserObject}->SplitAddressLine(
|
||||
Line => $Article->{Cc},
|
||||
);
|
||||
my @EmailAdresses = ( @ToEmailAddresses, @CcEmailAddresses );
|
||||
|
||||
EMAIL:
|
||||
for my $Email (@EmailAdresses) {
|
||||
my $Recipient = $Self->{ParserObject}->GetEmailAddress(
|
||||
Email => $Email,
|
||||
);
|
||||
if ( lc $Recipient eq lc $SenderAddress ) {
|
||||
$IsInternalForward = 1;
|
||||
last ARTICLE;
|
||||
}
|
||||
if ( $ReplyToAddress && lc $Recipient eq lc $ReplyToAddress ) {
|
||||
$IsInternalForward = 1;
|
||||
last ARTICLE;
|
||||
}
|
||||
}
|
||||
|
||||
# check based on Message-ID of the article
|
||||
for my $Reference (@References) {
|
||||
if ( $Article->{MessageID} && $Article->{MessageID} eq $Reference ) {
|
||||
$IsInternalForward = 1;
|
||||
last ARTICLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1 if !$IsInternalForward;
|
||||
|
||||
$Param{GetParam}->{'X-OTRS-FollowUp-IsVisibleForCustomer'} = $Param{JobConfig}->{IsVisibleForCustomer} // 0;
|
||||
$Param{GetParam}->{'X-OTRS-FollowUp-SenderType'} = $Param{JobConfig}->{SenderType} || 'customer';
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
200
Perl OTRS/Kernel/System/PostMaster/Filter/Match.pm
Normal file
200
Perl OTRS/Kernel/System/PostMaster/Filter/Match.pm
Normal file
@@ -0,0 +1,200 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::Filter::Match;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Kernel::System::VariableCheck qw(:all);
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::System::Log',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
# get parser object
|
||||
$Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject!";
|
||||
|
||||
# Get communication log object.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for (qw(JobConfig GetParam)) {
|
||||
if ( !$Param{$_} ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::Match',
|
||||
Value => "Need $_!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# get config options
|
||||
my %Config;
|
||||
my @Match;
|
||||
my @Set;
|
||||
my $StopAfterMatch;
|
||||
if ( $Param{JobConfig} && ref $Param{JobConfig} eq 'HASH' ) {
|
||||
%Config = %{ $Param{JobConfig} };
|
||||
|
||||
if ( IsArrayRefWithData( $Config{Match} ) ) {
|
||||
@Match = @{ $Config{Match} };
|
||||
}
|
||||
elsif ( IsHashRefWithData( $Config{Match} ) ) {
|
||||
for my $Key ( sort keys %{ $Config{Match} } ) {
|
||||
push @Match, {
|
||||
Key => $Key,
|
||||
Value => $Config{Match}->{$Key},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if ( IsArrayRefWithData( $Config{Set} ) ) {
|
||||
@Set = @{ $Config{Set} };
|
||||
}
|
||||
elsif ( IsHashRefWithData( $Config{Set} ) ) {
|
||||
|
||||
for my $Key ( sort keys %{ $Config{Set} } ) {
|
||||
push @Set, {
|
||||
Key => $Key,
|
||||
Value => $Config{Set}->{$Key},
|
||||
};
|
||||
}
|
||||
}
|
||||
$StopAfterMatch = $Config{StopAfterMatch} || 0;
|
||||
}
|
||||
|
||||
my $Prefix = '';
|
||||
if ( $Config{Name} ) {
|
||||
$Prefix = "Filter: '$Config{Name}' ";
|
||||
}
|
||||
|
||||
# match 'Match => ???' stuff
|
||||
my $Matched = '';
|
||||
my $MatchedNot = 0;
|
||||
my $MatchedResult = '';
|
||||
for my $Index ( 0 .. ( scalar @Match ) - 1 ) {
|
||||
my $Key = $Match[$Index]->{Key};
|
||||
my $Value = $Match[$Index]->{Value};
|
||||
|
||||
# match only email addresses
|
||||
if ( $Param{GetParam}->{$Key} && $Value =~ /^EMAILADDRESS:(.*)$/ ) {
|
||||
my $SearchEmail = $1;
|
||||
my @EmailAddresses = $Self->{ParserObject}->SplitAddressLine(
|
||||
Line => $Param{GetParam}->{$Key},
|
||||
);
|
||||
my $LocalMatched;
|
||||
RECIPIENTS:
|
||||
for my $Recipients (@EmailAddresses) {
|
||||
|
||||
my $Email = $Self->{ParserObject}->GetEmailAddress( Email => $Recipients );
|
||||
|
||||
if ( $Email =~ /^$SearchEmail$/i ) {
|
||||
|
||||
$LocalMatched = 1;
|
||||
|
||||
if ($SearchEmail) {
|
||||
$MatchedResult = $SearchEmail;
|
||||
}
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Filter::Match',
|
||||
Value => "$Prefix'$Param{GetParam}->{$Key}' =~ /$Value/i matched!",
|
||||
);
|
||||
|
||||
last RECIPIENTS;
|
||||
}
|
||||
}
|
||||
if ( !$LocalMatched ) {
|
||||
$MatchedNot = 1;
|
||||
}
|
||||
else {
|
||||
$Matched = 1;
|
||||
}
|
||||
}
|
||||
|
||||
# match string
|
||||
elsif ( $Param{GetParam}->{$Key} && $Param{GetParam}->{$Key} =~ /$Value/i ) {
|
||||
|
||||
# don't lose older match values if more than one header is
|
||||
# used for matching.
|
||||
$Matched = 1;
|
||||
|
||||
if ($1) {
|
||||
$MatchedResult = $1;
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Filter::Match',
|
||||
Value => "$Prefix'$Param{GetParam}->{$Key}' =~ /$Value/i matched!",
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
$MatchedNot = 1;
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Filter::Match',
|
||||
Value => "$Prefix'$Param{GetParam}->{$Key}' =~ /$Value/i matched NOT!",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# should I ignore the incoming mail?
|
||||
if ( $Matched && !$MatchedNot ) {
|
||||
|
||||
for my $SetItem (@Set) {
|
||||
my $Key = $SetItem->{Key};
|
||||
my $Value = $SetItem->{Value};
|
||||
$Value =~ s/\[\*\*\*\]/$MatchedResult/;
|
||||
$Param{GetParam}->{$Key} = $Value;
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Notice',
|
||||
Key => 'Kernel::System::PostMaster::Filter::Match',
|
||||
Value => $Prefix . "Set param '$Key' to '$Value' (Message-ID: $Param{GetParam}->{'Message-ID'})",
|
||||
);
|
||||
}
|
||||
|
||||
# stop after match
|
||||
if ($StopAfterMatch) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Notice',
|
||||
Key => 'Kernel::System::PostMaster::Filter::Match',
|
||||
Value => $Prefix
|
||||
. "Stopped filter processing because of used 'StopAfterMatch' (Message-ID: $Param{GetParam}->{'Message-ID'})",
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
217
Perl OTRS/Kernel/System/PostMaster/Filter/MatchDBSource.pm
Normal file
217
Perl OTRS/Kernel/System/PostMaster/Filter/MatchDBSource.pm
Normal file
@@ -0,0 +1,217 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::Filter::MatchDBSource;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::PostMaster::Filter',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
# get parser object
|
||||
$Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject!";
|
||||
|
||||
# Get communication log object.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for (qw(JobConfig GetParam)) {
|
||||
if ( !$Param{$_} ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::MatchDBSource',
|
||||
Value => "Need $_!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# get postmaster filter object
|
||||
my $PostMasterFilter = $Kernel::OM->Get('Kernel::System::PostMaster::Filter');
|
||||
|
||||
# get all db filters
|
||||
my %JobList = $PostMasterFilter->FilterList();
|
||||
|
||||
for ( sort keys %JobList ) {
|
||||
|
||||
my %NamedCaptures;
|
||||
|
||||
# get config options
|
||||
my %Config = $PostMasterFilter->FilterGet( Name => $_ );
|
||||
|
||||
my @Match;
|
||||
my @Set;
|
||||
if ( $Config{Match} ) {
|
||||
@Match = @{ $Config{Match} };
|
||||
}
|
||||
if ( $Config{Set} ) {
|
||||
@Set = @{ $Config{Set} };
|
||||
}
|
||||
my $StopAfterMatch = $Config{StopAfterMatch} || 0;
|
||||
my $Prefix = '';
|
||||
if ( $Config{Name} ) {
|
||||
$Prefix = "Filter: '$Config{Name}' ";
|
||||
}
|
||||
|
||||
# match 'Match => ???' stuff
|
||||
my $Matched = 0; # Numbers are required because of the bitwise or in the negation.
|
||||
my $MatchedNot = 0;
|
||||
my $MatchedResult = '';
|
||||
for my $Index ( 0 .. ( scalar @Match ) - 1 ) {
|
||||
my $Key = $Match[$Index]->{Key};
|
||||
my $Value = $Match[$Index]->{Value};
|
||||
|
||||
# match only email addresses
|
||||
if ( defined $Param{GetParam}->{$Key} && $Value =~ /^EMAILADDRESS:(.*)$/ ) {
|
||||
my $SearchEmail = $1;
|
||||
my @EmailAddresses = $Self->{ParserObject}->SplitAddressLine(
|
||||
Line => $Param{GetParam}->{$Key},
|
||||
);
|
||||
my $LocalMatched = 0;
|
||||
RECIPIENT:
|
||||
for my $Recipients (@EmailAddresses) {
|
||||
|
||||
my $Email = $Self->{ParserObject}->GetEmailAddress( Email => $Recipients );
|
||||
|
||||
next RECIPIENT if !$Email;
|
||||
|
||||
if ( $Email =~ /^$SearchEmail$/i ) {
|
||||
|
||||
$LocalMatched = 1;
|
||||
|
||||
if ($SearchEmail) {
|
||||
$MatchedResult = $SearchEmail;
|
||||
$NamedCaptures{email} = $SearchEmail;
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Filter::MatchDBSource',
|
||||
Value => "$Prefix'$Param{GetParam}->{$Key}' =~ /$Value/i matched!",
|
||||
);
|
||||
|
||||
last RECIPIENT;
|
||||
}
|
||||
}
|
||||
|
||||
# Switch LocalMatched if Config has a negation.
|
||||
if ( $Config{Not}->[$Index]->{Value} ) {
|
||||
$LocalMatched = !$LocalMatched;
|
||||
}
|
||||
|
||||
if ( !$LocalMatched ) {
|
||||
$MatchedNot = 1;
|
||||
}
|
||||
else {
|
||||
$Matched = 1;
|
||||
}
|
||||
}
|
||||
|
||||
# match string
|
||||
elsif (
|
||||
defined $Param{GetParam}->{$Key} &&
|
||||
(
|
||||
( !$Config{Not}->[$Index]->{Value} && $Param{GetParam}->{$Key} =~ m{$Value}i )
|
||||
||
|
||||
( $Config{Not}->[$Index]->{Value} && $Param{GetParam}->{$Key} !~ m{$Value}i )
|
||||
)
|
||||
)
|
||||
{
|
||||
|
||||
# don't lose older match values if more than one header is
|
||||
# used for matching.
|
||||
$Matched = 1;
|
||||
if ($1) {
|
||||
$MatchedResult = $1;
|
||||
}
|
||||
|
||||
if (%+) {
|
||||
my @Keys = keys %+;
|
||||
my @Values = values %+;
|
||||
|
||||
@NamedCaptures{@Keys} = @Values;
|
||||
}
|
||||
|
||||
my $Op = $Config{Not}->[$Index]->{Value} ? '!' : "=";
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Filter::MatchDBSource',
|
||||
Value => "successful $Prefix'$Param{GetParam}->{$Key}' $Op~ /$Value/i !",
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
$MatchedNot = 1;
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Filter::MatchDBSource',
|
||||
Value => "$Prefix'$Param{GetParam}->{$Key}' =~ /$Value/i matched NOT!",
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
# should I ignore the incoming mail?
|
||||
if ( $Matched && !$MatchedNot ) {
|
||||
for my $SetItem (@Set) {
|
||||
my $Key = $SetItem->{Key};
|
||||
my $Value = $SetItem->{Value};
|
||||
|
||||
$Value =~ s/\[\*\*\*\]/$MatchedResult/;
|
||||
$Value =~ s/\[\*\* \\(\w+) \*\*\]/$NamedCaptures{$1}/xmsg;
|
||||
|
||||
$Param{GetParam}->{$Key} = $Value;
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Notice',
|
||||
Key => 'Kernel::System::PostMaster::Filter::MatchDBSource',
|
||||
Value => $Prefix
|
||||
. "Set param '$Key' to '$Value' (Message-ID: $Param{GetParam}->{'Message-ID'}) ",
|
||||
);
|
||||
}
|
||||
|
||||
# stop after match
|
||||
if ($StopAfterMatch) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Notice',
|
||||
Key => 'Kernel::System::PostMaster::Filter::MatchDBSource',
|
||||
Value => $Prefix
|
||||
. "Stopped filter processing because of used 'StopAfterMatch' (Message-ID: $Param{GetParam}->{'Message-ID'}) ",
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
183
Perl OTRS/Kernel/System/PostMaster/Filter/NewTicketReject.pm
Normal file
183
Perl OTRS/Kernel/System/PostMaster/Filter/NewTicketReject.pm
Normal file
@@ -0,0 +1,183 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::Filter::NewTicketReject;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Kernel::System::VariableCheck qw(:all);
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::Email',
|
||||
'Kernel::System::Ticket',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
# Get communication log object.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for (qw(JobConfig GetParam)) {
|
||||
if ( !$Param{$_} ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::NewTicketReject',
|
||||
Value => "Need $_!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# get config options
|
||||
my %Config;
|
||||
my @Match;
|
||||
my @Set;
|
||||
if ( $Param{JobConfig} && ref $Param{JobConfig} eq 'HASH' ) {
|
||||
%Config = %{ $Param{JobConfig} };
|
||||
|
||||
if ( IsArrayRefWithData( $Config{Match} ) ) {
|
||||
@Match = @{ $Config{Match} };
|
||||
}
|
||||
elsif ( IsHashRefWithData( $Config{Match} ) ) {
|
||||
|
||||
for my $Key ( sort keys %{ $Config{Match} } ) {
|
||||
push @Match, {
|
||||
Key => $Key,
|
||||
Value => $Config{Match}->{$Key},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if ( IsArrayRefWithData( $Config{Set} ) ) {
|
||||
@Set = @{ $Config{Set} };
|
||||
}
|
||||
elsif ( IsHashRefWithData( $Config{Set} ) ) {
|
||||
|
||||
for my $Key ( sort keys %{ $Config{Set} } ) {
|
||||
push @Set, {
|
||||
Key => $Key,
|
||||
Value => $Config{Set}->{$Key},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# match 'Match => ???' stuff
|
||||
my $Matched = '';
|
||||
my $MatchedNot = 0;
|
||||
for my $Index ( 0 .. ( scalar @Match ) - 1 ) {
|
||||
my $Key = $Match[$Index]->{Key};
|
||||
my $Value = $Match[$Index]->{Value};
|
||||
|
||||
if ( $Param{GetParam}->{$Key} && $Param{GetParam}->{$Key} =~ /$Value/i ) {
|
||||
|
||||
$Matched = $1 || '1';
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Filter::NewTicketReject',
|
||||
Value => "'$Param{GetParam}->{$Key}' =~ /$Value/i matched!",
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
$MatchedNot = 1;
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Filter::NewTicketReject',
|
||||
Value => "'$Param{GetParam}->{$Key}' =~ /$Value/i matched NOT!",
|
||||
);
|
||||
}
|
||||
}
|
||||
if ( $Matched && !$MatchedNot ) {
|
||||
|
||||
# get ticket object
|
||||
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
||||
|
||||
# check if new ticket
|
||||
my $Tn = $TicketObject->GetTNByString( $Param{GetParam}->{Subject} );
|
||||
|
||||
return 1 if $Tn && $TicketObject->TicketCheckNumber( Tn => $Tn );
|
||||
|
||||
# set attributes if ticket is created
|
||||
for my $SetItem (@Set) {
|
||||
my $Key = $SetItem->{Key};
|
||||
my $Value = $SetItem->{Value};
|
||||
|
||||
$Param{GetParam}->{$Key} = $Value;
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Notice',
|
||||
Key => 'Kernel::System::PostMaster::Filter::NewTicketReject',
|
||||
Value => "Set param '$Key' to '$Value' (Message-ID: $Param{GetParam}->{'Message-ID'})",
|
||||
);
|
||||
}
|
||||
|
||||
# get config object
|
||||
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
||||
|
||||
# send bounce mail
|
||||
my $Subject = $ConfigObject->Get(
|
||||
'PostMaster::PreFilterModule::NewTicketReject::Subject'
|
||||
);
|
||||
my $Body = $ConfigObject->Get(
|
||||
'PostMaster::PreFilterModule::NewTicketReject::Body'
|
||||
);
|
||||
my $Sender = $ConfigObject->Get(
|
||||
'PostMaster::PreFilterModule::NewTicketReject::Sender'
|
||||
) || '';
|
||||
|
||||
$Kernel::OM->Get('Kernel::System::Email')->Send(
|
||||
From => $Sender,
|
||||
To => $Param{GetParam}->{From},
|
||||
Subject => $Subject,
|
||||
Body => $Body,
|
||||
Charset => 'utf-8',
|
||||
MimeType => 'text/plain',
|
||||
Loop => 1,
|
||||
Attachment => [
|
||||
{
|
||||
Filename => 'email.txt',
|
||||
Content => $Param{GetParam}->{Body},
|
||||
ContentType => 'application/octet-stream',
|
||||
}
|
||||
],
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Notice',
|
||||
Key => 'Kernel::System::PostMaster::Filter::NewTicketReject',
|
||||
Value => "Send reject mail to '$Param{GetParam}->{From}'!",
|
||||
);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,86 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::Filter::SMIMEFetchFromCustomer;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Kernel::System::EmailParser;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::Crypt::SMIME',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# Allocate new hash for object.
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
# Get parser object.
|
||||
$Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject!";
|
||||
|
||||
# Get communication log object.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# Check needed stuff.
|
||||
for my $Needed (qw(JobConfig GetParam)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::SMIMEFetchFromCustomer',
|
||||
Value => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
||||
|
||||
return 1 if !$ConfigObject->Get('SMIME');
|
||||
return 1 if !$ConfigObject->Get('SMIME::FetchFromCustomer');
|
||||
|
||||
my $CryptObject;
|
||||
eval {
|
||||
$CryptObject = $Kernel::OM->Get('Kernel::System::Crypt::SMIME');
|
||||
};
|
||||
return 1 if !$CryptObject;
|
||||
|
||||
my @EmailAddressOnField = $Self->{ParserObject}->SplitAddressLine(
|
||||
Line => $Self->{ParserObject}->GetParam( WHAT => 'From' ),
|
||||
);
|
||||
|
||||
my $IncomingMailAddress;
|
||||
|
||||
for my $EmailAddress (@EmailAddressOnField) {
|
||||
$IncomingMailAddress = $Self->{ParserObject}->GetEmailAddress(
|
||||
Email => $EmailAddress,
|
||||
);
|
||||
}
|
||||
|
||||
return 1 if !$IncomingMailAddress;
|
||||
|
||||
my @Files = $CryptObject->FetchFromCustomer(
|
||||
Search => $IncomingMailAddress,
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
789
Perl OTRS/Kernel/System/PostMaster/Filter/SystemMonitoring.pm
Normal file
789
Perl OTRS/Kernel/System/PostMaster/Filter/SystemMonitoring.pm
Normal file
@@ -0,0 +1,789 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
# important configuration items SystemMonitoring::SetIncidentState
|
||||
|
||||
package Kernel::System::PostMaster::Filter::SystemMonitoring;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Kernel::System::VariableCheck qw(:all);
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::DynamicField',
|
||||
'Kernel::System::LinkObject',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::Main',
|
||||
'Kernel::System::Ticket',
|
||||
'Kernel::System::DateTime',
|
||||
);
|
||||
|
||||
#the base name for dynamic fields
|
||||
our $DynamicFieldTicketTextPrefix = 'TicketFreeText';
|
||||
our $DynamicFieldArticleTextPrefix = 'ArticleFreeText';
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
$Self->{Debug} = $Param{Debug} || 0;
|
||||
|
||||
# check if CI incident state should be set automatically
|
||||
# this requires the ITSMConfigurationManagement module to be installed
|
||||
if ( $Kernel::OM->Get('Kernel::Config')->Get('SystemMonitoring::SetIncidentState') ) {
|
||||
|
||||
$Self->_IncidentStateNew();
|
||||
}
|
||||
|
||||
# Default Settings
|
||||
$Self->{Config} = {
|
||||
StateRegExp => '\s*State:\s+(\S+)',
|
||||
FromAddressRegExp => 'sysmon@example.com',
|
||||
NewTicketRegExp => 'CRITICAL|DOWN',
|
||||
CloseTicketRegExp => 'OK|UP',
|
||||
CloseActionState => 'closed successful',
|
||||
ClosePendingTime => 60 * 60 * 24 * 2, # 2 days
|
||||
HostRegExp => '\s*Address:\s+(\d+\.\d+\.\d+\.\d+)\s*',
|
||||
FreeTextHost => '1',
|
||||
FreeTextService => '2',
|
||||
FreeTextState => '1',
|
||||
ServiceRegExp => '\s*Service:\s+(.*)\s*',
|
||||
DefaultService => 'Host',
|
||||
SenderType => 'system',
|
||||
ArticleType => 'note-report',
|
||||
};
|
||||
|
||||
# get communication log object and MessageID
|
||||
if ( !defined $Param{CommuncationLogRequired} || $Param{CommuncationLogRequired} ) {
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
}
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub _GetDynamicFieldDefinition {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
for my $Argument (qw(Config Key Default Base Name ObjectType)) {
|
||||
if ( !$Param{$Argument} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Argument!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $Config = $Param{Config};
|
||||
my $Key = $Param{Key}; #FreeTextHost the config key
|
||||
my $Default = $Param{Default}; #1 the default value
|
||||
my $Base = $Param{Base}; # DynamicFieldTicketTextPrefix
|
||||
my $Name = $Param{Name}; #HostName
|
||||
my $ObjectType = $Param{ObjectType}; #HostName
|
||||
|
||||
my $ConfigFreeText = $Config->{$Key};
|
||||
|
||||
if ( !$ConfigFreeText ) {
|
||||
$ConfigFreeText = $Default;
|
||||
}
|
||||
|
||||
if ( $ConfigFreeText =~ /^\d+$/ ) {
|
||||
if ( ( $ConfigFreeText < 1 ) || ( $ConfigFreeText > 16 ) ) {
|
||||
die "Bad value $ConfigFreeText for CI Config $Key!";
|
||||
}
|
||||
}
|
||||
else {
|
||||
die "Bad value $ConfigFreeText for CI Config $Key!";
|
||||
}
|
||||
|
||||
my $FieldNameHost = $Base . $ConfigFreeText;
|
||||
|
||||
# define all dynamic fields for System Monitoring, these need to be changed as well if the
|
||||
# config changes
|
||||
return (
|
||||
{
|
||||
Name => $FieldNameHost,
|
||||
Label => 'SystemMonitoring ' . $Name,
|
||||
FieldType => 'Text',
|
||||
ObjectType => $ObjectType,
|
||||
Config => {
|
||||
TranslatableValues => 1,
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub GetDynamicFieldsDefinition {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $Config = $Param{Config};
|
||||
|
||||
push @{ $Param{NewFields} }, $Self->_GetDynamicFieldDefinition(
|
||||
Config => $Config,
|
||||
Key => 'FreeTextHost',
|
||||
Default => 1,
|
||||
Base => $DynamicFieldTicketTextPrefix,
|
||||
Name => 'HostName',
|
||||
ObjectType => 'Ticket',
|
||||
);
|
||||
push @{ $Param{NewFields} }, $Self->_GetDynamicFieldDefinition(
|
||||
Config => $Config,
|
||||
Key => 'FreeTextService',
|
||||
Default => 2,
|
||||
Base => $DynamicFieldTicketTextPrefix,
|
||||
Name => 'ServiceName',
|
||||
ObjectType => 'Ticket',
|
||||
);
|
||||
push @{ $Param{NewFields} }, $Self->_GetDynamicFieldDefinition(
|
||||
Config => $Config,
|
||||
Key => 'FreeTextState',
|
||||
Default => 1,
|
||||
Base => $DynamicFieldArticleTextPrefix,
|
||||
Name => 'StateName',
|
||||
ObjectType => 'Article',
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub _IncidentStateIncident {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# set the CI incident state to 'Incident'
|
||||
$Self->_SetIncidentState(
|
||||
Name => $Self->{Host},
|
||||
IncidentState => 'Incident',
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub _IncidentStateOperational {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# set the CI incident state to 'Operational'
|
||||
$Self->_SetIncidentState(
|
||||
Name => $Self->{Host},
|
||||
IncidentState => 'Operational',
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# these are optional modules from the ITSM Kernel::System::GeneralCatalog and Kernel::System::ITSMConfigItem
|
||||
|
||||
sub _IncidentStateNew {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# get main object
|
||||
my $MainObject = $Kernel::OM->Get('Kernel::System::Main');
|
||||
|
||||
# require the general catalog module
|
||||
if ( $MainObject->Require('Kernel::System::GeneralCatalog') ) {
|
||||
|
||||
# create general catalog object
|
||||
$Self->{GeneralCatalogObject} = Kernel::System::GeneralCatalog->new( %{$Self} );
|
||||
}
|
||||
|
||||
# require the config item module
|
||||
if ( $MainObject->Require('Kernel::System::ITSMConfigItem') ) {
|
||||
|
||||
# create config item object
|
||||
$Self->{ConfigItemObject} = Kernel::System::ITSMConfigItem->new( %{$Self} );
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub _MailParse {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
if ( !$Param{GetParam} || !$Param{GetParam}->{Subject} ) {
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::SystemMonitoring',
|
||||
Value => "Need Subject!",
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
my $Subject = $Param{GetParam}->{Subject};
|
||||
|
||||
# Try to get State, Host and Service from email subject
|
||||
my @SubjectLines = split /\n/, $Subject;
|
||||
for my $Line (@SubjectLines) {
|
||||
for my $Item (qw(State Host Service)) {
|
||||
if ( $Line =~ /$Self->{Config}->{ $Item . 'RegExp' }/ ) {
|
||||
$Self->{$Item} = $1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Don't Try to get State, Host and Service from email body, we want it from the subject alone
|
||||
|
||||
# split the body into separate lines
|
||||
if ( !$Param{GetParam}->{Body} ) {
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::SystemMonitoring',
|
||||
Value => "Need Body!",
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
my $Body = $Param{GetParam}->{Body};
|
||||
|
||||
my @BodyLines = split /\n/, $Body;
|
||||
|
||||
# to remember if an element was found before
|
||||
my %AlreadyMatched;
|
||||
|
||||
LINE:
|
||||
for my $Line (@BodyLines) {
|
||||
|
||||
# Try to get State, Host and Service from email body
|
||||
ELEMENT:
|
||||
for my $Element (qw(State Host Service)) {
|
||||
|
||||
next ELEMENT if $AlreadyMatched{$Element};
|
||||
|
||||
my $Regex = $Self->{Config}->{ $Element . 'RegExp' };
|
||||
|
||||
if ( $Line =~ /$Regex/ ) {
|
||||
|
||||
# get the found element value
|
||||
$Self->{$Element} = $1;
|
||||
|
||||
# remember that we found this element already
|
||||
$AlreadyMatched{$Element} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub _LogMessage {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
if ( !$Param{MessageText} ) {
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::SystemMonitoring',
|
||||
Value => "Need MessageText!",
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
my $MessageText = $Param{MessageText};
|
||||
|
||||
# logging
|
||||
# define log message
|
||||
$Self->{Service} ||= "No Service";
|
||||
$Self->{State} ||= "No State";
|
||||
$Self->{Host} ||= "No Host";
|
||||
|
||||
my $LogMessage = $MessageText . " - "
|
||||
. "Host: $Self->{Host}, "
|
||||
. "State: $Self->{State}, "
|
||||
. "Service: $Self->{Service}";
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Notice',
|
||||
Key => 'Kernel::System::PostMaster::Filter::SystemMonitoring',
|
||||
Value => 'SystemMonitoring Mail: ' . $LogMessage,
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub _TicketSearch {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# Is there a ticket for this Host/Service pair?
|
||||
my %Query = (
|
||||
Result => 'ARRAY',
|
||||
Limit => 1,
|
||||
UserID => 1,
|
||||
StateType => 'Open',
|
||||
);
|
||||
|
||||
for my $Type (qw(Host Service)) {
|
||||
my $FreeTextField = $Self->{Config}->{ 'FreeText' . $Type };
|
||||
my $KeyName = "DynamicField_" . $DynamicFieldTicketTextPrefix . $FreeTextField;
|
||||
my $KeyValue = $Self->{$Type};
|
||||
|
||||
$Query{$KeyName}->{Equals} = $KeyValue;
|
||||
}
|
||||
|
||||
# get dynamic field object
|
||||
my $DynamicFieldObject = $Kernel::OM->Get('Kernel::System::DynamicField');
|
||||
|
||||
# Check if dynamic fields really exists.
|
||||
# If dynamic fields don't exists, TicketSearch will return all tickets
|
||||
# and then the new article/ticket could take wrong place.
|
||||
# The lesser of the three evils is to create a new ticket
|
||||
# instead of defacing existing tickets or dropping it.
|
||||
# This behavior will come true if the dynamic fields
|
||||
# are named like TicketFreeTextHost. Its also bad.
|
||||
my $Errors = 0;
|
||||
for my $Type (qw(Host Service)) {
|
||||
my $FreeTextField = $Self->{Config}->{ 'FreeText' . $Type };
|
||||
|
||||
my $DynamicField = $DynamicFieldObject->DynamicFieldGet(
|
||||
Name => $DynamicFieldTicketTextPrefix . $FreeTextField,
|
||||
);
|
||||
|
||||
if ( !IsHashRefWithData($DynamicField) || $FreeTextField !~ m{\d+}xms ) {
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::SystemMonitoring',
|
||||
Value => "DynamicField "
|
||||
. $DynamicFieldTicketTextPrefix
|
||||
. $FreeTextField
|
||||
. " does not exists or misnamed."
|
||||
. " The configuration is based on Dynamic fields, so the number of the dynamic field is expected"
|
||||
. " (wrong value for dynamic field FreeText" . $Type . " is set).",
|
||||
);
|
||||
|
||||
$Errors = 1;
|
||||
}
|
||||
}
|
||||
|
||||
my $ArticleFreeTextField = $Self->{Config}->{'FreeTextState'};
|
||||
my $DynamicFieldArticle = $DynamicFieldObject->DynamicFieldGet(
|
||||
Name => $DynamicFieldArticleTextPrefix . $ArticleFreeTextField,
|
||||
);
|
||||
|
||||
if ( !IsHashRefWithData($DynamicFieldArticle) || $ArticleFreeTextField !~ m{\d+}xms ) {
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::SystemMonitoring',
|
||||
Value => "DynamicField "
|
||||
. $DynamicFieldArticleTextPrefix
|
||||
. $ArticleFreeTextField
|
||||
. " does not exists or misnamed."
|
||||
. " The configuration is based on dynamic fields, so the number of the dynamic field is expected"
|
||||
. " (wrong value for dynamic field FreeTextState is set).",
|
||||
);
|
||||
|
||||
$Errors = 1;
|
||||
}
|
||||
|
||||
my @TicketIDs = $Kernel::OM->Get('Kernel::System::Ticket')->TicketSearch(%Query);
|
||||
|
||||
# get the first and only ticket id
|
||||
my $TicketID;
|
||||
if ( !$Errors && @TicketIDs ) {
|
||||
$TicketID = shift @TicketIDs;
|
||||
}
|
||||
|
||||
return $TicketID;
|
||||
}
|
||||
|
||||
# the sub takes the param as a hash reference not as a copy, because it is updated
|
||||
|
||||
sub _TicketUpdate {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
for my $Needed (qw(TicketID Param)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::SystemMonitoring',
|
||||
Value => "Need $Needed",
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $TicketID = $Param{TicketID};
|
||||
my $Param = $Param{Param};
|
||||
|
||||
# get ticket object
|
||||
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
||||
|
||||
# get ticket number
|
||||
my $TicketNumber = $TicketObject->TicketNumberLookup(
|
||||
TicketID => $TicketID,
|
||||
UserID => 1,
|
||||
);
|
||||
|
||||
# build subject
|
||||
$Param->{GetParam}->{Subject} = $TicketObject->TicketSubjectBuild(
|
||||
TicketNumber => $TicketNumber,
|
||||
Subject => $Param->{GetParam}->{Subject},
|
||||
);
|
||||
|
||||
# set sender type and article type
|
||||
$Param->{GetParam}->{'X-OTRS-FollowUp-SenderType'} = $Self->{Config}->{SenderType};
|
||||
$Param->{GetParam}->{'X-OTRS-FollowUp-ArticleType'} = $Self->{Config}->{ArticleType};
|
||||
|
||||
# Set Article Free Field for State
|
||||
my $ArticleFreeTextNumber = $Self->{Config}->{'FreeTextState'};
|
||||
$Param->{GetParam}->{ 'X-OTRS-FollowUp-ArticleKey' . $ArticleFreeTextNumber } = 'State';
|
||||
$Param->{GetParam}->{ 'X-OTRS-FollowUp-ArticleValue' . $ArticleFreeTextNumber } = $Self->{State};
|
||||
|
||||
# get config object
|
||||
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
||||
|
||||
if ( $Self->{State} =~ /$Self->{Config}->{CloseTicketRegExp}/ ) {
|
||||
|
||||
# Close Ticket Condition -> Take Close Action
|
||||
if ( $Self->{Config}->{CloseActionState} ne 'OLD' ) {
|
||||
$Param->{GetParam}->{'X-OTRS-FollowUp-State'} = $Self->{Config}->{CloseActionState};
|
||||
|
||||
# get datetime object
|
||||
my $DateTimeObject = $Kernel::OM->Create(
|
||||
'Kernel::System::DateTime'
|
||||
);
|
||||
$DateTimeObject->Add(
|
||||
Seconds => $Self->{Config}->{ClosePendingTime},
|
||||
);
|
||||
|
||||
$Param->{GetParam}->{'X-OTRS-FollowUp-State-PendingTime'} = $DateTimeObject->ToString();
|
||||
}
|
||||
|
||||
# set log message
|
||||
$Self->_LogMessage( MessageText => 'Recovered' );
|
||||
|
||||
# if the CI incident state should be set
|
||||
if ( $ConfigObject->Get('SystemMonitoring::SetIncidentState') ) {
|
||||
$Self->_IncidentStateOperational();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
# Attach note to existing ticket
|
||||
$Self->_LogMessage( MessageText => 'New Notice' );
|
||||
}
|
||||
|
||||
# link ticket with CI, this is only possible if the ticket already exists,
|
||||
# e.g. in a subsequent email request, because we need a ticket id
|
||||
if ( $ConfigObject->Get('SystemMonitoring::LinkTicketWithCI') ) {
|
||||
|
||||
# link ticket with CI
|
||||
$Self->_LinkTicketWithCI(
|
||||
Name => $Self->{Host},
|
||||
TicketID => $TicketID,
|
||||
);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# the sub takes the param as a hash reference not as a copy, because it is updated
|
||||
|
||||
sub _TicketCreate {
|
||||
my ( $Self, $Param ) = @_;
|
||||
|
||||
# Create Ticket Condition -> Create new Ticket and record Host and Service
|
||||
for my $Item (qw(Host Service)) {
|
||||
|
||||
# get the freetext number from config
|
||||
my $TicketFreeTextNumber = $Self->{Config}->{ 'FreeText' . $Item };
|
||||
|
||||
# see the Kernel::System::PostMaster::NewTicket where this is read
|
||||
$Param->{GetParam}->{ 'X-OTRS-TicketKey' . $TicketFreeTextNumber } = $Item;
|
||||
$Param->{GetParam}->{ 'X-OTRS-TicketValue' . $TicketFreeTextNumber } = $Self->{$Item};
|
||||
}
|
||||
|
||||
# Set Article Free Field for State
|
||||
my $ArticleFreeTextNumber = $Self->{Config}->{'FreeTextState'};
|
||||
$Param->{GetParam}->{ 'X-OTRS-ArticleKey' . $ArticleFreeTextNumber } = 'State';
|
||||
$Param->{GetParam}->{ 'X-OTRS-ArticleValue' . $ArticleFreeTextNumber } = $Self->{State};
|
||||
|
||||
# set sender type and article type
|
||||
$Param->{GetParam}->{'X-OTRS-SenderType'} = $Self->{Config}->{SenderType};
|
||||
$Param->{GetParam}->{'X-OTRS-ArticleType'} = $Self->{Config}->{ArticleType};
|
||||
|
||||
# set log message
|
||||
$Self->_LogMessage( MessageText => 'New Ticket' );
|
||||
|
||||
# if the CI incident state should be set
|
||||
if ( $Kernel::OM->Get('Kernel::Config')->Get('SystemMonitoring::SetIncidentState') ) {
|
||||
$Self->_IncidentStateIncident();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# the sub takes the param as a hash reference not as a copy, because it is updated
|
||||
|
||||
sub _TicketDrop {
|
||||
my ( $Self, $Param ) = @_;
|
||||
|
||||
# No existing ticket and no open condition -> drop silently
|
||||
$Param->{GetParam}->{'X-OTRS-Ignore'} = 'yes';
|
||||
$Self->_LogMessage(
|
||||
MessageText => 'Mail Dropped, no matching ticket found, no open on this state ',
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# get config options, use defaults unless value specified
|
||||
if ( $Param{JobConfig} && ref $Param{JobConfig} eq 'HASH' ) {
|
||||
KEY:
|
||||
for my $Key ( keys( %{ $Param{JobConfig} } ) ) {
|
||||
next KEY if !$Self->{Config}->{$Key};
|
||||
$Self->{Config}->{$Key} = $Param{JobConfig}->{$Key};
|
||||
}
|
||||
}
|
||||
|
||||
# check if sender is of interest
|
||||
return 1 if !$Param{GetParam}->{From};
|
||||
return 1 if $Param{GetParam}->{From} !~ /$Self->{Config}->{FromAddressRegExp}/i;
|
||||
|
||||
$Self->_MailParse(%Param);
|
||||
|
||||
# we need State and Host to proceed
|
||||
if ( !$Self->{State} || !$Self->{Host} ) {
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::SystemMonitoring',
|
||||
Value => 'SystemMonitoring Mail: '
|
||||
. 'SystemMonitoring: Could not find host address '
|
||||
. 'and/or state in mail => Ignoring',
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Check for Service
|
||||
$Self->{Service} ||= $Self->{Config}->{DefaultService};
|
||||
|
||||
my $TicketID = $Self->_TicketSearch();
|
||||
|
||||
# OK, found ticket to deal with
|
||||
if ($TicketID) {
|
||||
$Self->_TicketUpdate(
|
||||
TicketID => $TicketID,
|
||||
Param => \%Param,
|
||||
);
|
||||
}
|
||||
elsif ( $Self->{State} =~ /$Self->{Config}->{NewTicketRegExp}/ ) {
|
||||
$Self->_TicketCreate( \%Param );
|
||||
}
|
||||
else {
|
||||
$Self->_TicketDrop( \%Param );
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub _SetIncidentState {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for my $Argument (qw(Name IncidentState )) {
|
||||
if ( !$Param{$Argument} ) {
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::SystemMonitoring',
|
||||
Value => "Need $Argument",
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# check configitem object
|
||||
return if !$Self->{ConfigItemObject};
|
||||
|
||||
# search configitem
|
||||
my $ConfigItemIDs = $Self->{ConfigItemObject}->ConfigItemSearchExtended(
|
||||
Name => $Param{Name},
|
||||
);
|
||||
|
||||
# if no config item with this name was found
|
||||
if ( !$ConfigItemIDs || ref $ConfigItemIDs ne 'ARRAY' || !@{$ConfigItemIDs} ) {
|
||||
|
||||
# log error
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::SystemMonitoring',
|
||||
Value => "Could not find any CI with the name '$Param{Name}'. ",
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
# if more than one config item with this name was found
|
||||
if ( scalar @{$ConfigItemIDs} > 1 ) {
|
||||
|
||||
# log error
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::SystemMonitoring',
|
||||
Value => "Can not set incident state for CI with the name '$Param{Name}'. "
|
||||
. "More than one CI with this name was found!",
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
# we only found one config item
|
||||
my $ConfigItemID = shift @{$ConfigItemIDs};
|
||||
|
||||
# get latest version data of config item
|
||||
my $Version = $Self->{ConfigItemObject}->VersionGet(
|
||||
ConfigItemID => $ConfigItemID,
|
||||
);
|
||||
|
||||
return if !$Version;
|
||||
return if ref $Version ne 'HASH';
|
||||
|
||||
# get incident state list
|
||||
my $InciStateList = $Self->{GeneralCatalogObject}->ItemList(
|
||||
Class => 'ITSM::Core::IncidentState',
|
||||
);
|
||||
|
||||
return if !$InciStateList;
|
||||
return if ref $InciStateList ne 'HASH';
|
||||
|
||||
# reverse the incident state list
|
||||
my %ReverseInciStateList = reverse %{$InciStateList};
|
||||
|
||||
# check if incident state is valid
|
||||
if ( !$ReverseInciStateList{ $Param{IncidentState} } ) {
|
||||
|
||||
# log error
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::SystemMonitoring',
|
||||
Value => "Invalid incident state '$Param{IncidentState}'!",
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
# add a new version with the new incident state
|
||||
my $VersionID = $Self->{ConfigItemObject}->VersionAdd(
|
||||
%{$Version},
|
||||
InciStateID => $ReverseInciStateList{ $Param{IncidentState} },
|
||||
UserID => 1,
|
||||
);
|
||||
|
||||
return $VersionID;
|
||||
}
|
||||
|
||||
sub _LinkTicketWithCI {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for my $Argument (qw(Name TicketID)) {
|
||||
if ( !$Param{$Argument} ) {
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::SystemMonitoring',
|
||||
Value => "Need $Argument",
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# check configitem object
|
||||
return if !$Self->{ConfigItemObject};
|
||||
|
||||
# search configitem
|
||||
my $ConfigItemIDs = $Self->{ConfigItemObject}->ConfigItemSearchExtended(
|
||||
Name => $Param{Name},
|
||||
);
|
||||
|
||||
# if no config item with this name was found
|
||||
if ( !$ConfigItemIDs || ref $ConfigItemIDs ne 'ARRAY' || !@{$ConfigItemIDs} ) {
|
||||
|
||||
# log error
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::SystemMonitoring',
|
||||
Value => "Could not find any CI with the name '$Param{Name}'. ",
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
# if more than one config item with this name was found
|
||||
if ( scalar @{$ConfigItemIDs} > 1 ) {
|
||||
|
||||
# log error
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Filter::SystemMonitoring',
|
||||
Value => "Can not set incident state for CI with the name '$Param{Name}'. "
|
||||
. "More than one CI with this name was found!",
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
# we only found one config item
|
||||
my $ConfigItemID = shift @{$ConfigItemIDs};
|
||||
|
||||
# link the ticket with the CI
|
||||
my $LinkResult = $Kernel::OM->Get('Kernel::System::LinkObject')->LinkAdd(
|
||||
SourceObject => 'Ticket',
|
||||
SourceKey => $Param{TicketID},
|
||||
TargetObject => 'ITSMConfigItem',
|
||||
TargetKey => $ConfigItemID,
|
||||
Type => 'RelevantTo',
|
||||
State => 'Valid',
|
||||
UserID => 1,
|
||||
);
|
||||
|
||||
return $LinkResult;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 TERMS AND CONDITIONS
|
||||
|
||||
This software is part of the OTRS project (L<https://otrs.org/>).
|
||||
|
||||
This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
the enclosed file COPYING for license information (GPL). If you
|
||||
did not receive this file, see L<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
702
Perl OTRS/Kernel/System/PostMaster/FollowUp.pm
Normal file
702
Perl OTRS/Kernel/System/PostMaster/FollowUp.pm
Normal file
@@ -0,0 +1,702 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::FollowUp;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::DynamicField',
|
||||
'Kernel::System::DynamicField::Backend',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::Ticket',
|
||||
'Kernel::System::Ticket::Article',
|
||||
'Kernel::System::DateTime',
|
||||
'Kernel::System::User',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
# get parser object
|
||||
$Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject!";
|
||||
|
||||
# Get communication log object.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for (qw(TicketID InmailUserID GetParam Tn AutoResponseType)) {
|
||||
if ( !$Param{$_} ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value => "Need $_!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
my %GetParam = %{ $Param{GetParam} };
|
||||
|
||||
# get ticket object
|
||||
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
||||
|
||||
my $OwnerID = $GetParam{'X-OTRS-FollowUp-OwnerID'};
|
||||
if ( $GetParam{'X-OTRS-FollowUp-Owner'} ) {
|
||||
|
||||
my $TmpOwnerID = $Kernel::OM->Get('Kernel::System::User')->UserLookup(
|
||||
UserLogin => $GetParam{'X-OTRS-FollowUp-Owner'},
|
||||
);
|
||||
|
||||
$OwnerID = $TmpOwnerID || $OwnerID;
|
||||
}
|
||||
|
||||
if ($OwnerID) {
|
||||
my $Success = $TicketObject->TicketOwnerSet(
|
||||
TicketID => $Param{TicketID},
|
||||
NewUserID => $OwnerID,
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
}
|
||||
|
||||
my $ResponsibleID = $GetParam{'X-OTRS-FollowUp-ResponsibleID'};
|
||||
if ( $GetParam{'X-OTRS-FollowUp-Responsible'} ) {
|
||||
|
||||
my $TmpResponsibleID = $Kernel::OM->Get('Kernel::System::User')->UserLookup(
|
||||
UserLogin => $GetParam{'X-OTRS-FollowUp-Responsible'},
|
||||
);
|
||||
|
||||
$ResponsibleID = $TmpResponsibleID || $ResponsibleID;
|
||||
}
|
||||
|
||||
if ($ResponsibleID) {
|
||||
my $Success = $TicketObject->TicketResponsibleSet(
|
||||
TicketID => $Param{TicketID},
|
||||
NewUserID => $ResponsibleID,
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
}
|
||||
|
||||
# get ticket data
|
||||
my %Ticket = $TicketObject->TicketGet(
|
||||
TicketID => $Param{TicketID},
|
||||
DynamicFields => 0,
|
||||
);
|
||||
|
||||
my $Comment = $Param{Comment} || '';
|
||||
my $Lock = $Param{Lock} || '';
|
||||
my $AutoResponseType = $Param{AutoResponseType} || '';
|
||||
|
||||
# Check if owner of ticket is still valid
|
||||
my %UserInfo = $Kernel::OM->Get('Kernel::System::User')->GetUserData(
|
||||
UserID => $Ticket{OwnerID},
|
||||
);
|
||||
|
||||
# 1) check user, out of office, unlock ticket
|
||||
if ( $UserInfo{OutOfOfficeMessage} ) {
|
||||
|
||||
$TicketObject->TicketLockSet(
|
||||
TicketID => $Param{TicketID},
|
||||
Lock => 'unlock',
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Notice',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value => "Ticket [$Param{Tn}] unlocked, current owner is out of office!",
|
||||
);
|
||||
}
|
||||
|
||||
# 2) check user, just lock it if user is valid and ticket was closed
|
||||
elsif ( $UserInfo{ValidID} eq 1 ) {
|
||||
|
||||
# set lock (if ticket should be locked on follow up)
|
||||
if ( $Lock && $Ticket{StateType} =~ /^close/i ) {
|
||||
|
||||
$TicketObject->TicketLockSet(
|
||||
TicketID => $Param{TicketID},
|
||||
Lock => 'lock',
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Notice',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value => "Ticket [$Param{Tn}] still locked.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# 3) Unlock ticket, because current user is set to invalid
|
||||
else {
|
||||
|
||||
$TicketObject->TicketLockSet(
|
||||
TicketID => $Param{TicketID},
|
||||
Lock => 'unlock',
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Notice',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value => "Ticket [$Param{Tn}] unlocked, current owner is invalid!",
|
||||
);
|
||||
}
|
||||
|
||||
# get config object
|
||||
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
||||
|
||||
# set state
|
||||
my $State = $ConfigObject->Get('PostmasterFollowUpState') || 'open';
|
||||
if (
|
||||
$Ticket{StateType} =~ /^close/
|
||||
&& $ConfigObject->Get('PostmasterFollowUpStateClosed')
|
||||
)
|
||||
{
|
||||
$State = $ConfigObject->Get('PostmasterFollowUpStateClosed');
|
||||
}
|
||||
if ( $GetParam{'X-OTRS-FollowUp-State'} ) {
|
||||
$State = $GetParam{'X-OTRS-FollowUp-State'};
|
||||
}
|
||||
|
||||
my $KeepStateHeader = $ConfigObject->Get('KeepStateHeader') || 'X-OTRS-FollowUp-State-Keep';
|
||||
if (
|
||||
( $Ticket{StateType} !~ /^new/ || $GetParam{'X-OTRS-FollowUp-State'} )
|
||||
&& !$GetParam{$KeepStateHeader}
|
||||
)
|
||||
{
|
||||
$TicketObject->TicketStateSet(
|
||||
State => $GetParam{'X-OTRS-FollowUp-State'} || $State,
|
||||
TicketID => $Param{TicketID},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value => "Ticket state will be left unchanged! State: $State.",
|
||||
);
|
||||
}
|
||||
|
||||
# set pending time
|
||||
if ( $GetParam{'X-OTRS-FollowUp-State-PendingTime'} ) {
|
||||
|
||||
# You can specify absolute dates like "2010-11-20 00:00:00" or relative dates, based on the arrival time of the email.
|
||||
# Use the form "+ $Number $Unit", where $Unit can be 's' (seconds), 'm' (minutes), 'h' (hours) or 'd' (days).
|
||||
# Only one unit can be specified. Examples of valid settings: "+50s" (pending in 50 seconds), "+30m" (30 minutes),
|
||||
# "+12d" (12 days). Note that settings like "+1d 12h" are not possible. You can specify "+36h" instead.
|
||||
|
||||
my $TargetTimeStamp = $GetParam{'X-OTRS-FollowUp-State-PendingTime'};
|
||||
|
||||
my ( $Sign, $Number, $Unit ) = $TargetTimeStamp =~ m{^\s*([+-]?)\s*(\d+)\s*([smhd]?)\s*$}smx;
|
||||
|
||||
if ($Number) {
|
||||
$Sign ||= '+';
|
||||
$Unit ||= 's';
|
||||
|
||||
my $Seconds = $Sign eq '-' ? ( $Number * -1 ) : $Number;
|
||||
|
||||
my %UnitMultiplier = (
|
||||
s => 1,
|
||||
m => 60,
|
||||
h => 60 * 60,
|
||||
d => 60 * 60 * 24,
|
||||
);
|
||||
|
||||
$Seconds = $Seconds * $UnitMultiplier{$Unit};
|
||||
|
||||
# get datetime object
|
||||
my $DateTimeObject = $Kernel::OM->Create('Kernel::System::DateTime');
|
||||
$DateTimeObject->Add( Seconds => $Seconds );
|
||||
$TargetTimeStamp = $DateTimeObject->ToString();
|
||||
}
|
||||
|
||||
my $Updated = $TicketObject->TicketPendingTimeSet(
|
||||
String => $TargetTimeStamp,
|
||||
TicketID => $Param{TicketID},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
# debug
|
||||
if ($Updated) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value =>
|
||||
"Pending time update via 'X-OTRS-FollowUp-State-PendingTime'! State-PendingTime: $GetParam{'X-OTRS-FollowUp-State-PendingTime'}.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# set priority
|
||||
if ( $GetParam{'X-OTRS-FollowUp-Priority'} ) {
|
||||
|
||||
$TicketObject->TicketPrioritySet(
|
||||
TicketID => $Param{TicketID},
|
||||
Priority => $GetParam{'X-OTRS-FollowUp-Priority'},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value =>
|
||||
"Priority update via 'X-OTRS-FollowUp-Priority'! Priority: $GetParam{'X-OTRS-FollowUp-Priority'}.",
|
||||
);
|
||||
}
|
||||
|
||||
# set queue
|
||||
if ( $GetParam{'X-OTRS-FollowUp-Queue'} ) {
|
||||
|
||||
$TicketObject->TicketQueueSet(
|
||||
Queue => $GetParam{'X-OTRS-FollowUp-Queue'},
|
||||
TicketID => $Param{TicketID},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value =>
|
||||
"Queue update via 'X-OTRS-FollowUp-Queue'! Queue: $GetParam{'X-OTRS-FollowUp-Queue'}.",
|
||||
);
|
||||
}
|
||||
|
||||
# set lock
|
||||
if ( $GetParam{'X-OTRS-FollowUp-Lock'} ) {
|
||||
|
||||
$TicketObject->TicketLockSet(
|
||||
Lock => $GetParam{'X-OTRS-FollowUp-Lock'},
|
||||
TicketID => $Param{TicketID},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value =>
|
||||
"Lock update via 'X-OTRS-FollowUp-Lock'! Lock: $GetParam{'X-OTRS-FollowUp-Lock'}.",
|
||||
);
|
||||
}
|
||||
|
||||
# set ticket type
|
||||
if ( $GetParam{'X-OTRS-FollowUp-Type'} ) {
|
||||
|
||||
$TicketObject->TicketTypeSet(
|
||||
Type => $GetParam{'X-OTRS-FollowUp-Type'},
|
||||
TicketID => $Param{TicketID},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value =>
|
||||
"Type update via 'X-OTRS-FollowUp-Type'! Type: $GetParam{'X-OTRS-FollowUp-Type'}.",
|
||||
);
|
||||
}
|
||||
|
||||
# set ticket service
|
||||
if ( $GetParam{'X-OTRS-FollowUp-Service'} ) {
|
||||
|
||||
$TicketObject->TicketServiceSet(
|
||||
Service => $GetParam{'X-OTRS-FollowUp-Service'},
|
||||
TicketID => $Param{TicketID},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value =>
|
||||
"Services update via 'X-OTRS-FollowUp-Service'! Service: $GetParam{'X-OTRS-FollowUp-Service'}.",
|
||||
);
|
||||
}
|
||||
|
||||
# set ticket sla
|
||||
if ( $GetParam{'X-OTRS-FollowUp-SLA'} ) {
|
||||
|
||||
$TicketObject->TicketSLASet(
|
||||
SLA => $GetParam{'X-OTRS-FollowUp-SLA'},
|
||||
TicketID => $Param{TicketID},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value =>
|
||||
"SLA update via 'X-OTRS-FollowUp-SLA'! SLA: $GetParam{'X-OTRS-FollowUp-SLA'}.",
|
||||
);
|
||||
}
|
||||
|
||||
# get dynamic field objects
|
||||
my $DynamicFieldObject = $Kernel::OM->Get('Kernel::System::DynamicField');
|
||||
my $DynamicFieldBackendObject = $Kernel::OM->Get('Kernel::System::DynamicField::Backend');
|
||||
|
||||
# dynamic fields
|
||||
my $DynamicFieldList =
|
||||
$DynamicFieldObject->DynamicFieldList(
|
||||
Valid => 1,
|
||||
ResultType => 'HASH',
|
||||
ObjectType => 'Ticket',
|
||||
);
|
||||
|
||||
# set dynamic fields for Ticket object type
|
||||
DYNAMICFIELDID:
|
||||
for my $DynamicFieldID ( sort keys %{$DynamicFieldList} ) {
|
||||
next DYNAMICFIELDID if !$DynamicFieldID;
|
||||
next DYNAMICFIELDID if !$DynamicFieldList->{$DynamicFieldID};
|
||||
my $Key = 'X-OTRS-FollowUp-DynamicField-' . $DynamicFieldList->{$DynamicFieldID};
|
||||
if ( defined $GetParam{$Key} && length $GetParam{$Key} ) {
|
||||
|
||||
# get dynamic field config
|
||||
my $DynamicFieldGet = $DynamicFieldObject->DynamicFieldGet(
|
||||
ID => $DynamicFieldID,
|
||||
);
|
||||
|
||||
$DynamicFieldBackendObject->ValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldGet,
|
||||
ObjectID => $Param{TicketID},
|
||||
Value => $GetParam{$Key},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value =>
|
||||
"DynamicField update via '$Key'! Value: $GetParam{$Key}.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# reverse dynamic field list
|
||||
my %DynamicFieldListReversed = reverse %{$DynamicFieldList};
|
||||
|
||||
# set ticket free text
|
||||
my %Values =
|
||||
(
|
||||
'X-OTRS-FollowUp-TicketKey' => 'TicketFreeKey',
|
||||
'X-OTRS-FollowUp-TicketValue' => 'TicketFreeText',
|
||||
);
|
||||
for my $Item ( sort keys %Values ) {
|
||||
for my $Count ( 1 .. 16 ) {
|
||||
my $Key = $Item . $Count;
|
||||
if (
|
||||
defined $GetParam{$Key}
|
||||
&& length $GetParam{$Key}
|
||||
&& $DynamicFieldListReversed{ $Values{$Item} . $Count }
|
||||
)
|
||||
{
|
||||
# get dynamic field config
|
||||
my $DynamicFieldGet = $DynamicFieldObject->DynamicFieldGet(
|
||||
ID => $DynamicFieldListReversed{ $Values{$Item} . $Count },
|
||||
);
|
||||
if ($DynamicFieldGet) {
|
||||
my $Success = $DynamicFieldBackendObject->ValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldGet,
|
||||
ObjectID => $Param{TicketID},
|
||||
Value => $GetParam{$Key},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value =>
|
||||
"DynamicField (TicketKey$Count) update via '$Key'! Value: $GetParam{$Key}.",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# set ticket free time
|
||||
for my $Count ( 1 .. 6 ) {
|
||||
|
||||
my $Key = 'X-OTRS-FollowUp-TicketTime' . $Count;
|
||||
|
||||
if ( defined $GetParam{$Key} && length $GetParam{$Key} ) {
|
||||
|
||||
# get datetime object
|
||||
my $DateTimeObject = $Kernel::OM->Create(
|
||||
'Kernel::System::DateTime',
|
||||
ObjectParams => {
|
||||
String => $GetParam{$Key}
|
||||
}
|
||||
);
|
||||
|
||||
if ( $DateTimeObject && $DynamicFieldListReversed{ 'TicketFreeTime' . $Count } ) {
|
||||
|
||||
# get dynamic field config
|
||||
my $DynamicFieldGet = $DynamicFieldObject->DynamicFieldGet(
|
||||
ID => $DynamicFieldListReversed{ 'TicketFreeTime' . $Count },
|
||||
);
|
||||
|
||||
if ($DynamicFieldGet) {
|
||||
my $Success = $DynamicFieldBackendObject->ValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldGet,
|
||||
ObjectID => $Param{TicketID},
|
||||
Value => $GetParam{$Key},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value =>
|
||||
"DynamicField (TicketTime$Count) update via '$Key'! Value: $GetParam{$Key}.",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $ArticleObject = $Kernel::OM->Get('Kernel::System::Ticket::Article');
|
||||
my $ArticleBackendObject = $ArticleObject->BackendForChannel(
|
||||
ChannelName => 'Email',
|
||||
);
|
||||
|
||||
my $IsVisibleForCustomer = 1;
|
||||
if ( length $GetParam{'X-OTRS-FollowUp-IsVisibleForCustomer'} ) {
|
||||
$IsVisibleForCustomer = $GetParam{'X-OTRS-FollowUp-IsVisibleForCustomer'};
|
||||
}
|
||||
|
||||
# Check if X-OTRS-FollowUp-SenderType exists, if not set default 'customer'.
|
||||
if ( !$ArticleObject->ArticleSenderTypeLookup( SenderType => $GetParam{'X-OTRS-FollowUp-SenderType'} ) )
|
||||
{
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value => "Can't find valid SenderType '$GetParam{'X-OTRS-FollowUp-SenderType'}' in DB, take 'customer'",
|
||||
);
|
||||
$GetParam{'X-OTRS-SenderType'} = 'customer';
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value => "Going to create follow up for TicketID '$Param{TicketID}'.",
|
||||
);
|
||||
|
||||
# do db insert
|
||||
my $ArticleID = $ArticleBackendObject->ArticleCreate(
|
||||
TicketID => $Param{TicketID},
|
||||
SenderType => $GetParam{'X-OTRS-FollowUp-SenderType'},
|
||||
IsVisibleForCustomer => $IsVisibleForCustomer,
|
||||
From => $GetParam{From},
|
||||
ReplyTo => $GetParam{ReplyTo},
|
||||
To => $GetParam{To},
|
||||
Cc => $GetParam{Cc},
|
||||
Subject => $GetParam{Subject},
|
||||
MessageID => $GetParam{'Message-ID'},
|
||||
InReplyTo => $GetParam{'In-Reply-To'},
|
||||
References => $GetParam{'References'},
|
||||
ContentType => $GetParam{'Content-Type'},
|
||||
Body => $GetParam{Body},
|
||||
UserID => $Param{InmailUserID},
|
||||
HistoryType => 'FollowUp',
|
||||
HistoryComment => "\%\%$Param{Tn}\%\%$Comment",
|
||||
AutoResponseType => $AutoResponseType,
|
||||
OrigHeader => \%GetParam,
|
||||
);
|
||||
return if !$ArticleID;
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value => "Follow up created for TicketID '$Param{TicketID}' (ArticleID: '$ArticleID')",
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLookupSet(
|
||||
ObjectLogType => 'Message',
|
||||
TargetObjectType => 'Article',
|
||||
TargetObjectID => $ArticleID,
|
||||
);
|
||||
|
||||
my %CommunicationLogSkipAttributes = (
|
||||
Body => 1,
|
||||
Attachment => 1,
|
||||
);
|
||||
|
||||
ATTRIBUTE:
|
||||
for my $Attribute ( sort keys %GetParam ) {
|
||||
next ATTRIBUTE if $CommunicationLogSkipAttributes{$Attribute};
|
||||
|
||||
my $Value = $GetParam{$Attribute};
|
||||
next ATTRIBUTE if !( defined $Value ) || !( length $Value );
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value => "$Attribute: $Value",
|
||||
);
|
||||
}
|
||||
|
||||
# write plain email to the storage
|
||||
$ArticleBackendObject->ArticleWritePlain(
|
||||
ArticleID => $ArticleID,
|
||||
Email => $Self->{ParserObject}->GetPlainEmail(),
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
# write attachments to the storage
|
||||
for my $Attachment ( $Self->{ParserObject}->GetAttachments() ) {
|
||||
$ArticleBackendObject->ArticleWriteAttachment(
|
||||
Filename => $Attachment->{Filename},
|
||||
Content => $Attachment->{Content},
|
||||
ContentType => $Attachment->{ContentType},
|
||||
ContentID => $Attachment->{ContentID},
|
||||
ContentAlternative => $Attachment->{ContentAlternative},
|
||||
Disposition => $Attachment->{Disposition},
|
||||
ArticleID => $ArticleID,
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
}
|
||||
|
||||
# dynamic fields
|
||||
$DynamicFieldList =
|
||||
$DynamicFieldObject->DynamicFieldList(
|
||||
Valid => 1,
|
||||
ResultType => 'HASH',
|
||||
ObjectType => 'Article'
|
||||
);
|
||||
|
||||
# set dynamic fields for Article object type
|
||||
DYNAMICFIELDID:
|
||||
for my $DynamicFieldID ( sort keys %{$DynamicFieldList} ) {
|
||||
next DYNAMICFIELDID if !$DynamicFieldID;
|
||||
next DYNAMICFIELDID if !$DynamicFieldList->{$DynamicFieldID};
|
||||
my $Key = 'X-OTRS-FollowUp-DynamicField-' . $DynamicFieldList->{$DynamicFieldID};
|
||||
if ( defined $GetParam{$Key} && length $GetParam{$Key} ) {
|
||||
|
||||
# get dynamic field config
|
||||
my $DynamicFieldGet = $DynamicFieldObject->DynamicFieldGet(
|
||||
ID => $DynamicFieldID,
|
||||
);
|
||||
|
||||
$DynamicFieldBackendObject->ValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldGet,
|
||||
ObjectID => $ArticleID,
|
||||
Value => $GetParam{$Key},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value => "Article DynamicField update via '$Key'! Value: $GetParam{$Key}.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# reverse dynamic field list
|
||||
%DynamicFieldListReversed = reverse %{$DynamicFieldList};
|
||||
|
||||
# set free article text
|
||||
%Values =
|
||||
(
|
||||
'X-OTRS-FollowUp-ArticleKey' => 'ArticleFreeKey',
|
||||
'X-OTRS-FollowUp-ArticleValue' => 'ArticleFreeText',
|
||||
);
|
||||
for my $Item ( sort keys %Values ) {
|
||||
for my $Count ( 1 .. 16 ) {
|
||||
my $Key = $Item . $Count;
|
||||
if (
|
||||
defined $GetParam{$Key}
|
||||
&& length $GetParam{$Key}
|
||||
&& $DynamicFieldListReversed{ $Values{$Item} . $Count }
|
||||
)
|
||||
{
|
||||
# get dynamic field config
|
||||
my $DynamicFieldGet = $DynamicFieldObject->DynamicFieldGet(
|
||||
ID => $DynamicFieldListReversed{ $Values{$Item} . $Count },
|
||||
);
|
||||
if ($DynamicFieldGet) {
|
||||
my $Success = $DynamicFieldBackendObject->ValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldGet,
|
||||
ObjectID => $ArticleID,
|
||||
Value => $GetParam{$Key},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value =>
|
||||
"Article DynamicField (ArticleKey) update via '$Key'! Value: $GetParam{$Key}.",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# set ticket title
|
||||
if ( $GetParam{'X-OTRS-FollowUp-Title'} ) {
|
||||
|
||||
$TicketObject->TicketTitleUpdate(
|
||||
Title => $GetParam{'X-OTRS-FollowUp-Title'},
|
||||
TicketID => $Param{TicketID},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value => "Title update via 'X-OTRS-FollowUp-Title'! Value: $GetParam{'X-OTRS-FollowUp-Title'}.",
|
||||
);
|
||||
}
|
||||
|
||||
# write log
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Notice',
|
||||
Key => 'Kernel::System::PostMaster::FollowUp',
|
||||
Value => "FollowUp Article to Ticket [$Param{Tn}] created "
|
||||
. "(TicketID=$Param{TicketID}, ArticleID=$ArticleID). $Comment,",
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,75 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::FollowUpCheck::Attachments;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::Ticket',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
$Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject";
|
||||
|
||||
# Get communication log object.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
||||
|
||||
# Ignore all inline parts as these are actually part of the email body.
|
||||
my @Attachments = $Self->{ParserObject}->GetAttachments();
|
||||
@Attachments = grep { defined $_->{ContentDisposition} && $_->{ContentDisposition} ne 'inline' } @Attachments;
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUpCheck::Attachments',
|
||||
Value => 'Searching for TicketNumber in email attachments.',
|
||||
);
|
||||
|
||||
ATTACHMENT:
|
||||
for my $Attachment (@Attachments) {
|
||||
|
||||
my $Tn = $TicketObject->GetTNByString( $Attachment->{Content} );
|
||||
next ATTACHMENT if !$Tn;
|
||||
|
||||
my $TicketID = $TicketObject->TicketCheckNumber( Tn => $Tn );
|
||||
|
||||
if ($TicketID) {
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUpCheck::Attachments',
|
||||
Value =>
|
||||
"Found valid TicketNumber '$Tn' (TicketID '$TicketID') in email attachment '$Attachment->{Filename}'.",
|
||||
);
|
||||
|
||||
return $TicketID;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
1;
|
||||
66
Perl OTRS/Kernel/System/PostMaster/FollowUpCheck/Body.pm
Normal file
66
Perl OTRS/Kernel/System/PostMaster/FollowUpCheck/Body.pm
Normal file
@@ -0,0 +1,66 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::FollowUpCheck::Body;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::Ticket',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
$Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject";
|
||||
|
||||
# Get communication log object.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUpCheck::Body',
|
||||
Value => 'Searching for TicketNumber in email body.',
|
||||
);
|
||||
|
||||
my $Tn = $TicketObject->GetTNByString( $Self->{ParserObject}->GetMessageBody() );
|
||||
return if !$Tn;
|
||||
|
||||
my $TicketID = $TicketObject->TicketCheckNumber( Tn => $Tn );
|
||||
|
||||
if ($TicketID) {
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUpCheck::Body',
|
||||
Value => "Found valid TicketNumber '$Tn' (TicketID '$TicketID') in email body.",
|
||||
);
|
||||
|
||||
return $TicketID;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
1;
|
||||
154
Perl OTRS/Kernel/System/PostMaster/FollowUpCheck/BounceEmail.pm
Normal file
154
Perl OTRS/Kernel/System/PostMaster/FollowUpCheck/BounceEmail.pm
Normal file
@@ -0,0 +1,154 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::FollowUpCheck::BounceEmail;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::Ticket',
|
||||
'Kernel::System::Ticket::Article',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
$Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject";
|
||||
|
||||
# Get communication log object.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
# Get Article backend object.
|
||||
$Self->{ArticleBackendObject} =
|
||||
$Kernel::OM->Get('Kernel::System::Ticket::Article')->BackendForChannel( ChannelName => 'Email' );
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
$Self->_AddCommunicationLog( Message => 'Searching for header X-OTRS-Bounce.' );
|
||||
|
||||
return if !$Param{GetParam}->{'X-OTRS-Bounce'};
|
||||
|
||||
my $BounceMessageID = $Param{GetParam}->{'X-OTRS-Bounce-OriginalMessageID'};
|
||||
|
||||
$Self->_AddCommunicationLog(
|
||||
Message => sprintf(
|
||||
'Searching for article with message id "%s".',
|
||||
$BounceMessageID,
|
||||
),
|
||||
);
|
||||
|
||||
# Look for the article that is associated with the BounceMessageID
|
||||
my %Article = $Self->{ArticleBackendObject}->ArticleGetByMessageID(
|
||||
MessageID => $BounceMessageID,
|
||||
);
|
||||
|
||||
return if !%Article;
|
||||
|
||||
$Self->_AddCommunicationLog(
|
||||
Message => sprintf(
|
||||
'Found corresponding article ID "%s".',
|
||||
$Article{ArticleID},
|
||||
),
|
||||
);
|
||||
|
||||
$Self->_SetArticleTransmissionSendError(
|
||||
%Param,
|
||||
ArticleID => $Article{ArticleID},
|
||||
);
|
||||
|
||||
return $Article{TicketID};
|
||||
}
|
||||
|
||||
sub _SetArticleTransmissionSendError {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $ArticleID = $Param{ArticleID};
|
||||
my $ArticleObject = $Kernel::OM->Get('Kernel::System::Ticket::Article');
|
||||
my $ArticleBackendObject = $ArticleObject->BackendForChannel(
|
||||
ChannelName => 'Email',
|
||||
);
|
||||
|
||||
my $BounceError = $Param{GetParam}->{'X-OTRS-Bounce-ErrorMessage'};
|
||||
my $BounceMessageID = $Param{GetParam}->{'X-OTRS-Bounce-OriginalMessageID'};
|
||||
|
||||
my $CurrentStatus = $ArticleBackendObject->ArticleGetTransmissionError(
|
||||
ArticleID => $ArticleID,
|
||||
);
|
||||
|
||||
if ($CurrentStatus) {
|
||||
|
||||
my $Result = $ArticleBackendObject->ArticleUpdateTransmissionError(
|
||||
ArticleID => $ArticleID,
|
||||
Message => $BounceError,
|
||||
);
|
||||
|
||||
if ( !$Result ) {
|
||||
|
||||
my $ErrorMessage = sprintf(
|
||||
'Error while updating transmission error for article "%s"!',
|
||||
$ArticleID,
|
||||
);
|
||||
|
||||
$Self->_AddCommunicationLog(
|
||||
Message => $ErrorMessage,
|
||||
Priority => 'Error',
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
my $Result = $ArticleBackendObject->ArticleCreateTransmissionError(
|
||||
ArticleID => $ArticleID,
|
||||
MessageID => $BounceMessageID,
|
||||
Message => $BounceError,
|
||||
);
|
||||
|
||||
if ( !$Result ) {
|
||||
|
||||
my $ErrorMessage = sprintf(
|
||||
'Error while creating transmission error for article "%s"!',
|
||||
$ArticleID,
|
||||
);
|
||||
|
||||
$Self->_AddCommunicationLog(
|
||||
Message => $ErrorMessage,
|
||||
Priority => 'Error',
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub _AddCommunicationLog {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => $Param{Priority} || 'Debug',
|
||||
Key => ref($Self),
|
||||
Value => $Param{Message},
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
1;
|
||||
66
Perl OTRS/Kernel/System/PostMaster/FollowUpCheck/RawEmail.pm
Normal file
66
Perl OTRS/Kernel/System/PostMaster/FollowUpCheck/RawEmail.pm
Normal file
@@ -0,0 +1,66 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::FollowUpCheck::RawEmail;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::Ticket',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
$Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject";
|
||||
|
||||
# Get communication log object.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUpCheck::RawEmail',
|
||||
Value => 'Searching for TicketNumber in raw email.',
|
||||
);
|
||||
|
||||
my $Tn = $TicketObject->GetTNByString( $Self->{ParserObject}->GetPlainEmail() );
|
||||
return if !$Tn;
|
||||
|
||||
my $TicketID = $TicketObject->TicketCheckNumber( Tn => $Tn );
|
||||
|
||||
if ($TicketID) {
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUpCheck::RawEmail',
|
||||
Value => "Found valid TicketNumber '$Tn' (TicketID '$TicketID') in raw email.",
|
||||
);
|
||||
|
||||
return $TicketID;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,75 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::FollowUpCheck::References;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Kernel::System::ObjectManager; # prevent used once warning
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::Ticket::Article',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
$Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject";
|
||||
|
||||
# Get communication log object.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUpCheck::References',
|
||||
Value => 'Searching for TicketID in email references.',
|
||||
);
|
||||
|
||||
my @References = $Self->{ParserObject}->GetReferences();
|
||||
return if !@References;
|
||||
|
||||
my $ArticleBackendObject = $Kernel::OM->Get('Kernel::System::Ticket::Article')->BackendForChannel(
|
||||
ChannelName => 'Email',
|
||||
);
|
||||
|
||||
for my $Reference (@References) {
|
||||
|
||||
my %Article = $ArticleBackendObject->ArticleGetByMessageID(
|
||||
MessageID => "<$Reference>",
|
||||
);
|
||||
|
||||
if (%Article) {
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUpCheck::References',
|
||||
Value => "Found valid TicketID '$Article{TicketID}' in email references.",
|
||||
);
|
||||
|
||||
return $Article{TicketID};
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
1;
|
||||
66
Perl OTRS/Kernel/System/PostMaster/FollowUpCheck/Subject.pm
Normal file
66
Perl OTRS/Kernel/System/PostMaster/FollowUpCheck/Subject.pm
Normal file
@@ -0,0 +1,66 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::FollowUpCheck::Subject;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::Ticket',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
# Get communication log object.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUpCheck::Subject',
|
||||
Value => 'Searching for TicketNumber in email subject.',
|
||||
);
|
||||
|
||||
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
||||
|
||||
my $Subject = $Param{GetParam}->{Subject} || '';
|
||||
|
||||
my $Tn = $TicketObject->GetTNByString($Subject);
|
||||
return if !$Tn;
|
||||
|
||||
my $TicketID = $TicketObject->TicketCheckNumber( Tn => $Tn );
|
||||
|
||||
if ($TicketID) {
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::FollowUpCheck::Subject',
|
||||
Value => "Found valid TicketNumber '$Tn' (TicketID '$TicketID') in email subject.",
|
||||
);
|
||||
|
||||
return $TicketID;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
1;
|
||||
71
Perl OTRS/Kernel/System/PostMaster/LoopProtection.pm
Normal file
71
Perl OTRS/Kernel/System/PostMaster/LoopProtection.pm
Normal file
@@ -0,0 +1,71 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::LoopProtection;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::Main',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub SendEmail {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# get configured backend module
|
||||
my $BackendModule = $Kernel::OM->Get('Kernel::Config')->Get('LoopProtectionModule')
|
||||
|| 'Kernel::System::PostMaster::LoopProtection::DB';
|
||||
|
||||
# get backend object
|
||||
my $BackendObject = $Kernel::OM->Get($BackendModule);
|
||||
|
||||
if ( !$BackendObject ) {
|
||||
|
||||
# get main object
|
||||
my $MainObject = $Kernel::OM->Get('Kernel::System::Main');
|
||||
|
||||
$MainObject->Die("Can't load loop protection backend module $BackendModule!");
|
||||
}
|
||||
|
||||
return $BackendObject->SendEmail(%Param);
|
||||
}
|
||||
|
||||
sub Check {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# get configured backend module
|
||||
my $BackendModule = $Kernel::OM->Get('Kernel::Config')->Get('LoopProtectionModule')
|
||||
|| 'Kernel::System::PostMaster::LoopProtection::DB';
|
||||
|
||||
# get backend object
|
||||
my $BackendObject = $Kernel::OM->Get($BackendModule);
|
||||
|
||||
if ( !$BackendObject ) {
|
||||
|
||||
# get main object
|
||||
my $MainObject = $Kernel::OM->Get('Kernel::System::Main');
|
||||
|
||||
$MainObject->Die("Can't load loop protection backend module $BackendModule!");
|
||||
}
|
||||
|
||||
return $BackendObject->Check(%Param);
|
||||
}
|
||||
|
||||
1;
|
||||
83
Perl OTRS/Kernel/System/PostMaster/LoopProtection/DB.pm
Normal file
83
Perl OTRS/Kernel/System/PostMaster/LoopProtection/DB.pm
Normal file
@@ -0,0 +1,83 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::LoopProtection::DB;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use parent 'Kernel::System::PostMaster::LoopProtectionCommon';
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::DB',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::DateTime',
|
||||
);
|
||||
|
||||
sub SendEmail {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# get database object
|
||||
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
||||
|
||||
my $To = $Param{To} || return;
|
||||
|
||||
# insert log
|
||||
return if !$DBObject->Do(
|
||||
SQL => "INSERT INTO ticket_loop_protection (sent_to, sent_date)"
|
||||
. " VALUES ('"
|
||||
. $DBObject->Quote($To)
|
||||
. "', '$Self->{LoopProtectionDate}')",
|
||||
);
|
||||
|
||||
# delete old enrties
|
||||
return if !$DBObject->Do(
|
||||
SQL => "DELETE FROM ticket_loop_protection WHERE "
|
||||
. " sent_date != '$Self->{LoopProtectionDate}'",
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub Check {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# get database object
|
||||
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
||||
|
||||
my $To = $Param{To} || return;
|
||||
my $Count = 0;
|
||||
|
||||
# check existing logfile
|
||||
my $SQL = "SELECT count(*) FROM ticket_loop_protection "
|
||||
. " WHERE sent_to = '" . $DBObject->Quote($To) . "' AND "
|
||||
. " sent_date = '$Self->{LoopProtectionDate}'";
|
||||
|
||||
$DBObject->Prepare( SQL => $SQL );
|
||||
|
||||
while ( my @Row = $DBObject->FetchrowArray() ) {
|
||||
$Count = $Row[0];
|
||||
}
|
||||
|
||||
my $Max = $Self->{PostmasterMaxEmailsPerAddress}{ lc $To } // $Self->{PostmasterMaxEmails};
|
||||
|
||||
# check possible loop
|
||||
if ( $Max && $Count >= $Max ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'notice',
|
||||
Message =>
|
||||
"LoopProtection: send no more emails to '$To'! Max. count of $Self->{PostmasterMaxEmails} has been reached!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
107
Perl OTRS/Kernel/System/PostMaster/LoopProtection/FS.pm
Normal file
107
Perl OTRS/Kernel/System/PostMaster/LoopProtection/FS.pm
Normal file
@@ -0,0 +1,107 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::LoopProtection::FS;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use parent 'Kernel::System::PostMaster::LoopProtectionCommon';
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::DateTime',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
my $Self = $Type->SUPER::new(%Param);
|
||||
|
||||
$Self->{LoopProtectionLog} = $Kernel::OM->Get('Kernel::Config')->Get('LoopProtectionLog')
|
||||
|| die 'No Config option "LoopProtectionLog"!';
|
||||
$Self->{LoopProtectionLog} .= '-' . $Self->{LoopProtectionDate} . '.log';
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub SendEmail {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $To = $Param{To} || return;
|
||||
|
||||
# write log
|
||||
## no critic
|
||||
if ( open( my $Out, '>>', $Self->{LoopProtectionLog} ) ) {
|
||||
my $DateTimeObject = $Kernel::OM->Create('Kernel::System::DateTime');
|
||||
## use critic
|
||||
print $Out "$To;" . $DateTimeObject->Format( Format => '%a %b %{day} %H:%M:%S %Y' ) . ";\n"; ## no critic
|
||||
close($Out);
|
||||
}
|
||||
else {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "LoopProtection! Can't write '$Self->{LoopProtectionLog}': $!!",
|
||||
);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub Check {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $To = $Param{To} || return;
|
||||
my $Count = 0;
|
||||
|
||||
# check existing logfile
|
||||
## no critic
|
||||
if ( !open( my $In, '<', $Self->{LoopProtectionLog} ) ) {
|
||||
## use critic
|
||||
|
||||
# create new log file
|
||||
## no critic
|
||||
if ( !open( my $Out, '>', $Self->{LoopProtectionLog} ) ) {
|
||||
## use critic
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "LoopProtection! Can't write '$Self->{LoopProtectionLog}': $!!",
|
||||
);
|
||||
}
|
||||
else {
|
||||
close($Out);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
# open old log file
|
||||
while (<$In>) {
|
||||
my @Data = split( /;/, $_ );
|
||||
if ( $Data[0] eq $To ) {
|
||||
$Count++;
|
||||
}
|
||||
}
|
||||
close($In);
|
||||
}
|
||||
|
||||
# check possible loop
|
||||
my $Max = $Self->{PostmasterMaxEmailsPerAddress}{ lc $To } // $Self->{PostmasterMaxEmails};
|
||||
|
||||
if ( $Max && $Count >= $Max ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'notice',
|
||||
Message =>
|
||||
"LoopProtection: send no more emails to '$To'! Max. count of $Self->{PostmasterMaxEmails} has been reached!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
35
Perl OTRS/Kernel/System/PostMaster/LoopProtectionCommon.pm
Normal file
35
Perl OTRS/Kernel/System/PostMaster/LoopProtectionCommon.pm
Normal file
@@ -0,0 +1,35 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
package Kernel::System::PostMaster::LoopProtectionCommon;
|
||||
## nofilter(TidyAll::Plugin::OTRS::Perl::Time)
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use utf8;
|
||||
|
||||
our $ObjectManagerDisabled = 1;
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
# get config options
|
||||
$Self->{PostmasterMaxEmails} = $Kernel::OM->Get('Kernel::Config')->Get('PostmasterMaxEmails') || 40;
|
||||
$Self->{PostmasterMaxEmailsPerAddress} =
|
||||
$Kernel::OM->Get('Kernel::Config')->Get('PostmasterMaxEmailsPerAddress') || {};
|
||||
|
||||
my $DateTimeObject = $Kernel::OM->Create('Kernel::System::DateTime');
|
||||
$Self->{LoopProtectionDate} = $DateTimeObject->Format( Format => '%Y-%m-%d' );
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
1;
|
||||
754
Perl OTRS/Kernel/System/PostMaster/NewTicket.pm
Normal file
754
Perl OTRS/Kernel/System/PostMaster/NewTicket.pm
Normal file
@@ -0,0 +1,754 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::NewTicket;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::CustomerUser',
|
||||
'Kernel::System::DynamicField',
|
||||
'Kernel::System::DynamicField::Backend',
|
||||
'Kernel::System::LinkObject',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::Priority',
|
||||
'Kernel::System::Queue',
|
||||
'Kernel::System::State',
|
||||
'Kernel::System::Ticket',
|
||||
'Kernel::System::Ticket::Article',
|
||||
'Kernel::System::DateTime',
|
||||
'Kernel::System::Type',
|
||||
'Kernel::System::User',
|
||||
'Kernel::System::Service',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
# get parser object
|
||||
$Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject!";
|
||||
|
||||
# Get communication log object.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for my $Needed (qw(InmailUserID GetParam)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
my %GetParam = %{ $Param{GetParam} };
|
||||
my $Comment = $Param{Comment} || '';
|
||||
my $AutoResponseType = $Param{AutoResponseType} || '';
|
||||
|
||||
# get queue id and name
|
||||
my $QueueID = $Param{QueueID} || die "need QueueID!";
|
||||
my $Queue = $Kernel::OM->Get('Kernel::System::Queue')->QueueLookup(
|
||||
QueueID => $QueueID,
|
||||
);
|
||||
|
||||
# get config object
|
||||
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
||||
|
||||
# get state
|
||||
my $State = $ConfigObject->Get('PostmasterDefaultState') || 'new';
|
||||
if ( $GetParam{'X-OTRS-State'} ) {
|
||||
|
||||
my $StateID = $Kernel::OM->Get('Kernel::System::State')->StateLookup(
|
||||
State => $GetParam{'X-OTRS-State'},
|
||||
);
|
||||
|
||||
if ($StateID) {
|
||||
$State = $GetParam{'X-OTRS-State'};
|
||||
}
|
||||
else {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "State $GetParam{'X-OTRS-State'} does not exist, falling back to $State!",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# get priority
|
||||
my $Priority = $ConfigObject->Get('PostmasterDefaultPriority') || '3 normal';
|
||||
|
||||
if ( $GetParam{'X-OTRS-Priority'} ) {
|
||||
|
||||
my $PriorityID = $Kernel::OM->Get('Kernel::System::Priority')->PriorityLookup(
|
||||
Priority => $GetParam{'X-OTRS-Priority'},
|
||||
);
|
||||
|
||||
if ($PriorityID) {
|
||||
$Priority = $GetParam{'X-OTRS-Priority'};
|
||||
}
|
||||
else {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "Priority $GetParam{'X-OTRS-Priority'} does not exist, falling back to $Priority!",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
my $TypeID;
|
||||
|
||||
if ( $GetParam{'X-OTRS-Type'} ) {
|
||||
|
||||
# Check if type exists
|
||||
$TypeID = $Kernel::OM->Get('Kernel::System::Type')->TypeLookup( Type => $GetParam{'X-OTRS-Type'} );
|
||||
|
||||
if ( !$TypeID ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "Type $GetParam{'X-OTRS-Type'} does not exist, falling back to default type.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# get sender email
|
||||
my @EmailAddresses = $Self->{ParserObject}->SplitAddressLine(
|
||||
Line => $GetParam{From},
|
||||
);
|
||||
for my $Address (@EmailAddresses) {
|
||||
$GetParam{SenderEmailAddress} = $Self->{ParserObject}->GetEmailAddress(
|
||||
Email => $Address,
|
||||
);
|
||||
}
|
||||
|
||||
$GetParam{SenderEmailAddress} //= '';
|
||||
|
||||
# get customer id (sender email) if there is no customer id given
|
||||
if ( !$GetParam{'X-OTRS-CustomerNo'} && $GetParam{'X-OTRS-CustomerUser'} ) {
|
||||
|
||||
# get customer user object
|
||||
my $CustomerUserObject = $Kernel::OM->Get('Kernel::System::CustomerUser');
|
||||
|
||||
# get customer user data form X-OTRS-CustomerUser
|
||||
my %CustomerData = $CustomerUserObject->CustomerUserDataGet(
|
||||
User => $GetParam{'X-OTRS-CustomerUser'},
|
||||
);
|
||||
|
||||
if (%CustomerData) {
|
||||
$GetParam{'X-OTRS-CustomerNo'} = $CustomerData{UserCustomerID};
|
||||
}
|
||||
}
|
||||
|
||||
# get customer user data form From: (sender address)
|
||||
if ( !$GetParam{'X-OTRS-CustomerUser'} ) {
|
||||
|
||||
my %CustomerData;
|
||||
if ( $GetParam{From} ) {
|
||||
|
||||
my @EmailAddresses = $Self->{ParserObject}->SplitAddressLine(
|
||||
Line => $GetParam{From},
|
||||
);
|
||||
|
||||
for my $Address (@EmailAddresses) {
|
||||
$GetParam{EmailFrom} = $Self->{ParserObject}->GetEmailAddress(
|
||||
Email => $Address,
|
||||
);
|
||||
}
|
||||
|
||||
if ( $GetParam{EmailFrom} ) {
|
||||
|
||||
# get customer user object
|
||||
my $CustomerUserObject = $Kernel::OM->Get('Kernel::System::CustomerUser');
|
||||
|
||||
my %List = $CustomerUserObject->CustomerSearch(
|
||||
PostMasterSearch => lc( $GetParam{EmailFrom} ),
|
||||
);
|
||||
|
||||
for my $UserLogin ( sort keys %List ) {
|
||||
%CustomerData = $CustomerUserObject->CustomerUserDataGet(
|
||||
User => $UserLogin,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# take CustomerID from customer backend lookup or from from field
|
||||
if ( $CustomerData{UserLogin} && !$GetParam{'X-OTRS-CustomerUser'} ) {
|
||||
$GetParam{'X-OTRS-CustomerUser'} = $CustomerData{UserLogin};
|
||||
|
||||
# notice that UserLogin is from customer source backend
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Notice',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "Take UserLogin ($CustomerData{UserLogin}) from "
|
||||
. "customer source backend based on ($GetParam{'EmailFrom'}).",
|
||||
);
|
||||
}
|
||||
if ( $CustomerData{UserCustomerID} && !$GetParam{'X-OTRS-CustomerNo'} ) {
|
||||
$GetParam{'X-OTRS-CustomerNo'} = $CustomerData{UserCustomerID};
|
||||
|
||||
# notice that UserCustomerID is from customer source backend
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Notice',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "Take UserCustomerID ($CustomerData{UserCustomerID})"
|
||||
. " from customer source backend based on ($GetParam{'EmailFrom'}).",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# if there is no customer id found!
|
||||
if (
|
||||
!$GetParam{'X-OTRS-CustomerNo'}
|
||||
&& $ConfigObject->Get('PostMaster::NewTicket::AutoAssignCustomerIDForUnknownCustomers')
|
||||
)
|
||||
{
|
||||
$GetParam{'X-OTRS-CustomerNo'} = $GetParam{SenderEmailAddress};
|
||||
}
|
||||
|
||||
# if there is no customer user found!
|
||||
if ( !$GetParam{'X-OTRS-CustomerUser'} ) {
|
||||
$GetParam{'X-OTRS-CustomerUser'} = $GetParam{SenderEmailAddress};
|
||||
}
|
||||
|
||||
# get ticket owner
|
||||
my $OwnerID = $GetParam{'X-OTRS-OwnerID'} || $Param{InmailUserID};
|
||||
if ( $GetParam{'X-OTRS-Owner'} ) {
|
||||
|
||||
my $TmpOwnerID = $Kernel::OM->Get('Kernel::System::User')->UserLookup(
|
||||
UserLogin => $GetParam{'X-OTRS-Owner'},
|
||||
);
|
||||
|
||||
$OwnerID = $TmpOwnerID || $OwnerID;
|
||||
}
|
||||
|
||||
my %Opts;
|
||||
if ( $GetParam{'X-OTRS-ResponsibleID'} ) {
|
||||
$Opts{ResponsibleID} = $GetParam{'X-OTRS-ResponsibleID'};
|
||||
}
|
||||
|
||||
if ( $GetParam{'X-OTRS-Responsible'} ) {
|
||||
|
||||
my $TmpResponsibleID = $Kernel::OM->Get('Kernel::System::User')->UserLookup(
|
||||
UserLogin => $GetParam{'X-OTRS-Responsible'},
|
||||
);
|
||||
|
||||
$Opts{ResponsibleID} = $TmpResponsibleID || $Opts{ResponsibleID};
|
||||
}
|
||||
|
||||
# get ticket object
|
||||
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "Going to create new ticket.",
|
||||
);
|
||||
|
||||
if ( $GetParam{'X-OTRS-Service'} ) {
|
||||
my $ServiceObject = $Kernel::OM->Get('Kernel::System::Service');
|
||||
|
||||
# Check if service exists.
|
||||
my %ServiceData = $ServiceObject->ServiceGet(
|
||||
Name => $GetParam{'X-OTRS-Service'},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
# Get all service list filtering by KeepChildren SysConfig if available.
|
||||
my %ServiceList = $ServiceObject->ServiceList(
|
||||
Valid => 1,
|
||||
KeepChildren => $ConfigObject->Get('Ticket::Service::KeepChildren') // 0,
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
if ( $ServiceData{ServiceID} ne '' && !$ServiceList{ $ServiceData{ServiceID} } ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value =>
|
||||
"Service $GetParam{'X-OTRS-Service'} does not exists or is invalid or is a child of invalid service.",
|
||||
);
|
||||
$GetParam{'X-OTRS-Service'} = '';
|
||||
}
|
||||
}
|
||||
|
||||
# create new ticket
|
||||
my $NewTn = $TicketObject->TicketCreateNumber();
|
||||
my $TicketID = $TicketObject->TicketCreate(
|
||||
TN => $NewTn,
|
||||
Title => $GetParam{'X-OTRS-Title'} || $GetParam{Subject},
|
||||
QueueID => $QueueID,
|
||||
Lock => $GetParam{'X-OTRS-Lock'} || 'unlock',
|
||||
Priority => $Priority,
|
||||
State => $State,
|
||||
TypeID => $TypeID,
|
||||
Service => $GetParam{'X-OTRS-Service'} || '',
|
||||
SLA => $GetParam{'X-OTRS-SLA'} || '',
|
||||
CustomerID => $GetParam{'X-OTRS-CustomerNo'},
|
||||
CustomerUser => $GetParam{'X-OTRS-CustomerUser'},
|
||||
OwnerID => $OwnerID,
|
||||
UserID => $Param{InmailUserID},
|
||||
%Opts,
|
||||
);
|
||||
|
||||
if ( !$TicketID ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "Ticket could not be created!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
my $TicketCreateMessage = <<"Message";
|
||||
New Ticket created:
|
||||
|
||||
TicketNumber: $NewTn
|
||||
TicketID: $TicketID
|
||||
Priority: $Priority
|
||||
State: $State
|
||||
CustomerID: $GetParam{'X-OTRS-CustomerNo'}
|
||||
CustomerUser: $GetParam{'X-OTRS-CustomerUser'}
|
||||
|
||||
Message
|
||||
|
||||
for my $Value (qw(Type Service SLA Lock)) {
|
||||
|
||||
if ( $GetParam{ 'X-OTRS-' . $Value } ) {
|
||||
$TicketCreateMessage .= "$Value: " . $GetParam{ 'X-OTRS-' . $Value } . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => $TicketCreateMessage,
|
||||
);
|
||||
|
||||
# set pending time
|
||||
if ( $GetParam{'X-OTRS-State-PendingTime'} ) {
|
||||
|
||||
# You can specify absolute dates like "2010-11-20 00:00:00" or relative dates, based on the arrival time of the email.
|
||||
# Use the form "+ $Number $Unit", where $Unit can be 's' (seconds), 'm' (minutes), 'h' (hours) or 'd' (days).
|
||||
# Only one unit can be specified. Examples of valid settings: "+50s" (pending in 50 seconds), "+30m" (30 minutes),
|
||||
# "+12d" (12 days). Note that settings like "+1d 12h" are not possible. You can specify "+36h" instead.
|
||||
|
||||
my $TargetTimeStamp = $GetParam{'X-OTRS-State-PendingTime'};
|
||||
|
||||
my ( $Sign, $Number, $Unit ) = $TargetTimeStamp =~ m{^\s*([+-]?)\s*(\d+)\s*([smhd]?)\s*$}smx;
|
||||
|
||||
if ($Number) {
|
||||
$Sign ||= '+';
|
||||
$Unit ||= 's';
|
||||
|
||||
my $Seconds = $Sign eq '-' ? ( $Number * -1 ) : $Number;
|
||||
|
||||
my %UnitMultiplier = (
|
||||
s => 1,
|
||||
m => 60,
|
||||
h => 60 * 60,
|
||||
d => 60 * 60 * 24,
|
||||
);
|
||||
|
||||
$Seconds = $Seconds * $UnitMultiplier{$Unit};
|
||||
|
||||
# get datetime object
|
||||
my $DateTimeObject = $Kernel::OM->Create('Kernel::System::DateTime');
|
||||
$DateTimeObject->Add( Seconds => $Seconds );
|
||||
$TargetTimeStamp = $DateTimeObject->ToString();
|
||||
}
|
||||
|
||||
my $Set = $TicketObject->TicketPendingTimeSet(
|
||||
String => $TargetTimeStamp,
|
||||
TicketID => $TicketID,
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value =>
|
||||
"Pending time update via 'X-OTRS-State-PendingTime'! State-PendingTime: $GetParam{'X-OTRS-State-PendingTime'}.",
|
||||
);
|
||||
}
|
||||
|
||||
# get dynamic field objects
|
||||
my $DynamicFieldObject = $Kernel::OM->Get('Kernel::System::DynamicField');
|
||||
my $DynamicFieldBackendObject = $Kernel::OM->Get('Kernel::System::DynamicField::Backend');
|
||||
|
||||
# dynamic fields
|
||||
my $DynamicFieldList =
|
||||
$DynamicFieldObject->DynamicFieldList(
|
||||
Valid => 1,
|
||||
ResultType => 'HASH',
|
||||
ObjectType => 'Ticket',
|
||||
);
|
||||
|
||||
# set dynamic fields for Ticket object type
|
||||
DYNAMICFIELDID:
|
||||
for my $DynamicFieldID ( sort keys %{$DynamicFieldList} ) {
|
||||
next DYNAMICFIELDID if !$DynamicFieldID;
|
||||
next DYNAMICFIELDID if !$DynamicFieldList->{$DynamicFieldID};
|
||||
my $Key = 'X-OTRS-DynamicField-' . $DynamicFieldList->{$DynamicFieldID};
|
||||
|
||||
if ( defined $GetParam{$Key} && length $GetParam{$Key} ) {
|
||||
|
||||
# get dynamic field config
|
||||
my $DynamicFieldGet = $DynamicFieldObject->DynamicFieldGet(
|
||||
ID => $DynamicFieldID,
|
||||
);
|
||||
|
||||
$DynamicFieldBackendObject->ValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldGet,
|
||||
ObjectID => $TicketID,
|
||||
Value => $GetParam{$Key},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "DynamicField update via '$Key'! Value: $GetParam{$Key}.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# reverse dynamic field list
|
||||
my %DynamicFieldListReversed = reverse %{$DynamicFieldList};
|
||||
|
||||
# set ticket free text
|
||||
# for backward compatibility (should be removed in a future version)
|
||||
my %Values =
|
||||
(
|
||||
'X-OTRS-TicketKey' => 'TicketFreeKey',
|
||||
'X-OTRS-TicketValue' => 'TicketFreeText',
|
||||
);
|
||||
for my $Item ( sort keys %Values ) {
|
||||
for my $Count ( 1 .. 16 ) {
|
||||
my $Key = $Item . $Count;
|
||||
if (
|
||||
defined $GetParam{$Key}
|
||||
&& length $GetParam{$Key}
|
||||
&& $DynamicFieldListReversed{ $Values{$Item} . $Count }
|
||||
)
|
||||
{
|
||||
# get dynamic field config
|
||||
my $DynamicFieldGet = $DynamicFieldObject->DynamicFieldGet(
|
||||
ID => $DynamicFieldListReversed{ $Values{$Item} . $Count },
|
||||
);
|
||||
if ($DynamicFieldGet) {
|
||||
my $Success = $DynamicFieldBackendObject->ValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldGet,
|
||||
ObjectID => $TicketID,
|
||||
Value => $GetParam{$Key},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "DynamicField (TicketKey$Count) update via '$Key'! Value: $GetParam{$Key}.",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# set ticket free time
|
||||
# for backward compatibility (should be removed in a future version)
|
||||
for my $Count ( 1 .. 6 ) {
|
||||
|
||||
my $Key = 'X-OTRS-TicketTime' . $Count;
|
||||
|
||||
if ( defined $GetParam{$Key} && length $GetParam{$Key} ) {
|
||||
|
||||
# get datetime object
|
||||
my $DateTimeObject = $Kernel::OM->Create(
|
||||
'Kernel::System::DateTime',
|
||||
ObjectParams => {
|
||||
String => $GetParam{$Key}
|
||||
}
|
||||
);
|
||||
|
||||
if ( $DateTimeObject && $DynamicFieldListReversed{ 'TicketFreeTime' . $Count } ) {
|
||||
|
||||
# get dynamic field config
|
||||
my $DynamicFieldGet = $DynamicFieldObject->DynamicFieldGet(
|
||||
ID => $DynamicFieldListReversed{ 'TicketFreeTime' . $Count },
|
||||
);
|
||||
|
||||
if ($DynamicFieldGet) {
|
||||
my $Success = $DynamicFieldBackendObject->ValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldGet,
|
||||
ObjectID => $TicketID,
|
||||
Value => $GetParam{$Key},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "DynamicField (TicketTime$Count) update via '$Key'! Value: $GetParam{$Key}.",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $ArticleObject = $Kernel::OM->Get('Kernel::System::Ticket::Article');
|
||||
my $ArticleBackendObject = $ArticleObject->BackendForChannel(
|
||||
ChannelName => 'Email',
|
||||
);
|
||||
|
||||
my $IsVisibleForCustomer = 1;
|
||||
if ( length $GetParam{'X-OTRS-IsVisibleForCustomer'} ) {
|
||||
$IsVisibleForCustomer = $GetParam{'X-OTRS-IsVisibleForCustomer'};
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "Going to create new article for TicketID '$TicketID'.",
|
||||
);
|
||||
|
||||
# Check if X-OTRS-SenderType exists, if not set default 'customer'.
|
||||
if ( !$ArticleObject->ArticleSenderTypeLookup( SenderType => $GetParam{'X-OTRS-SenderType'} ) )
|
||||
{
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "Can't find valid SenderType '$GetParam{'X-OTRS-SenderType'}' in DB, take 'customer'",
|
||||
);
|
||||
$GetParam{'X-OTRS-SenderType'} = 'customer';
|
||||
}
|
||||
|
||||
# Create email article.
|
||||
my $ArticleID = $ArticleBackendObject->ArticleCreate(
|
||||
TicketID => $TicketID,
|
||||
SenderType => $GetParam{'X-OTRS-SenderType'},
|
||||
IsVisibleForCustomer => $IsVisibleForCustomer,
|
||||
From => $GetParam{From},
|
||||
ReplyTo => $GetParam{ReplyTo},
|
||||
To => $GetParam{To},
|
||||
Cc => $GetParam{Cc},
|
||||
Subject => $GetParam{Subject},
|
||||
MessageID => $GetParam{'Message-ID'},
|
||||
InReplyTo => $GetParam{'In-Reply-To'},
|
||||
References => $GetParam{'References'},
|
||||
ContentType => $GetParam{'Content-Type'},
|
||||
ContentDisposition => $GetParam{'Content-Disposition'},
|
||||
Body => $GetParam{Body},
|
||||
UserID => $Param{InmailUserID},
|
||||
HistoryType => 'EmailCustomer',
|
||||
HistoryComment => "\%\%$Comment",
|
||||
OrigHeader => \%GetParam,
|
||||
AutoResponseType => $AutoResponseType,
|
||||
Queue => $Queue,
|
||||
);
|
||||
|
||||
# close ticket if article create failed!
|
||||
if ( !$ArticleID ) {
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "Can't process email with MessageID <$GetParam{'Message-ID'}>! "
|
||||
. "Please create a bug report with this email (From: $GetParam{From}, Located "
|
||||
. "under var/spool/problem-email*) on http://bugs.otrs.org/!",
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "TicketID '$TicketID' will be deleted again!",
|
||||
);
|
||||
|
||||
$TicketObject->TicketDelete(
|
||||
TicketID => $TicketID,
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLookupSet(
|
||||
ObjectLogType => 'Message',
|
||||
TargetObjectType => 'Article',
|
||||
TargetObjectID => $ArticleID,
|
||||
);
|
||||
|
||||
if ( $Param{LinkToTicketID} ) {
|
||||
|
||||
my $SourceKey = $Param{LinkToTicketID};
|
||||
my $TargetKey = $TicketID;
|
||||
|
||||
$Kernel::OM->Get('Kernel::System::LinkObject')->LinkAdd(
|
||||
SourceObject => 'Ticket',
|
||||
SourceKey => $SourceKey,
|
||||
TargetObject => 'Ticket',
|
||||
TargetKey => $TargetKey,
|
||||
Type => 'Normal',
|
||||
State => 'Valid',
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
}
|
||||
|
||||
my %CommunicationLogSkipAttributes = (
|
||||
Body => 1,
|
||||
Attachment => 1,
|
||||
);
|
||||
|
||||
ATTRIBUTE:
|
||||
for my $Attribute ( sort keys %GetParam ) {
|
||||
next ATTRIBUTE if $CommunicationLogSkipAttributes{$Attribute};
|
||||
|
||||
my $Value = $GetParam{$Attribute};
|
||||
next ATTRIBUTE if !( defined $Value ) || !( length $Value );
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "$Attribute: $Value",
|
||||
);
|
||||
}
|
||||
|
||||
# dynamic fields
|
||||
$DynamicFieldList =
|
||||
$DynamicFieldObject->DynamicFieldList(
|
||||
Valid => 1,
|
||||
ResultType => 'HASH',
|
||||
ObjectType => 'Article',
|
||||
);
|
||||
|
||||
# set dynamic fields for Article object type
|
||||
DYNAMICFIELDID:
|
||||
for my $DynamicFieldID ( sort keys %{$DynamicFieldList} ) {
|
||||
next DYNAMICFIELDID if !$DynamicFieldID;
|
||||
next DYNAMICFIELDID if !$DynamicFieldList->{$DynamicFieldID};
|
||||
my $Key = 'X-OTRS-DynamicField-' . $DynamicFieldList->{$DynamicFieldID};
|
||||
if ( defined $GetParam{$Key} && length $GetParam{$Key} ) {
|
||||
|
||||
# get dynamic field config
|
||||
my $DynamicFieldGet = $DynamicFieldObject->DynamicFieldGet(
|
||||
ID => $DynamicFieldID,
|
||||
);
|
||||
|
||||
$DynamicFieldBackendObject->ValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldGet,
|
||||
ObjectID => $ArticleID,
|
||||
Value => $GetParam{$Key},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "Article DynamicField update via '$Key'! Value: $GetParam{$Key}.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# reverse dynamic field list
|
||||
%DynamicFieldListReversed = reverse %{$DynamicFieldList};
|
||||
|
||||
# set free article text
|
||||
# for backward compatibility (should be removed in a future version)
|
||||
%Values =
|
||||
(
|
||||
'X-OTRS-ArticleKey' => 'ArticleFreeKey',
|
||||
'X-OTRS-ArticleValue' => 'ArticleFreeText',
|
||||
);
|
||||
for my $Item ( sort keys %Values ) {
|
||||
for my $Count ( 1 .. 16 ) {
|
||||
my $Key = $Item . $Count;
|
||||
if (
|
||||
defined $GetParam{$Key}
|
||||
&& length $GetParam{$Key}
|
||||
&& $DynamicFieldListReversed{ $Values{$Item} . $Count }
|
||||
)
|
||||
{
|
||||
# get dynamic field config
|
||||
my $DynamicFieldGet = $DynamicFieldObject->DynamicFieldGet(
|
||||
ID => $DynamicFieldListReversed{ $Values{$Item} . $Count },
|
||||
);
|
||||
if ($DynamicFieldGet) {
|
||||
my $Success = $DynamicFieldBackendObject->ValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldGet,
|
||||
ObjectID => $ArticleID,
|
||||
Value => $GetParam{$Key},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::NewTicket',
|
||||
Value => "Article DynamicField (ArticleKey) update via '$Key'! Value: $GetParam{$Key}.",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# write plain email to the storage
|
||||
$ArticleBackendObject->ArticleWritePlain(
|
||||
ArticleID => $ArticleID,
|
||||
Email => $Self->{ParserObject}->GetPlainEmail(),
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
# write attachments to the storage
|
||||
for my $Attachment ( $Self->{ParserObject}->GetAttachments() ) {
|
||||
$ArticleBackendObject->ArticleWriteAttachment(
|
||||
Filename => $Attachment->{Filename},
|
||||
Content => $Attachment->{Content},
|
||||
ContentType => $Attachment->{ContentType},
|
||||
ContentID => $Attachment->{ContentID},
|
||||
ContentAlternative => $Attachment->{ContentAlternative},
|
||||
Disposition => $Attachment->{Disposition},
|
||||
ArticleID => $ArticleID,
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
}
|
||||
|
||||
return $TicketID;
|
||||
}
|
||||
|
||||
1;
|
||||
271
Perl OTRS/Kernel/System/PostMaster/Reject.pm
Normal file
271
Perl OTRS/Kernel/System/PostMaster/Reject.pm
Normal file
@@ -0,0 +1,271 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::PostMaster::Reject;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::System::DynamicField',
|
||||
'Kernel::System::DynamicField::Backend',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::Ticket',
|
||||
'Kernel::System::Ticket::Article',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
# get parser object
|
||||
$Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject!";
|
||||
|
||||
# Get communication log object.
|
||||
$Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for (qw(TicketID InmailUserID GetParam Tn AutoResponseType)) {
|
||||
if ( !$Param{$_} ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Reject',
|
||||
Value => "Need $_!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
my %GetParam = %{ $Param{GetParam} };
|
||||
|
||||
# get ticket object
|
||||
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
||||
|
||||
# get ticket data
|
||||
my %Ticket = $TicketObject->TicketGet(
|
||||
TicketID => $Param{TicketID},
|
||||
DynamicFields => 0,
|
||||
);
|
||||
|
||||
my $Comment = $Param{Comment} || '';
|
||||
my $Lock = $Param{Lock} || '';
|
||||
my $AutoResponseType = $Param{AutoResponseType} || '';
|
||||
|
||||
my $ArticleObject = $Kernel::OM->Get('Kernel::System::Ticket::Article');
|
||||
my $ArticleBackendObject = $ArticleObject->BackendForChannel(
|
||||
ChannelName => 'Email',
|
||||
);
|
||||
|
||||
# Check if X-OTRS-SenderType exists, if not set default 'customer'.
|
||||
if ( !$ArticleObject->ArticleSenderTypeLookup( SenderType => $GetParam{'X-OTRS-SenderType'} ) ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Reject',
|
||||
Value => "Can't find valid SenderType '$GetParam{'X-OTRS-SenderType'}' in DB, take 'customer'",
|
||||
);
|
||||
$GetParam{'X-OTRS-SenderType'} = 'customer';
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Reject',
|
||||
Value => "Going to create new article for TicketID '$Param{TicketID}'.",
|
||||
);
|
||||
|
||||
# do db insert
|
||||
my $ArticleID = $ArticleBackendObject->ArticleCreate(
|
||||
TicketID => $Param{TicketID},
|
||||
IsVisibleForCustomer => $GetParam{'X-OTRS-IsVisibleForCustomer'} // 1,
|
||||
SenderType => $GetParam{'X-OTRS-SenderType'},
|
||||
From => $GetParam{From},
|
||||
ReplyTo => $GetParam{ReplyTo},
|
||||
To => $GetParam{To},
|
||||
Cc => $GetParam{Cc},
|
||||
Subject => $GetParam{Subject},
|
||||
MessageID => $GetParam{'Message-ID'},
|
||||
InReplyTo => $GetParam{'In-Reply-To'},
|
||||
References => $GetParam{'References'},
|
||||
ContentType => $GetParam{'Content-Type'},
|
||||
Body => $GetParam{Body},
|
||||
UserID => $Param{InmailUserID},
|
||||
HistoryType => 'FollowUp',
|
||||
HistoryComment => "\%\%$Param{Tn}\%\%$Comment",
|
||||
AutoResponseType => $AutoResponseType,
|
||||
OrigHeader => \%GetParam,
|
||||
);
|
||||
|
||||
if ( !$ArticleID ) {
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Error',
|
||||
Key => 'Kernel::System::PostMaster::Reject',
|
||||
Value => "Article could not be created!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLookupSet(
|
||||
ObjectLogType => 'Message',
|
||||
TargetObjectType => 'Article',
|
||||
TargetObjectID => $ArticleID,
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Reject',
|
||||
Value => "Reject Follow up Ticket!",
|
||||
);
|
||||
|
||||
my %CommunicationLogSkipAttributes = (
|
||||
Body => 1,
|
||||
Attachment => 1,
|
||||
);
|
||||
|
||||
ATTRIBUTE:
|
||||
for my $Attribute ( sort keys %GetParam ) {
|
||||
next ATTRIBUTE if $CommunicationLogSkipAttributes{$Attribute};
|
||||
|
||||
my $Value = $GetParam{$Attribute};
|
||||
next ATTRIBUTE if !( defined $Value ) || !( length $Value );
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Reject',
|
||||
Value => "$Attribute: $Value",
|
||||
);
|
||||
}
|
||||
|
||||
# write plain email to the storage
|
||||
$ArticleBackendObject->ArticleWritePlain(
|
||||
ArticleID => $ArticleID,
|
||||
Email => $Self->{ParserObject}->GetPlainEmail(),
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
# write attachments to the storage
|
||||
for my $Attachment ( $Self->{ParserObject}->GetAttachments() ) {
|
||||
$ArticleBackendObject->ArticleWriteAttachment(
|
||||
Filename => $Attachment->{Filename},
|
||||
Content => $Attachment->{Content},
|
||||
ContentType => $Attachment->{ContentType},
|
||||
ContentID => $Attachment->{ContentID},
|
||||
ContentAlternative => $Attachment->{ContentAlternative},
|
||||
Disposition => $Attachment->{Disposition},
|
||||
ArticleID => $ArticleID,
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
}
|
||||
|
||||
# get dynamic field objects
|
||||
my $DynamicFieldObject = $Kernel::OM->Get('Kernel::System::DynamicField');
|
||||
my $DynamicFieldBackendObject = $Kernel::OM->Get('Kernel::System::DynamicField::Backend');
|
||||
|
||||
# dynamic fields
|
||||
my $DynamicFieldList =
|
||||
$DynamicFieldObject->DynamicFieldList(
|
||||
Valid => 0,
|
||||
ResultType => 'HASH',
|
||||
ObjectType => 'Article',
|
||||
);
|
||||
|
||||
# set dynamic fields for Article object type
|
||||
DYNAMICFIELDID:
|
||||
for my $DynamicFieldID ( sort keys %{$DynamicFieldList} ) {
|
||||
next DYNAMICFIELDID if !$DynamicFieldID;
|
||||
next DYNAMICFIELDID if !$DynamicFieldList->{$DynamicFieldID};
|
||||
my $Key = 'X-OTRS-FollowUp-DynamicField-' . $DynamicFieldList->{$DynamicFieldID};
|
||||
if ( defined $GetParam{$Key} && length $GetParam{$Key} ) {
|
||||
|
||||
# get dynamic field config
|
||||
my $DynamicFieldGet = $DynamicFieldObject->DynamicFieldGet(
|
||||
ID => $DynamicFieldID,
|
||||
);
|
||||
|
||||
$DynamicFieldBackendObject->ValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldGet,
|
||||
ObjectID => $ArticleID,
|
||||
Value => $GetParam{$Key},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Reject',
|
||||
Value => "Article DynamicField update via '$Key'! Value: $GetParam{$Key}.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# reverse dynamic field list
|
||||
my %DynamicFieldListReversed = reverse %{$DynamicFieldList};
|
||||
|
||||
# set free article text
|
||||
my %Values =
|
||||
(
|
||||
'X-OTRS-FollowUp-ArticleKey' => 'ArticleFreeKey',
|
||||
'X-OTRS-FollowUp-ArticleValue' => 'ArticleFreeText',
|
||||
);
|
||||
for my $Item ( sort keys %Values ) {
|
||||
for my $Count ( 1 .. 16 ) {
|
||||
my $Key = $Item . $Count;
|
||||
if (
|
||||
defined $GetParam{$Key}
|
||||
&& length $GetParam{$Key}
|
||||
&& $DynamicFieldListReversed{ $Values{$Item} . $Count }
|
||||
)
|
||||
{
|
||||
# get dynamic field config
|
||||
my $DynamicFieldGet = $DynamicFieldObject->DynamicFieldGet(
|
||||
ID => $DynamicFieldListReversed{ $Values{$Item} . $Count },
|
||||
);
|
||||
if ($DynamicFieldGet) {
|
||||
my $Success = $DynamicFieldBackendObject->ValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldGet,
|
||||
ObjectID => $ArticleID,
|
||||
Value => $GetParam{$Key},
|
||||
UserID => $Param{InmailUserID},
|
||||
);
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Debug',
|
||||
Key => 'Kernel::System::PostMaster::Reject',
|
||||
Value =>
|
||||
"TicketKey$Count: Article DynamicField (ArticleKey) update via '$Key'! Value: $GetParam{$Key}.",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$Self->{CommunicationLogObject}->ObjectLog(
|
||||
ObjectLogType => 'Message',
|
||||
Priority => 'Notice',
|
||||
Key => 'Kernel::System::PostMaster::Reject',
|
||||
Value => "Reject FollowUp Article to Ticket [$Param{Tn}] created "
|
||||
. "(TicketID=$Param{TicketID}, ArticleID=$ArticleID). $Comment"
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
Reference in New Issue
Block a user