How To

Using Webhooks

HTTP requests on Fider's events

Webhooks are a powerful integration feature that allow you to propagate events from Fider to other applications.

Events happens when users interact on Fider. Four types of events currently exists, but more of them could be created in the future.

Webhooks are highly customizable and you can create as many webhooks as you need for each event type.

Create a new Webhook

While logged in as an Administrator, navigate to Site Settings -> Webhooks.

This page list all created Webhooks, either Enabled or Disabled. To create a new one, click Add New and fill the form with all the required information as explained on the section below.

The admin control panel to manage your Webhooks

Webhook configuration

The power of this feature reside in its customization. Each Webhook has a name for you to quickly recognize it, a type defining its trigger event, a status so you can enable or disable it, an URL and a content both formattable using Go templates, an HTTP method used to perform the request and even a set of additional HTTP headers.

The Webhook creation form

Name

The name is used in the admin control panel to identify the Webhook. You may give the name you want, it'll never get shown to users or sent in the request. It do not needs to be unique: a unique ID display with a # symbol is always included with the name so you can distinguish two Webhooks with the same name.

Type

The type define which event will trigger this Webhook. It's also used to categorize them on the admin control panel. As new events could be added in future, this attribute is subject to modification.

Status

The status define whether the Webhook is active or not. We highly recommend you to test your Webhook before enabling it. When the execution of a Webhook fails, it'll automatically get disabled until you edit and fix it.

URL

The URL is one of the most important parts in the Webhook definition. Indeed, it is part of the definition of the HTTP request that this Webhook perform. This is usually defined by your targeted application, and you must refer to its documentation to know how to get one. See the list of common Webhook targets that you probably want to integrate with below to get some help with them.

Content

The content is the main element in your Webhook. You define here the data sent as HTTP request body. In most cases, the payload will include information about the event that triggered it. Just like the URL, you can also use Go template formatting here. Do not hesitate to check the integrated help section by clicking on the information icon next to it. Take a look at the Preview zone to see what would your request contains with example data.

HTTP Method

This is the HTTP request method of the request triggered by the Webhook. In most cases, when sending data in the Content, the HTTP method will be POST. Check your targeted application's documentation to be sure.

HTTP Headers

You can add any HTTP headers you want here. Each header have a name and a value, and you cannot define the same header twice. The most common headers are:

  • Content-Type: use it to tell your application the MIME type of the data represented in your Content. Common values are: application/json, text/plain, application/x-www-form-urlencoded, application/xml...
  • Authorization: use it to authenticate with given credentials.

Writing Go templates (for your Webhook URL and content)

The preview field

When writing templates, a preview is available before saving you check when it'll look like. Use it as many times as you need!

An example of the preview field

Presentation

Go templates are a way to customize a text using external values (also called here "properties"). The engine used here is the native text/template Go package. This is a powerful engine, but creating a basic templates is not complicated. You can write text as you want and insert a property name, prefixed by a dot, enclosed in double braces with space within to place its value. For example, this is the most basic template with some values:

Template

A new post entitled "{{ .post_title }}" has been created by {{ .author_name }}.

Rendered text

A new post entitled "Example dummy post title" has been created by Test.

In addition to properties, you can also use "functions", which are really useful to perform operations on values before they got inserted in the text. Example: (Read more about time formatting here)

Template

The post was created on {{ format "Monday, 02 Jan 2006 at 15:04:05" .post_created_at }}.

Rendered text

The post was created on Friday, 07 May 2021 at 18:42:27.

To adapt the content dynamically depending on a property's value, you can even use "control structures", such as conditions and loops! For example, you may add an element for post tags (also note the use of the minus sign - to trim lisibility white spaces):

Template

The post have {{ if len .post_tags -}}
  {{ len .post_tags }} tag {{- if gt (len .post_tags) 1 -}} s {{- end }}:
  {{- range .post_tags }} {{ . }} {{- end -}}
{{- else -}}
  no tag
{{- end }}.

Rendered text

Post with tags

The post have 2 tags: tag1 tag2.

Post without tag

The post have no tag.

When using function call result as another function's argument, don't forget to parenthesis the expression: {{ quote (format "15:04:05" .post_created_at) }}. You can also use a pipe character (|) to chain calls: {{ .post_created_at | format "15:04:05" | quote }} or {{ format "15:04:05" .post_created_at | quote }}.

Since the double braces are special characters in templates, if you need to insert them in your text, use the following trick: {{ "{{" }}. Do not hesitate to consult the official Go documentation about templates to see what are the possibilities.

Security disclaimer

You should always keep in mind user content may be insecure! Posts title and description, comments or users name are free text directly from the users. You need to properly encode values like that when using them in JSON fields for example. The following example is a bad configuration:

{
  "message": "{{ .post_description }}"
}

A malicious user could create a post with this description:

Hacked!",
"important": true,
"from": "admin

When the template will be executed, the final result will look like:

{
  "message": "Hacked!",
  "important": true,
  "from": "admin"
}

The targeted application may interpret the "important": true as a message requiring a notification and use the from field to set the sender. Thus, people will receive a notification for a message from the admin saying "Hacked!". Pretty scary.

Please avoid these trouble and use the safety functions like quote, escape, urlquery, stripHtml...

The correct configuration would be (note the external quotes have been removed too):

{
  "message": {{ quote .post_description }}
}

List of properties and functions

You can find theses information in the integrated help by clicking on the information icon next to the URL and Content fields.

Properties
Property nameExample value
author_avatarhttps://yourapp.fider.io/static/avatars/letter/1/Test
author_emailtest@test.fr
author_id1
author_nameTest
author_roleadministrator
commentAn example **comment** on a post.
post_author_avatarhttps://fider.io/images/logo-100x100.png
post_author_emailcontact@fider.io
post_author_id7
post_author_nameFider
post_author_rolevisitor
post_comments3
post_created_at2021-05-07T18:42:27Z
post_description*Those data are fake.*<br /><br />This is an example of a post, but don't worry, nothing was created on your Fider instance:<br />It was just a test of a webhook trigger.<br /><br />You can use `{{ markdown .post_description }}` to parse __Markdown__ to **HTML** in post!
post_id36
post_number36
post_old_statusopen
post_responsetrue
post_response_author_avatarhttps://yourapp.fider.io/static/avatars/letter/1/Test
post_response_author_emailtest@test.fr
post_response_author_id1
post_response_author_nameTest
post_response_author_roleadministrator
post_response_responded_at2021-07-09T15:29:57Z
post_response_textThis is a response, still in *Markdown*.
post_slugexample-dummy-post-title
post_statusstarted
post_tagstag1
tag2
post_titleExample dummy post title
post_urlhttps://yourapp.fider.io/posts/36/example-dummy-post-title
post_votes7
tenant_id1
tenant_localefr
tenant_logohttps://fider.io/images/logo-100x100.png
tenant_nameTesting
tenant_statusactive
tenant_subdomainyourapp
tenant_urlhttps://yourapp.fider.io
Functions
FunctionDescriptionParameters
Type - Description
stripHtmlStrip HTML tags from the input datastring - The input string containing HTML to strip
md5Hash text using MD5 algorithmstring - The input string to hash
lowerLowercase textstring - The input string to lowercase
upperUppercase textstring - The input string to uppercase
markdownParse Markdown to HTML from the input datastring - The input string containing Markdown to parse
formatFormat the given date and timestring - The date format according to Go specifications
time - The time to format
quoteEnquote a string and escape inner special charactersstring - The input string to quote
escapeEscape inner special characters of a string, without enquoting itstring - The input string to escape
urlqueryEncode a string into a valid URL query elementstring - The input string to encode as URL query value

Don't forget to use the Preview field to help you experiment these functions!

Webhook trigger failure report

This report is shown when a manual trigger of a Webhook goes wrong. It means your configuration is incorrect and you should not enable this Webhook now. A failed Webhook is automatically disabled until you edit it. It is a good practice to always test it after each edition to ensure nothing was broken.

An extract of the failure report

Understanding the report

There is a lot of informations included in the report and it may be disconcerting the first time you see it.

First, the Message indicates where the process was interrupted, and why. Then, the Error shows what went wrong and caused the trigger process to stop. URL and Content are the parsed templates replaced with properties' values, helping you to understand the performed request. The Status code is the HTTP response status code returned by the request. Properties are every variables you can use in templates associated with their resolved values.

Testing

Before enabling any your Webhook on Fider, we highly recommend that you keep it disabled and use the Trigger button to confirm it's working properly.

Trigger button becomes available after creating a new Webhook. Whenever clicked, an event of the appropriate type is simulated, triggered only this Webhook. A notification in the upper-right corner of the screen indicate the result of the trigger. Once you're happy with the configuration, you can enable it and it will be triggered automatically with real properties every time the selected event occurs.

The result can be either a success: everything was good and the HTTP request was executed successfully; or a failure: something went wrong during the process. In case of a success, check your targeted application to confirm everyhing is OK, then you can enable your Webhook. However, if it was a failure, a report will be available beside your Webhook's name, by clicking on this information icon. Read more about Webhook trigger failure reports here.

Analyzing the message and error

Four error messages are possible:

  1. Could not parse webhook URL template
  2. Could not parse webhook content template
  3. Could not execute webhook HTTP request
  4. Webhook HTTP request returned an error response code

For each of these messages, the error field will bring more precise information about:

  1. What was malformated in the URL template
  2. What was malformated in the Content template
  3. What prevented the HTTP request from being executed
  4. What did the server respond to the request

Solving problems

In case of 1. or 2., you should verify your templates and do not hesitate to take advantage of the Preview area in the Webhook edition form. See Writing Go templates for more information.

Regarding the 3., it become more subtle. If anything, from the request sending, to the response reading, fails, it will be this error. First of all, verify manually the URL to check if you didn't made a spelling mistake in your app's domain name. Also, try pasting this URL in your browser to see if the targeted application is alive. On your application, be sure to reply and properly close the HTTP connection after Webhook handling. If you're trying to reach the Internet from an internal network, ensure your server can emit request to your application.

Finally, concerning the 4., the request was correctly sent to your application, but it was invalid. This can be caused by an invalid URL, an inappropriate content, or even a missing HTTP header. Please refer to your application's official documentation and try to start with basic example (sending Hello World seems to be a good idea to begin your debugging session).

A special case of failing could be the malformation of the result produced by templates with some values. Here are some recommendations about this:

  • Properties passed as GET parameters in the URL query (i.e. after the ?) should always be encoded using urlquery.
    https://example.org/webhook/fider?author={{ urlquery .author_name }}
    
  • When using a structured text format such as JSON, or any other format asking you to enquote an element, you should use the quote function.
    {
      "title": {{ quote .post_title }}
    }
    

When you think your problem has been solved, don't forget to test your Webhook before enabling it!

Common Webhook targets documentation