ELI5: Automating extraction of new-ticket content with a Scrip

I’ve spent a few hours trying to solve this myself and am still missing (or, forgetting) some key part of what is required, so, I’ll describe what I’m after, and if anyone is patient enough to walk me through how to do what I want, like I’m 5, it would be appreciated.

Goal: I have automated content being sent to a specific queue in RT. The tickets are not interacted with within RT in any way, merely resolved. No comments, no replies, etc. The email that creates the ticket contains certain pre-formatted data that I would like to extract and save into a file. That file will then be read by Splunk for other purposes.

The content that arrives looks similar to this:

Source: 12381238123
Destination: 6234234
Submit Date: Tue, 21 Feb 2023 08:22:31 +1000

What I’m after is the JSON text that comes after the Text:\n. I would like just that JSON to be appended to a file on the local filesystem, ideally.

My initial approach was to try to create a custom Scrip for the queue where this email arrives, but I could not figure out what could be configured in the Web UI versus what had to be a Perl file.

I wasn’t sure if I could solve it all with the right perl in the Custom condition, Custom action preparation code, or Custom action commit code boxes, for example. I ended up trying to call a Perl snippet from the “Custom action commit code” box, but that sent me down a path of errors along the lines of

Commit failed: Can’t call method “TransactionObj” on an undefined value

And frustration built.

My Custom Action Commit code was:

# Set the path to the RT etc directory
my $etc_dir = RT->Config->Get('etc_path');

# Set the path to the SaveEmailToFile Scrip
my $scrip_path = "$etc_dir/SaveEmailToFile.pm";

# Load the SaveEmailToFile Scrip code
require $scrip_path;

# Call the SaveEmailToFile function

But my Perl is nowhere near good enough to do the SaveEmailToFile function correctly, it turns out.

At the risk of raucous laughter, the code is:

sub SaveEmailToFile {
    my ($self) = @_;

    # Set the name of the file where the email content will be saved
    my $filename = '/tmp/testing.txt';

    # Get the email message
    my $message = $self->TransactionObj->Content;

    # Check if the ticket belongs to Queue 11
    my $queue_id = $self->TicketObj->QueueObj->Id;
    if ($queue_id == 11 && $message =~ /Text:\n{"q":/) {
        # Save the email message to a file
        open(my $fh, '>>', $filename) or die "Could not open file '$filename' $!";
        print $fh $message;
        close $fh;
    } else {
        # Generate a warning message
        RT::Logger->warning("SaveEmailToFile Scrip executed on ticket in invalid queue (queue_id = $queue_id) or something else failed.");

    # Return a true value
    return 1;

I must have been getting close, as I was able to invoke the SaveEmailToFile.pm, but, parsing the message content and saving it into a file was not happening. Obviously, I wasn’t looking at just the JSON extraction here, I was trying to get ANYTHING to dump out.

The checking for the queue ID was a sanity check to ensure I didn’t try to run this code on another queue, but is obviously optional (since I wanted to create the Scrip for JUST this queue).

This queue receives content which does NOT contain the JSON text, so, I need whatever I end up with to only try to operate on messages that match the pattern in my bad code above, and, ideally, to just save to the output file the JSON, not the whole message.

I’ve read through various Wiki articles, and some of the code contributions, but, I’m obviously missing something in understanding exactly what needs to go where. If there is a simple tutorial which has screenshots or details about what the RT5.0.3 UI needs, versus what needs to be some Perl within the RT directory structure, that would help a lot.

Thank you!

I’ve not seen someone try to require in a file with a subroutine in a custom commit before, but one thing you might need to do is actually pass $self from the outer commit into the SaveEmailToFile() subroutine call. At the moment you appear to be calling that subroutine with no arguments, yet the first thing it tries to do is get its own local (my scoped) copy of $self from @_.