How to Link / Get Config Item to a Ticket through

2020-02-26 13:21发布

问题:

I want to know how to get and link the ticket to Configuration item through SOAP or REST Webservice. I have imported this Restfull Web service in admin console and successfully created and getting ticket information using this url http://XXX.XXX.XXX.XXX/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/Ticket/1.

but the problem is the linked config item information is not coming when i get the ticket information.

i did lots of search on google found that ticket can be linked to Config Item through OTRS GUI and in AgentTicketzoom page it will show, i want this to be done through web service. can any one help me in this problem or suggest some doc on how to create web service to get linked object information from ticket.

Updated#1

i added web controller to my existing Ticket connector successfully. the url is http://XXX.XXX.XXX.XXX/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorRest/LinkObject with POST Call.but i am getting this error

{"faultcode":"Server","faultstring":"Got no ConfigObject!"}

i checked the initial parameters also

$VAR1 = {  'Password' => '1234567',  'RequestMethod' => 'POST','SourceKey' => '1',  'SourceObject' => 'Ticket',  'State' => 'valid',  'TargetKey' => '2',  'TargetObject' => 'ITSMConfigItem',  'Type' => 'ParentChild',  'UserID' => '1',  'UserLogin' => 'XXXXX.XXXX@XXXX.com'};

$VAR1 = {  'ErrorMessage' => 'Got no ConfigObject!',  'Success' => 0};

回答1:

Yes, the ticket can be linked to a configItem via a GUI and it can be done via a Webservice.

First of all you should write a new Generic Interface Connector operation, which will handle method LinkAdd from LinkObject Class ( APIdoc )

Then create and register new operations via a new XML file, like this:

FILE NAME: GenericInterfaceLinkObjectConnector.xml

<?xml version="1.0" encoding="utf-8"?>
<otrs_config version="1.0" init="Application">
<ConfigItem Name="GenericInterface::Operation::Module###LinkObject::LinkAdd" Required="0" Valid="1">
        <Description Translatable="1">GenericInterface module registration for the operation layer.</Description>
        <Group>GenericInterface</Group>
        <SubGroup>GenericInterface::Operation::ModuleRegistration</SubGroup>
        <Setting>
            <Hash>
                <Item Key="Name">LinkAdd</Item>
                <Item Key="Controller">LinkObject</Item>
                <Item Key="ConfigDialog">AdminGenericInterfaceOperationDefault</Item>
            </Hash>
        </Setting>
    </ConfigItem>
</otrs_config>

After that you can publish a new provider WebService from OTRS GUI, where a newly created connector is used.

Make sure, that you pass all the needed parameters for the method!!!

 $True = $LinkObject->LinkAdd(
    SourceObject => 'Ticket',
    SourceKey    => '321',
    TargetObject => 'FAQ',
    TargetKey    => '5',
    Type         => 'ParentChild',
    State        => 'Valid',
    UserID       => 1,
);

UPDATE:

Please read this Document to understand how Generic Interface is built and then please add a new Connector ( LinkObject )

To register the connector and its operation - place XML file in /Kernel/Config/Files/...

Then go to Sysconfig -> GenericInterface -> GenericInterface::Operation::ModuleRegistration and set a tick next to the GenericInterface::Operation::Module###LinkObject::LinkAdd and save changes

Afterwards add this Connector file to /Custom/Kernel/GenericInterface/Operation/LinkObject/LinkAdd.pm

# --
# Kernel/GenericInterface/Operation/LinkObject/LinkAdd.pm - GenericInterface LinkAdd operation backend
# Copyright (C) 2016 ArtyCo (Artjoms Petrovs), http://artjoms.lv/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (AGPL). If you
# did not receive this file, see http://www.gnu.org/licenses/agpl.txt.
# --

package Kernel::GenericInterface::Operation::LinkObject::LinkAdd;

use strict;
use warnings;

use Kernel::GenericInterface::Operation::Common;
use Kernel::System::LinkObject;
use Kernel::System::VariableCheck qw(IsStringWithData IsHashRefWithData);

=head1 NAME

Kernel::GenericInterface::Operation::LinkObject::LinkAdd - GenericInterface Link Create Operation backend

=head1 SYNOPSIS

=head1 PUBLIC INTERFACE

=over 4

=cut

=item new()

usually, you want to create an instance of this
by using Kernel::GenericInterface::Operation->new();

=cut

sub new {
    my ( $Type, %Param ) = @_;

    my $Self = {};
    bless( $Self, $Type );

    # check needed objects
    for my $Needed (
        qw(DebuggerObject ConfigObject MainObject LogObject TimeObject DBObject EncodeObject WebserviceID)
        )
    {
        if ( !$Param{$Needed} ) {
            return {
                Success      => 0,
                ErrorMessage => "Got no $Needed!"
            };
        }

        $Self->{$Needed} = $Param{$Needed};
    }

    # create additional objects
    $Self->{CommonObject} = Kernel::GenericInterface::Operation::Common->new( %{$Self} );
    $Self->{LinkObject}
        = Kernel::System->LinkObject->new( %{$Self} );

    return $Self;
}

=item Run()

Create a new link.

    my $Result = $OperationObject->Run(
        Data => {
            SourceObject => 'Ticket',
            SourceKey    => '321',
            TargetObject => 'Ticket',
            TargetKey    => '12345',
            Type         => 'ParentChild',
            State        => 'Valid',
            UserID       => 1,
        },
    );

    $Result = {
        Success      => 1,                                # 0 or 1
        ErrorMessage => '',                               # In case of an error
        Data         => {
            Result => 1,                                  # 0 or 1 
        },
    };

=cut

sub Run {
    my ( $Self, %Param ) = @_;

    # check needed stuff
    if ( !IsHashRefWithData( $Param{Data} ) ) {
        return $Self->{CommonObject}->ReturnError(
            ErrorCode    => 'LinkAdd.MissingParameter',
            ErrorMessage => "LinkAdd: The request is empty!",
        );
    }



    my $LinkID = $Self->{LinkObject}->LinkAdd(
        %Param,
    );

    if ( !$LinkID ) {
        return $Self->{CommonObject}->ReturnError(
            ErrorCode    => 'LinkAdd.AuthFail',
            ErrorMessage => "LinkAdd: Authorization failing!",
        );
    }

    return {
        Success => 1,
        Data    => {
            Result => $LinkID,
        },
    };
}

1;

=back

=head1 TERMS AND CONDITIONS

This software is part of the OTRS project (L<http://otrs.org/>).

This software comes with ABSOLUTELY NO WARRANTY. For details, see
the enclosed file COPYING for license information (AGPL). If you
did not receive this file, see L<http://www.gnu.org/licenses/agpl.txt>.

=cut

And afterwards it should appear and can be used from the Admin -> WebServices -> Available Operations dropdown and of course can be used as a webservice.

A PHP usage example can be seen below:

    #### Initialize new client session ####
$client = new SoapClient(
 null, 
 array(
 'location' => $url,
 'uri' => "Core",
 'trace' => 1,
 'login' => $username,
 'password' => $password,
 'style' => SOAP_RPC,
 'use' => SOAP_ENCODED
 )
);
#### Create and send the SOAP Function Call ####
$success = $client->__soapCall("Dispatch", 
array($username, $password,
"LinkObject", "LinkAdd",
"SourceObject", 'Ticket',
"SourceKey", $ticket_id1,
"TargetObject", 'Ticket',
"TargetKey", $ticket_id2,
"Type", 'ParentChild',
"State", 'Valid',
"UserID", '1'
));

In case of errors - enable debugging, review the System Log and check all the initial settings of OTRS

Good Luck!

UPDATE #2

To register a webservice - press the button Add new webservice, name it as you want it and set the following settings ( Select the LinkAdd Operation ) and save it

UPDATE #3

Here is an updated module file for OTRS 5

    # --
# Kernel/GenericInterface/Operation/LinkObject/LinkAdd.pm - GenericInterface LinkAdd operation backend
# Copyright (C) 2016 ArtyCo (Artjoms Petrovs), http://artjoms.lv/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (AGPL). If you
# did not receive this file, see http://www.gnu.org/licenses/agpl.txt.
# --

package Kernel::GenericInterface::Operation::LinkObject::LinkAdd;

use strict;
use warnings;

use Kernel::GenericInterface::Operation::Common;
use Kernel::System::LinkObject;
use Kernel::System::VariableCheck qw(IsStringWithData IsHashRefWithData);

=head1 NAME

Kernel::GenericInterface::Operation::LinkObject::LinkAdd - GenericInterface Link Create Operation backend

=head1 SYNOPSIS

=head1 PUBLIC INTERFACE

=over 4

=cut

=item new()

usually, you want to create an instance of this
by using Kernel::GenericInterface::Operation->new();

=cut

sub new {
    my ( $Type, %Param ) = @_;

    my $Self = {};
    bless( $Self, $Type );

    # check needed objects
    for my $Needed (
        qw( DebuggerObject WebserviceID )
        )
    {
        if ( !$Param{$Needed} ) {
            return {
                Success      => 0,
                ErrorMessage => "Got no $Needed!"
            };
        }

        $Self->{$Needed} = $Param{$Needed};
    }

    # create additional objects
    $Self->{CommonObject} = Kernel::GenericInterface::Operation::Common->new( %{$Self} );
    $Self->{LinkObject}
        = $Kernel::OM->Get('Kernel::System::LinkObject');

    return $Self;
}

=item Run()

Create a new link.

    my $Result = $OperationObject->Run(
        Data => {
            SourceObject => 'Ticket',
            SourceKey    => '321',
            TargetObject => 'Ticket',
            TargetKey    => '12345',
            Type         => 'ParentChild',
            State        => 'Valid',
            UserID       => 1,
        },
    );

    $Result = {
        Success      => 1,                                # 0 or 1
        ErrorMessage => '',                               # In case of an error
        Data         => {
            Result => 1,                                  # 0 or 1 
        },
    };

=cut

sub Run {
    my ( $Self, %Param ) = @_;

    # check needed stuff
    if ( !IsHashRefWithData( $Param{Data} ) ) {
        return $Self->{CommonObject}->ReturnError(
            ErrorCode    => 'LinkAdd.MissingParameter',
            ErrorMessage => "LinkAdd: The request is empty!",
        );
    }



    my $LinkID = $Self->{LinkObject}->LinkAdd(
        %Param,
    );

    if ( !$LinkID ) {
        return $Self->{CommonObject}->ReturnError(
            ErrorCode    => 'LinkAdd.AuthFail',
            ErrorMessage => "LinkAdd: Authorization failing!",
        );
    }

    return {
        Success => 1,
        Data    => {
            Result => $LinkID,
        },
    };
}

1;

=back

=head1 TERMS AND CONDITIONS

This software is part of the OTRS project (L<http://otrs.org/>).

This software comes with ABSOLUTELY NO WARRANTY. For details, see
the enclosed file COPYING for license information (AGPL). If you
did not receive this file, see L<http://www.gnu.org/licenses/agpl.txt>.

=cut


回答2:

After lot of work, i've found the solution to made it by POST REST call. My main trouble was about creating LinkObject with right %Param. So, i've implement direct code to aquire right call LinkAdd. Mainly, Artjoman provide the way. But i catch some errors on it, so here is another perl module in OTRS_HOME/Custom/Kernel/GenericInterface/Operation/LinkObject/LinkAdd.pm:

# --
# Kernel/GenericInterface/Operation/LinkObject/LinkAdd.pm - GenericInterface LinkAdd operation backend
# Copyright (C) 2016 ArtyCo (Artjoms Petrovs), http://artjoms.lv/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (AGPL). If you
# did not receive this file, see http://www.gnu.org/licenses/agpl.txt.
# --

package Kernel::GenericInterface::Operation::LinkObject::LinkAdd;

use strict;
use warnings;

use Kernel::System::ObjectManager;
use Kernel::System::VariableCheck qw(IsStringWithData IsHashRefWithData);

=head1 NAME

Kernel::GenericInterface::Operation::LinkObject::LinkAdd - GenericInterface Link Create Operation backend

=head1 SYNOPSIS

=head1 PUBLIC INTERFACE

=over 4

=cut

=item new()

usually, you want to create an instance of this
by using Kernel::GenericInterface::Operation->new();

=cut

sub new {
    my ( $Type, %Param ) = @_;

    my $Self = {};
    bless( $Self, $Type );

    # check needed objects
    for my $Needed (
        qw( DebuggerObject WebserviceID )
        )
    {
        if ( !$Param{$Needed} ) {
            return {
                Success      => 0,
                ErrorMessage => "Got no $Needed!"
            };
        }

        $Self->{$Needed} = $Param{$Needed};
    }

    # create additional objects

    local $Kernel::OM = Kernel::System::ObjectManager->new( %{$Self} );
    $Self->{LinkObject}
        = $Kernel::OM->Get('Kernel::System::LinkObject');

    return $Self;
}

=item Run()

Create a new link.

    my $Result = $OperationObject->Run(
        Data => {
            SourceObject => 'Ticket',
            SourceKey    => '321',
            TargetObject => 'Ticket',
            TargetKey    => '12345',
            Type         => 'ParentChild',
            State        => 'Valid',
            UserID       => 1,
        },
    );

    $Result = {
        Success      => 1,                                # 0 or 1
        ErrorMessage => '',                               # In case of an error
        Data         => {
            Result => 1,                                  # 0 or 1 
        },
    };

=cut

sub Run {
    my ( $Self, %Param ) = @_;

    # check needed stuff
    if ( !IsHashRefWithData( $Param{Data} ) ) {
        return $Self->ReturnError(
            ErrorCode    => 'LinkAdd.MissingParameter',
            ErrorMessage => "LinkAdd: The request is empty!",
        );
    }

    my $LinkID = $Self->{LinkObject}->LinkAdd(
        'SourceKey' => $Param{Data}{SourceKey},
        'SourceObject' => $Param{Data}{SourceObject},
        'State' => $Param{Data}{State},
        'TargetKey' => $Param{Data}{TargetKey},
        'TargetObject' => $Param{Data}{TargetObject},
        'Type' => $Param{Data}{Type},
        'UserID' => $Param{Data}{UserID},
    );

    if ( !$LinkID ) {
        return $Self->ReturnError(
            ErrorCode    => 'LinkAdd.AuthFail',
            ErrorMessage => "LinkAdd: Authorization failing!",
        );
    }

    return {
        Success => 1,
        Data    => {
            Result => $LinkID,
        },
    };
}

sub ReturnError {
    my ( $Self, %Param ) = @_;

    $Self->{DebuggerObject}->Error(
        Summary => $Param{ErrorCode},
        Data    => $Param{ErrorMessage},
    );

    # return structure
    return {
        Success      => 1,
        ErrorMessage => "$Param{ErrorCode}: $Param{ErrorMessage}",
        Data         => {
            Error => {
                ErrorCode    => $Param{ErrorCode},
                ErrorMessage => $Param{ErrorMessage},
            },
        },
    };
}

1;

=back

=head1 TERMS AND CONDITIONS

This software is part of the OTRS project (L<http://otrs.org/>).

This software comes with ABSOLUTELY NO WARRANTY. For details, see
the enclosed file COPYING for license information (AGPL). If you
did not receive this file, see L<http://www.gnu.org/licenses/agpl.txt>.

=cut

So, making POST call to (http://otrs_host/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/LinkAdd?UserLogin=login&Password=password) with json

{"SourceObject":"Ticket","SourceKey":"7","TargetObject":"ITSMConfigItem","TargetKey":"1","Type":"DependsOn","State":"Valid","UserID":"1"}

will create a link between Ticket and ITSMConfigItem (not a computer, hardware and so on.) I think, this simple and quite rude solution will help to understand how to add a full-api operations to your REST otrs with a better(but working) way.