Search code examples
jsonperlnagios

add to JSON ($payload={}) on condition


I feed JSON to some webhook to trigger a notification (M$ Teams). This works well. However, I want to extend my Perl script: I need to add a new node to my "messagecard" construct on a certain condition.

E.g. I defined this:

my $payload={};
$payload = {
    '@type' => 'MessageCard',
    '@context' => 'http://schema.org/extensions',
    themeColor => $event{COLOR},
    text => $event{SERVICEOUTPUT},
    sections => [{
        facts => [{
            name => 'Type',
            value => "$event{NOTIFICATIONTYPE} $event{ADDITIONALINFO}"
        },
        ]
    }],
    potentialAction => [{
        '@type' => "OpenUri",
        name => "View Monitoring",
        targets => [{
            os => "default",
            uri => $naemon_url
        }]
    }]
};

$ua = LWP::UserAgent->new;
my $req = POST($opt_webhook
    , 'Content-Type' => 'application/json; charset=UTF-8'
    , 'Content' => encode_json($payload)
);
my $resp = $ua->request($req);

And if (conditon), I want to extend this as follows (order is important):

$payload = {
    '@type' => 'MessageCard',
    '@context' => 'http://schema.org/extensions',
    themeColor => $event{COLOR},
    text => $event{SERVICEOUTPUT},
    sections => [{
        facts => [{
            name => 'Type',
            value => "$event{NOTIFICATIONTYPE} $event{ADDITIONALINFO}"
        },
        ]
    }],
    potentialAction => [{
        '@type' => "OpenUri",
        name => "View Monitoring",
        targets => [{
            os => "default",
            uri => $naemon_url
        }]
    },
    {
        '@type' => "OpenUri",
        name => "Notes (Logs, Docs,..)",
        targets => [{
            os => "default",
            uri => $event{SERVICENOTESURL}
        }]
  }]
};

I am unsure how this can be achieved. Can anyone please provide wisdom how to tackle this?


Solution

  • You can push into the array reference that you've got inside your potentialAction key. In order to do that, you need to dereference it as an array.

    my $payload = {
        '@type' => 'MessageCard',
        potentialAction => [{
            name => "View Monitoring",
            targets => [{
                os => "default",
            }]
        }]
    };
    
    if ($maybe) {
        push @{ $payload->{potentialAction} }, {
            name => "Notes (Logs, Docs,..)",
            targets => [{
                os => "default",
            }]
        };
    }
    

    If your Perl version is 5.24 or newer you can also use postfix dereferencing, which some people find easier to read.

    push $payload->{potentialAction}->@*, ...
    

    See perlref and perlreftut for more information.