Facebook Webhook - pass back hub.challenge value

Hi there,

in order to subscribe myself to Facebooks Webhook, Facebook sends the following request:

GET https://www.your-clever-domain-name.com/webhooks?
  hub.mode=subscribe&
  hub.challenge=1158201444&
  hub.verify_token=meatyhamhock

It then expects a response containing the hub.challenge value (1158201444) to verify.

How can I define this response? Response Mode “On Receive” does not work as it only responds with a status. Could this be achieved with “Last Node”?

Many thanks
Felix

Welcome to the community @fkaul!

Yes that could be done with “Last Node”. Does it really just expect that single value back or is it some kind of JSON?

Thanks for responding so quickly Jan.

This is the error I receive from Facebook:

The URL couldn’t be validated. Response does not match challenge, expected value=“1158201444”, received="{“success”:true}"

So it appears it expects it back as a single value.

Could you point me in the right direction of how I could achieve this?

The following workflow should work:
(You can simply copy and then past directly into n8n. It will automatically create all the nodes and connections.)

{
  "nodes": [
    {
      "parameters": {
        "path": "webhook",
        "responseMode": "lastNode",
        "options": {
          "responseContentType": "text/plain",
          "responsePropertyName": "data"
        }
      },
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        500,
        300
      ]
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "data",
              "value": "={{$node[\"Webhook\"].json[\"query\"][\"hub.challenge\"]}}"
            }
          ]
        },
        "options": {}
      },
      "name": "Set",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        700,
        300
      ]
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Set",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

That was really helpful and it works like a charm.

Last question: Above method was needed to verify the Webhook URL with Facebook. Once thats done however, Facebook will use this very same Webhook URL going forward to send new lead data to via a POST request. The thing is, it will always be sent to the very SAME URL we verified before (meaning that the same URL must be able to both listen to GET and POST). Unfortunately I had no luck creating another Webhook with the POST method to listen to while having the very same URL. How would you go about this?

The easiest would probably be to simply have an IF directly after the node. If “hub.mode” is subscribe it goes to the Set-Node and returns what it wants. If not it does whatever else you want.

Okay, thanks @jan - will try to get it work :slight_smile:

1 Like

So, I did as you said and implemented an IF after the node, and the verification works. However if the Request from FB is a POST (to send lead data) instead of GET (to verify), it doesn’t even trigger the webhook as it is only listening to GET. How can I get the webhook to listen to both GET and POST?

This is my setup:

{
  "nodes": [
    {
      "parameters": {
        "httpMethod": "=GET",
        "path": "webhook",
        "responseMode": "lastNode",
        "options": {
          "responseContentType": "text/plain",
          "responsePropertyName": "data"
        }
      },
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        400,
        300
      ]
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "data",
              "value": "={{$node[\"Webhook\"].json[\"query\"][\"hub.challenge\"]}}"
            }
          ]
        },
        "options": {}
      },
      "name": "Set",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        710,
        230
      ]
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{$node[\"Webhook\"].json[\"query\"][\"hub.mode\"]}}",
              "value2": "subscribe"
            }
          ]
        }
      },
      "name": "IF",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        550,
        300
      ]
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "IF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF": {
      "main": [
        [
          {
            "node": "Set",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Ah one request come via “POST” and the other one via “GET”. In that case there is nothing that can be done.

The problem is that the node-name is part of the URL and because two nodes can not have the same name that can currently not be done. We will work on making that possible soon but till then it simply does not work.

The only thing you can do for now, is to create the webhook having the nodeset to “GET” and then once it is confirmed you change it to “POST” and then save the workflow again.

Ahh thats unfortunate. Okay, will try your suggested workaround! Anyways, thank a lot for the quick help and have a nice evening! (also Berlin-based here :slight_smile:)

Sure you are welcome!

Ah great to hear! Once that whole virus-mess is over we have planned to organize some Meetups. Hope to see you there! Have a nice evening.

1 Like