Kernel::System::Ticket::Article - sub module of Kernel::System::Ticket
All article functions.
ArticleCreate()
create an article
my $ArticleID = $TicketObject->ArticleCreate(
TicketID => 123,
ArticleType => 'note-internal', # email-external|email-internal|phone|fax|...
SenderType => 'agent', # agent|system|customer
From => 'Some Agent <email@example.com>', # not required but useful
To => 'Some Customer A <customer-a@example.com>', # not required but useful
Cc => 'Some Customer B <customer-b@example.com>', # not required but useful
ReplyTo => 'Some Customer B <customer-b@example.com>', # not required
Subject => 'some short description', # required
Body => 'the message text', # required
MessageID => '<asdasdasd.123@example.com>', # not required but useful
InReplyTo => '<asdasdasd.12@example.com>', # not required but useful
References => '<asdasdasd.1@example.com> <asdasdasd.12@example.com>', # not required but useful
ContentType => 'text/plain; charset=ISO-8859-15', # or optional Charset & MimeType
HistoryType => 'OwnerUpdate', # EmailCustomer|Move|AddNote|PriorityUpdate|WebRequestCustomer|...
HistoryComment => 'Some free text!',
UserID => 123,
Attachment => [
{
Content => $Content,
ContentType => $ContentType,
Filename => 'lala.txt',
},
{
Content => $Content,
ContentType => $ContentType,
Filename => 'lala1.txt',
},
],
NoAgentNotify => 0, # if you don't want to send agent notifications
AutoResponseType => 'auto reply' # auto reject|auto follow up|auto reply/new ticket|auto remove
ForceNotificationToUserID => [ 1, 43, 56 ], # if you want to force somebody
ExcludeNotificationToUserID => [ 43,56 ], # if you want full exclude somebody from notfications,
# will also be removed in To: line of article,
# higher prio as ForceNotificationToUserID
ExcludeMuteNotificationToUserID => [ 43,56 ], # the same as ExcludeNotificationToUserID but only the
# sending gets muted, agent will still shown in To:
# line of article
);
example with Charset & MimeType
and no ContentType
my $ArticleID = $TicketObject->ArticleCreate(
TicketID => 123,
ArticleType => 'note-internal', # email-external|email-internal|phone|fax|...
SenderType => 'agent', # agent|system|customer
From => 'Some Agent <email@example.com>', # not required but useful
To => 'Some Customer A <customer-a@example.com>', # not required but useful
Subject => 'some short description', # required
Body => 'the message text', # required
Charset => 'ISO-8859-15',
MimeType => 'text/plain',
HistoryType => 'OwnerUpdate', # EmailCustomer|Move|AddNote|PriorityUpdate|WebRequestCustomer|...
HistoryComment => 'Some free text!',
UserID => 123,
UnlockOnAway => 1, # Unlock ticket if owner is away
);
Events: ArticleCreate
ArticleGetTicketIDOfMessageID()
get ticket id of given message id
my $TicketID = $TicketObject->ArticleGetTicketIDOfMessageID(
MessageID => '<13231231.1231231.32131231@example.com>',
);
ArticleGetContentPath()
get article content path
my $Path = $TicketObject->ArticleGetContentPath(
ArticleID => 123,
);
ArticleSenderTypeList()
get a article sender type list
my @ArticleSenderTypeList = $TicketObject->ArticleSenderTypeList(
Result => 'ARRAY', # optional, ARRAY|HASH
);
ArticleSenderTypeLookup()
article sender lookup
my $SenderTypeID = $TicketObject->ArticleSenderTypeLookup(
SenderType => 'customer', # customer|system|agent
);
my $SenderType = $TicketObject->ArticleSenderTypeLookup(
SenderTypeID => 1,
);
ArticleTypeLookup()
article type lookup
my $ArticleTypeID = $TicketObject->ArticleTypeLookup(
ArticleType => 'webrequest-customer', # note-internal|...
);
my $ArticleType = $TicketObject->ArticleTypeLookup(
ArticleTypeID => 1,
);
ArticleTypeList()
get a article type list
my @ArticleTypeList = $TicketObject->ArticleTypeList(
Result => 'ARRAY', # optional, ARRAY|HASH
);
# to get only article types visible for customers
my @ArticleTypeList = $TicketObject->ArticleTypeList(
Result => 'ARRAY', # optional, ARRAY|HASH
Type => 'Customer', # optional to get only customer viewable article types
);
ArticleLastCustomerArticle()
get last customer article
my %Article = $TicketObject->ArticleLastCustomerArticle(
TicketID => 123,
Extended => 1, # 0 or 1, see ArticleGet(),
DynamicFields => 1, # 0 or 1, see ArticleGet(),
);
ArticleFirstArticle()
get first article
my %Article = $TicketObject->ArticleFirstArticle(
TicketID => 123,
DynamicFields => 1, # 0 or 1, see ArticleGet()
);
ArticleIndex()
returns an array with article IDs
my @ArticleIDs = $TicketObject->ArticleIndex(
TicketID => 123,
);
my @ArticleIDs = $TicketObject->ArticleIndex(
SenderType => 'customer', # optional, to limit to a certain sender type
TicketID => 123,
);
ArticleContentIndex()
returns an array with hash ref (hash contains result of ArticleGet())
my @ArticleBox = $TicketObject->ArticleContentIndex(
TicketID => 123,
DynamicFields => 1, # 0 or 1, default 1. To include or not the dynamic field values on the return structure.
UserID => 1,
Order => 'ASC', # 'ASC' or 'DESC', default 'ASC'
);
or with StripPlainBodyAsAttachment => 1
feature to not include first
attachment / body and html body as attachment
my @ArticleBox = $TicketObject->ArticleContentIndex(
TicketID => 123,
UserID => 1,
StripPlainBodyAsAttachment => 1,
);
or with StripPlainBodyAsAttachment => 2
feature to not include first
attachment / body as attachment (html body will be shown as attachment)
my @ArticleBox = $TicketObject->ArticleContentIndex(
TicketID => 123,
UserID => 1,
StripPlainBodyAsAttachment => 2,
);
returns an array with hash ref (hash contains result of ArticleGet()) only with given article types
my @ArticleBox = $TicketObject->ArticleContentIndex(
TicketID => 123,
UserID => 1,
ArticleType => [ $ArticleType1, $ArticleType2 ],
# or
ArticleTypeID => [ $ArticleTypeID1, $ArticleTypeID2 ],
);
Likewise ArticleSenderTypeID
allows filtering of only articles with
the given sender type IDs.
example of how to access the hash ref
for my $Article (@ArticleBox) {
print "From: $Article->{From}\n";
}
Note: If an attachment with html body content is available, the attachment id is returned as 'AttachmentIDOfHTMLBody' in hash ref.
You can limit the list of returned elements with the Page
and Limit
parameters:
my @ArticleBox = $TicketObject->ArticleContentIndex(
TicketID => 123,
UserID => 1,
Limit => 5,
Page => 3, # get 11th to 16th element
);
ArticleGet()
returns article data
my %Article = $TicketObject->ArticleGet(
ArticleID => 123,
DynamicFields => 1, # Optional. To include the dynamic field values for this article on the return structure.
UserID => 123,
);
Article: ArticleID From To Cc Subject Body ReplyTo MessageID InReplyTo References SenderType SenderTypeID ArticleType ArticleTypeID ContentType Charset MimeType IncomingTime
# If DynamicFields => 1 was passed, you'll get an entry like this for each dynamic field:
DynamicField_X => 'value_x',
Ticket: - see TicketGet() for ticket attributes -
returns articles in array / hash by given ticket id
my @ArticleIndex = $TicketObject->ArticleGet(
TicketID => 123,
UserID => 123,
);
returns articles in array / hash by given ticket id but only requested article types
my @ArticleIndex = $TicketObject->ArticleGet(
TicketID => 123,
ArticleType => [ $ArticleType1, $ArticleType2 ],
# or
ArticleTypeID => [ $ArticleTypeID1, $ArticleTypeID2 ],
UserID => 123,
);
returns articles in array / hash by given ticket id but only requested article sender types (could be useful when trying to exclude autoreplies sent by system sender from certain views)
my @ArticleIndex = $TicketObject->ArticleGet(
TicketID => 123,
ArticleSenderType => [ $ArticleSenderType1, $ArticleSenderType2 ],
# or
ArticleSenderTypeID => [ $ArticleSenderTypeID1, $ArticleSenderTypeID2 ],
UserID => 123,
);
to get extended ticket attributes, use param Extended - see TicketGet() for extended attributes -
my @ArticleIndex = $TicketObject->ArticleGet(
TicketID => 123,
UserID => 123,
Extended => 1,
);
to get only a dedicated count you can use Limit and Order attributes
my @ArticleIndex = $TicketObject->ArticleGet(
TicketID => 123,
UserID => 123,
Order => 'DESC', # DESC,ASC - default is ASC
Limit => 5,
);
You can also provide an offset by passing the Page
argument. To get the
6th to 10th article, you can say
my @ArticleIndex = $TicketObject->ArticleGet(
TicketID => 123,
UserID => 123,
Limit => 5,
Page => 2,
);
Page numbers start with 1.
ArticleCount()
Returns the number of articles for a ticket, possibly filtered by ArticleSenderTypeID and ArticleTypeID
my $ArticleCount = $TicketID->ArticleCount(
TicketID => 123,
ArticleTypeID => [1, 2], # optional
ArticleSenderTypeID => [1, 2], # optional
);
If the argument UpToArticleID
is given, only articles that would normally
shown before (and including) this article are shown; Order
(which can
be ASC
or DESC
) controls whether ascending or descending order is used.
ArticlePage()
Get the page number of a given article when pagination is active
my $Page = $TicketObject->ArticlePage(
TicketID => 123,
ArticleID => 4242,
RowsPerPage => 20,
ArticleTypeID => [1, 2], # optional
ArticleSenderTypeID => [1], # optional
Order => 'DESC', # optional, 'ASC' or 'DESC'
);
ArticleUpdate()
update an article
Note: Keys Body
, Subject
, From
, To
, Cc
, ReplyTo
, ArticleType
and SenderType
are implemented.
my $Success = $TicketObject->ArticleUpdate(
ArticleID => 123,
Key => 'Body',
Value => 'New Body',
UserID => 123,
TicketID => 123,
);
my $Success = $TicketObject->ArticleUpdate(
ArticleID => 123,
Key => 'ArticleType',
Value => 'email-internal',
UserID => 123,
TicketID => 123,
);
Events: ArticleUpdate
ArticleSend()
send article via email and create article with attachments
my $ArticleID = $TicketObject->ArticleSend(
TicketID => 123,
ArticleType => 'note-internal', # email-external|email-internal|phone|fax|...
SenderType => 'agent', # agent|system|customer
From => 'Some Agent <email@example.com>', # required
To => 'Some Customer A <customer-a@example.com>', # required if both Cc and Bcc are not present
Cc => 'Some Customer B <customer-b@example.com>', # required if both To and Bcc are not present
Bcc => 'Some Customer C <customer-c@example.com>', # required if both To and Cc are not present
ReplyTo => 'Some Customer B <customer-b@example.com>', # not required, is possible to use 'Reply-To' instead
Subject => 'some short description', # required
Body => 'the message text', # required
InReplyTo => '<asdasdasd.12@example.com>', # not required but useful
References => '<asdasdasd.1@example.com> <asdasdasd.12@example.com>', # not required but useful
Charset => 'iso-8859-15'
MimeType => 'text/plain',
Loop => 0, # 1|0 used for bulk emails
Attachment => [
{
Content => $Content,
ContentType => $ContentType,
Filename => 'lala.txt',
},
{
Content => $Content,
ContentType => $ContentType,
Filename => 'lala1.txt',
},
],
Sign => {
Type => 'PGP',
SubType => 'Inline|Detached',
Key => '81877F5E',
Type => 'SMIME',
Key => '3b630c80',
},
Crypt => {
Type => 'PGP',
SubType => 'Inline|Detached',
Key => '81877F5E',
Type => 'SMIME',
Key => '3b630c80',
},
HistoryType => 'OwnerUpdate', # Move|AddNote|PriorityUpdate|WebRequestCustomer|...
HistoryComment => 'Some free text!',
NoAgentNotify => 0, # if you don't want to send agent notifications
UserID => 123,
);
Events: ArticleSend
ArticleBounce()
bounce an article
my $Success = $TicketObject->ArticleBounce(
From => 'some@example.com',
To => 'webmaster@example.com',
TicketID => 123,
ArticleID => 123,
UserID => 123,
);
Events: ArticleBounce
SendAgentNotification()
send an agent notification via email
my $Success = $TicketObject->SendAgentNotification(
TicketID => 123,
CustomerMessageParams => {
SomeParams => 'For the message!',
},
Type => 'Move', # notification types, see database
RecipientID => $UserID,
UserID => 123,
);
Events: ArticleAgentNotification
SendCustomerNotification()
DEPRECATED. This function is incompatible with the rich text editor, don't use it any more!
send a customer notification via email
my $ArticleID = $TicketObject->SendCustomerNotification(
Type => 'Move', # notification types, see database
CustomerMessageParams => {
SomeParams => 'For the message!',
},
TicketID => 123,
UserID => 123,
);
Events: ArticleCustomerNotification
SendAutoResponse()
send an auto response to a customer via email
my $ArticleID = $TicketObject->SendAutoResponse(
TicketID => 123,
AutoResponseType => 'auto reply',
OrigHeader => {
From => 'some@example.com',
Subject => 'For the message!',
},
UserID => 123,
ArticleType => 'email-internal' # optional
);
Events: ArticleAutoResponse
ArticleFlagSet()
set article flags
my $Success = $TicketObject->ArticleFlagSet(
ArticleID => 123,
Key => 'Seen',
Value => 1,
UserID => 123,
);
Events: ArticleFlagSet
ArticleFlagDelete()
delete article flag
my $Success = $TicketObject->ArticleFlagDelete(
ArticleID => 123,
Key => 'seen',
UserID => 123,
);
my $Success = $TicketObject->ArticleFlagDelete(
ArticleID => 123,
Key => 'seen',
AllUsers => 1, # delete for all users
);
Events: ArticleFlagDelete
ArticleFlagGet()
get article flags
my %Flags = $TicketObject->ArticleFlagGet(
ArticleID => 123,
UserID => 123,
);
ArticleFlagsOfTicketGet()
get all article flags of a ticket
my %Flags = $TicketObject->ArticleFlagsOfTicketGet(
TicketID => 123,
UserID => 123,
);
returns (
123 => { # ArticleID
'Seen' => 1,
'Other' => 'something',
},
)
ArticleAccountedTimeGet()
returns the accounted time of a article.
my $AccountedTime = $TicketObject->ArticleAccountedTimeGet(
ArticleID => $ArticleID,
);
ArticleAccountedTimeDelete()
delete accounted time of article
my $Success = $TicketObject->ArticleAccountedTimeDelete(
ArticleID => $ArticleID,
);
ArticleDelete()
delete an article, its plain message, and all attachments
my $Success = $TicketObject->ArticleDelete(
ArticleID => 123,
UserID => 123,
);
ArticleDeletePlain()
delete a plain article
my $Success = $TicketObject->ArticleDeletePlain(
ArticleID => 123,
UserID => 123,
);
ArticleDeleteAttachment()
delete all attachments of an article
my $Success = $TicketObject->ArticleDeleteAttachment(
ArticleID => 123,
UserID => 123,
);
ArticleWritePlain()
write a plain email to storage
my $Success = $TicketObject->ArticleWritePlain(
ArticleID => 123,
Email => $EmailAsString,
UserID => 123,
);
ArticlePlain()
get plain article/email
my $PlainMessage = $TicketObject->ArticlePlain(
ArticleID => 123,
UserID => 123,
);
ArticleWriteAttachment()
write an article attachment to storage
my $Success = $TicketObject->ArticleWriteAttachment(
Content => $ContentAsString,
ContentType => 'text/html; charset="iso-8859-15"',
Filename => 'lala.html',
ContentID => 'cid-1234', # optional
ContentAlternative => 0, # optional, alternative content to shown as body
Disposition => 'attachment', # or 'inline'
ArticleID => 123,
UserID => 123,
);
You also can use Force => 1
to not check if a filename already exists, it force to use the given file name. Otherwise a new file name like oldfile-2.html
is used.
ArticleAttachment()
get article attachment (Content, ContentType, Filename and optional ContentID, ContentAlternative)
my %Attachment = $TicketObject->ArticleAttachment(
ArticleID => 123,
FileID => 1, # as returned by ArticleAttachmentIndex
UserID => 123,
);
returns:
my %Attachment = (
Content => "xxxx", # actual attachment contents
ContentAlternative => "",
ContentID => "",
ContentType => "application/pdf",
Filename => "StdAttachment-Test1.pdf",
Filesize => "4.6 KBytes",
FilesizeRaw => 4722,
Disposition => 'attachment',
);
ArticleAttachmentIndex()
get article attachment index as hash
(ID => hashref (Filename, Filesize, ContentID (if exists), ContentAlternative(if exists) ))
my %Index = $TicketObject->ArticleAttachmentIndex(
ArticleID => 123,
UserID => 123,
);
or with StripPlainBodyAsAttachment => 1
feature to not include first
attachment (not include text body, html body as attachment and inline attachments)
my %Index = $TicketObject->ArticleAttachmentIndex(
ArticleID => 123,
UserID => 123,
Article => \%Article,
StripPlainBodyAsAttachment => 1,
);
or with StripPlainBodyAsAttachment => 2
feature to not include first
attachment (not include text body as attachment)
my %Index = $TicketObject->ArticleAttachmentIndex(
ArticleID => 123,
UserID => 123,
Article => \%Article,
StripPlainBodyAsAttachment => 2,
);
or with StripPlainBodyAsAttachment => 3
feature to not include first
attachment (not include text body and html body as attachment)
my %Index = $TicketObject->ArticleAttachmentIndex(
ArticleID => 123,
UserID => 123,
Article => \%Article,
StripPlainBodyAsAttachment => 3,
);
returns:
my %Index = {
'1' => {
ContentAlternative => '',
ContentID => '',
Filesize => '4.6 KBytes',
ContentType => 'application/pdf',
Filename => 'StdAttachment-Test1.pdf',
FilesizeRaw => 4722,
Disposition => attachment,
},
'2' => {
ContentAlternative => '',
ContentID => '',
Filesize => '183 Bytes',
ContentType => 'text/html; charset="utf-8"',
Filename => 'file-2',
FilesizeRaw => 183,
Disposition => attachment,
},
};
This software is part of the OTRS project (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 https://www.gnu.org/licenses/gpl-3.0.txt.