Generating a configurable HTTP post payload in a module

I'm working on a module, based on the slack-alarm-notification example, that sends alarm notifications to an SMS gateway via HTTP. Mainly as a learning exercise, but it will be useful for a project I'm involved in.

For now I have hard-coded the module to format the required data i.e. the SMS message and the recipient number, as JSON delivered via HTTP post as required by my specific SMS provider but I'm thinking it should be possible to allow the user to provide a custom data format, which would make the module much more generic.

Two ways I can think of are 1. to use a user supplied Python script or 2. to use a user supplied string template. Which way would be feasible? If so, how is it done? Are there other ways to do this?

I have made the target URL, and the API keys as Notification Profile Settings so these are already somewhat configurable. However these should be made more configurable because different providers may use different HTTP headers for those purposes. Is it possible to allow variable settings where the user specifies any number of key+value pairs as would be needed for an HTTP header?

Currently the alarm notification system's only extension point for flexibility is by registering additional properties:

The two options for this are, basically, raw strings or Ignition expressions, but generally speaking users experienced with Ignition are going to be comfortable with expressions for string substitution so this should probably be fine. E.G. instead of implementing your own string substitution, you could just lean on the stringFormat expression function in the platform. You could also look to @pturmel's Simulation Aids module, which adds array and object literal "constructor" expression functions, which return classes that could be easily mapped to JSON strings to send to an arbitrary API; in some future Ignition release we'll offer that first party, but it's probably the most natural way to get the flexibility you're looking for within the restrictions of the general alarming system.

I'd also personally like for us to implement a 'scripted' notification profile type, but that's basically an end-run around your whole idea.

1 Like

Thanks @PGriffith,
I've implemented the REST API config information as RestNotificationProfileSettings extends PersistentRecord following the slack example. I've add the POST json payload as a template string like this:

{ "destination":"{ContactInfo.sms}", "content":"{AlarmMessage}" }

Where I've just used Java's String.IndexOf and String.replace to substitute the templated variables.

I don't understand how I would use stringFormat to do this. As far as I can see it does %s type substitution so that would need positional rather than named arguments.