krlwebhooks

KRL webhooks receiving JSON


I'm trying to set up a Webhook for Amazon SNS. SNS will send a JSON object to the webhook. Based on the KRL documentation I can get the event parameters using event:param('name'). That works for form encoded data, but what about JSON?

I sent a call to postbin.org and this is what postbin reported:

body {
  "Message": "You have ...",
  "MessageId": "958....",
  "Signature": "vo3v5f....",
  ...
}

Here is what I would like to write in KRL:

rule sns_webhook {
  select when webhook sometopic Type "SubscriptionConfirmation"
  pre {
    topic_arn = event:param("TopicARN");
    signature = event:param("Signature");
    message = event:param("Message");
    subscribe_url = event:param("SubscribeURL");
  }
  if valid_signature(signature) then {
    confirm_subscription(subscribe_url);
  }
}

That would probably work for HTTP form encoded data, but with JSON I expect the following will be required:

rule sns_json {
  select when webhook sometopic
  pre {
    body = event:param('body').decode();
    msg_type = body.pick("Type");
    signature = body.pick("Signature");
    ...
  }
  if msg_type eq "SubscriptionConfirmation" && valid(signature) then
  {
    confirm_subscription(...);
  }
}

Do I need to use the second method described here? Will event:param('body') get the JSON data from the SNS message?


Solution

  • Your second code block is very close. Here it is, rewritten to use the correct event:param()

    rule sns_json {
      select when webhook sometopic
      pre {
        body = event:param('request_body').decode();
        msg_type = body.pick("Type");
        signature = body.pick("Signature");
        ...
      }
      if msg_type eq "SubscriptionConfirmation" && valid(signature) then
      {
        confirm_subscription(...);
      }
    }
    

    If you had this rule first, I would remember to add a last in the fired postlude block.

    Instead of decoding the body multiple times, you could also raise an explicit event with the already decoded message as an event param, and include the Type of the message so that you can write rules that explicitly handle the different types.