- NAME
- SYNOPSIS
- DESCRIPTION
  - Format
    - SkipCreate
  - Acceptable Fields
- METHODS
  - Parse
  - _ParseMultilineTemplate
  - _ParseXSVTemplate

# NAME

RT::Action::CreateTickets - Create one or more tickets according to an externally supplied template

# SYNOPSIS

     ===Create-Ticket: codereview
     Subject: Code review for {$Tickets{'TOP'}->Subject}
     Depended-On-By: TOP
     Content: Someone has created a ticket. you should review and approve it,
     so they can finish their work
     ENDOFCONTENT

# DESCRIPTION

The CreateTickets ScripAction allows you to create automated workflows in RT, creating new tickets in response to actions and conditions from other tickets.

## Format

CreateTickets uses the RT template configured in the scrip as a template for an ordered set of tickets to create. The basic format is as follows:

     ===Create-Ticket: identifier
     Param: Value
     Param2: Value
     Param3: Value
     Content: Blah
     blah
     blah
     ENDOFCONTENT
     ===Create-Ticket: id2
     Param: Value
     Content: Blah
     ENDOFCONTENT

As shown, you can put one or more `===Create-Ticket:` sections in a template. Each `===Create-Ticket:` section is evaluated as its own Text::Template object, which means that you can embed snippets of Perl inside the Text::Template using `{}` delimiters, but that such sections absolutely can not span a `===Create-Ticket:` boundary.

Note that each `Value` must come right after the `Param` on the same line. The `Content:` param can extend over multiple lines, but the text of the first line must start right after `Content:`. Don't try to start your `Content:` section with a newline.

After each ticket is created, it's stuffed into a hash called `%Tickets` making it available during the creation of other tickets during the same ScripAction. The hash key for each ticket is `create-[identifier]`, where `[identifier]` is the value you put after `===Create-Ticket:`. The hash is prepopulated with the ticket which triggered the ScripAction as `$Tickets{'TOP'}`. You can also access that ticket using the shorthand `TOP`.

A simple example:

     ===Create-Ticket: codereview
     Subject: Code review for {$Tickets{'TOP'}->Subject}
     Depended-On-By: TOP
     Content: Someone has created a ticket. you should review and approve it,
     so they can finish their work
     ENDOFCONTENT

A convoluted example:

     ===Create-Ticket: approval
     { # Find out who the administrators of the group called "HR"
       # of which the creator of this ticket is a member
        my $name = "HR";

        my $groups = RT::Groups->new(RT->SystemUser);
        $groups->LimitToUserDefinedGroups();
        $groups->Limit(FIELD => "Name", OPERATOR => "=", VALUE => $name, CASESENSITIVE => 0);
        $groups->WithMember(PrincipalId => $TransactionObj->CreatorObj->Id);

        my $groupid = $groups->First->Id;

        my $adminccs = RT::Users->new(RT->SystemUser);
        $adminccs->WhoHaveRight(
            Right => "AdminGroup",
            Object =>$groups->First,
            IncludeSystemRights => undef,
            IncludeSuperusers => 0,
            IncludeSubgroupMembers => 0,
        );

         our @admins;
         while (my $admin = $adminccs->Next) {
             push (@admins, $admin->EmailAddress);
         }
     }
     Queue: ___Approvals
     Type: approval
     AdminCc: {join ("\nAdminCc: ",@admins) }
     Depended-On-By: TOP
     Refers-To: TOP
     Subject: Approval for ticket: {$Tickets{"TOP"}->Id} - {$Tickets{"TOP"}->Subject}
     Due: {time + 86400}
     Content-Type: text/plain
     Content: Your approval is requested for the ticket {$Tickets{"TOP"}->Id}: {$Tickets{"TOP"}->Subject}
     Blah
     Blah
     ENDOFCONTENT
     ===Create-Ticket: two
     Subject: Manager approval
     Type: approval
     Depended-On-By: TOP
     Refers-To: {$Tickets{"create-approval"}->Id}
     Queue: ___Approvals
     Content-Type: text/plain
     Content: Your approval is required for this ticket, too.
     ENDOFCONTENT

As shown above, you can include a block with Perl code to set up some values for the new tickets. If you want to access a variable in the template section after the block, you must scope it with `our` rather than `my`. Just as with other RT templates, you can also include Perl code in the template sections using `{}`.

### SkipCreate

This flag allows for ticket creation to be skipped programmatically. Taking a look at the example above the template creates two different tickets, maybe a second approval ticket shouldn't be created if the ticket's priority is low. Using Perl logic we can check some information about the ticket and decide using this flag if we should skip creating this ticket:

     ===Create-Ticket: two
     SkipCreate: {$Tickets{'TOP'}->PriorityAsString eq 'Low' ? 1 : 0}
     Subject: Manager approval
     Type: approval
     Depended-On-By: TOP
     Refers-To: {$Tickets{"create-approval"}->Id}
     Queue: ___Approvals
     Content-Type: text/plain
     Content: Your approval is required for this ticket, too.
     ENDOFCONTENT

## Acceptable Fields

A complete list of acceptable fields:

        *  Queue           => Name or id# of a queue
           Subject         => A text string
         ! Status          => A valid status. Defaults to 'new'
           SLA             => A valid SLA level
           Due             => Dates can be specified in seconds since the epoch
                              to be handled literally or in a semi-free textual
                              format which RT will attempt to parse.
           Starts          =>
           Started         =>
           Resolved        =>
           Owner           => Username or id of an RT user who can and should own
                              this ticket; forces the owner if necessary
       +   Requestor       => Email address
       +   Cc              => Email address
       +   AdminCc         => Email address
       +   RequestorGroup  => Group name
       +   CcGroup         => Group name
       +   AdminCcGroup    => Group name
           TimeWorked      =>
           TimeEstimated   =>
           TimeLeft        =>
           InitialPriority =>
           FinalPriority   =>
           Type            =>
        +! DependsOn       =>
        +! DependedOnBy    =>
        +! RefersTo        =>
        +! ReferredToBy    =>
        +! Members         =>
        +! MemberOf        =>
           Content         => Content. Can extend to multiple lines. Everything
                              within a template after a Content: header is treated
                              as content until we hit a line containing only
                              ENDOFCONTENT
           ContentType     => the content-type of the Content field.  Defaults to
                              'text/plain'
           UpdateType      => 'correspond' or 'comment'; used in conjunction with
                              'content' if this is an update.  Defaults to
                              'correspond'

           CustomField-<id#> => custom field value
           CF-name           => custom field value
           CustomField-name  => custom field value

           SkipCreate        => 0/1, if true, skip this create ticket block

           CustomRole-<id#> => custom role email address
           CR-name          => custom role email address
           CustomRole-name  => custom role email address

Fields marked with an `*` are required.

Fields marked with a `+` may have multiple values, simply by repeating the field-name on a new line with an additional value.

Fields marked with a `!` have processing postponed until after all tickets in the same actions are created. Except for `Status`, those fields can also take a ticket name within the same action (i.e. the identifiers after `===Create-Ticket:`), instead of raw ticket ID numbers.

When parsed, field names are converted to lowercase and have hyphens stripped. `Refers-To`, `RefersTo`, `refersto`, `refers-to` and `r-e-f-er-s-tO` will all be treated as the same thing.

# METHODS

## Parse

Takes (in order) template content, a default queue, a default requestor, and active (a boolean flag).

Parses a template in the template content, defaulting queue and requestor if unspecified in the template to the values provided as arguments.

If the active flag is true, then we'll use Text::Template to parse the templates, allowing you to embed active Perl in your templates.

## _ParseMultilineTemplate

Parses mulitline templates. Things like:

     ===Create-Ticket: ...

Takes the same arguments as "Parse".

## _ParseXSVTemplate

Parses a tab or comma delimited template. Should only ever be called by "Parse".

← Back to index