gristlabs / grist-core

Grist is the evolution of spreadsheets.
https://www.getgrist.com/
Apache License 2.0
6.57k stars 287 forks source link

Customer Headers in Webhooks #827

Open hooksie1 opened 5 months ago

hooksie1 commented 5 months ago

I think it would be an awesome feature to allow custom headers in webhooks. The main thought is this would let us use systems that require some kind of authentication for the webhooks.

Talked about this in discord, tagging @vviers.

vviers commented 5 months ago

we plan on working on this, cc @CamilleLegeron

Quoting @fflorent :

Thinking of it, it may be interesting to allow defining the methods, headers and shapes of the request body in columns so their values can be computed through formulas.

paulfitz commented 5 months ago

Neat! A workaround is passing requests through an external service like cloudflare workers to rewrite them, but that is a pain to setup and then annoying to maintain.

paulfitz commented 3 months ago

With @CamilleLegeron working on webhooks in #832, I wonder if we could sneak a field for this into the migration she'll be introducing. Just a generic options column would do, we wouldn't have to commit to any representation yet. We typically have an options columns on tables for non-relational stuff that shouldn't require every Grist document everywhere in the world to be migrated when something is added, but there isn't one yet on the _grist_Triggers table. Doing it now would save another migration later.

CamilleLegeron commented 2 months ago

What about security if there is an authorization secret ? Inside webhook settings page maybe add an input for secret and another for none secret ? And that way we can encrypte the secret and set both in options column

CamilleLegeron commented 2 months ago

Thinking about what headers could be great to custom, I'm only thinking of the authorization parameter. How about adding only Authorization input in the webhooks params and see later if other needs arise? Wdyt @paulfitz ?

paulfitz commented 2 months ago

Thinking about what headers could be great to custom, I'm only thinking of the authorization parameter. How about adding only Authorization input in the webhooks params and see later if other needs arise? Wdyt @paulfitz ?

There's nothing very special to Grist about webhooks. Could be worth looking at what similar apps offer, to see if there is any consensus?

What about security if there is an authorization secret ? Inside webhook settings page maybe add an input for secret and another for none secret ? And that way we can encrypt the secret and set both in options column

The security question is interesting. The webhook URL itself may have a sensitive key in it, which is part of why it is not stored directly in the document but in a secrets table in the home database. This makes some things more awkward and some things simpler., and makes adding more encryption in the future easier. It could make sense to treat material for Authorization header in the same way, at least partially.

I wonder if this needs actually two features:

fflorent commented 1 month ago

I tend to think it be more interesting to change this issue title so it tracks three similar features that will probably be implemented altogether (otherwise please mention your disagreement about that), which are the ability to customize the following things for webhooks:

(as stated in an above comment)

nicolas-imbert commented 1 month ago

Hey,

Following a quick talk with @fflorent and some users, I just wanted to add my 2 cents on the potential use cases for this feature.

  1. Send an email when there is a new record or updated record (via tools like Brevo or Mailchimp)
  2. Send a notification when new record or updated record (via tools like Mattermost or Teams)

And probably a lot more to come ! Looking forward to it, thanks for the job done.

fflorent commented 1 month ago

Regarding the implementation, what about allowing configuring a column in which it is expected to return these items thanks to a formula, like:

import json
return {
  'method': 'PATCH', # Defaults to Post
  'headers': { # Headers to append to the one sent by the webhooks (like the headers)
    'X-Specific-Header': $someColumn,
    'X-Common-Header': 'Common value for all records',
  },
  'body': json.dumps({ # the body, defaults to nothing
    'whatever': $someOtherColumn
  }),
  'queryParams': 'blah=' + $queryParams # Defaults to empty string.
  # Other stuffs?
}

(The queryParam property came to my mind when writing this formula)

What do you think?

fflorent commented 2 weeks ago

We would need to clarify the User Story, prevent security issues and have a design mockup for this issue.