Get Facebook Ad Lead Notifications with Node.js & Webhooks

Jul 21, 2021

I recently finished setting up a Lead Generation ad on Facebook Ads, which is a special type of ad that asks a potential customer to leave their details for you to get in touch with them. The process looks something like this, and Facebook pre-fills any information they already have about your customer:

Facebook Lead Generation Ad

So far, so good. For the advertiser, though, to actually get access to the incoming leads (and the submitted form info), you can either:

  1. Connect to a CRM of choice ($$) or a tool such as Zapier (also $$)
  2. Manually go into the Facebook Business Suite -> Select Your Account -> More Tools -> Instant Forms and click Download to fetch a .csv file with any new leads every time you get a new lead (by manually checking the page for new leads)
  3. Subscribe to the leadgen webhook which is invoked every time a lead submits the form

Since time is of the essence with most leads, and since I chose to go with the free route, option 3 made the most sense. Yet actually getting it to work was the tricky part. Here's a detailed step-by-step guide on how to do just that:

Create a Facebook App

  1. Sign up for Facebook Developer access if you haven't already, from the same account as your Facebook Ads advertising account.

  2. Create an app and select Manage business integrations as the app purpose. If you're using Facebook Business Manager, make sure to select the right Business Manager account in the app creation form, when asked to do so.

Note: You will need to submit your app to Facebook for review to enable Live mode, otherwise you won't be able to access real leads but only test leads.

Generate a Never-Expiring Page Access Token

  1. Visit the Graph API Explorer and add the click Generate Access Token:

   2. Add the following custom permissions which are necessary to retrieve Facebook Ads leads:

pages_show_list
ads_management
ads_read
leads_retrieval
pages_read_engagement
pages_manage_metadata
pages_manage_ads

   3. Click Generate Access Token again and select your page, granting all permissions:

   4. Under User or Page, select the name of your page, ensure the permissions are still there, and click Generate Access Token:

Accept the permission dialog once again.

   5. Most likely, the page you selected under User or Page, will have reset back to User. Select your page again, and click Generate Access Token:

   6. Now, let's extend the Access Token's expiration date. Copy the Access Token and paste it into the Access Token Debugger, and click Debug. By default, page access tokens expire in an hour, but we can extend them indefinitely.

   7. To extend the access token, scroll down and click the Extend Access Token button at the end of the page:

   8. Click Debug and ensure the expiration is set to Never:

You have now generated an access token that never expires, which we can use to fetch leads programmatically and indefinitely, without having to bother with re-generating an access token ever again for this purpose.

Setting Up the Node.js Server

Now, the easy part: let's set up a basic web server to receive the webhook requests from Facebook every time a new lead submits their information.

  1. Install Express (web server), Axios (outgoing HTTP request library) and Body Parser (for parsing requests with JSON):
npm install express axios body-parser --save  

     2. Create a file server.js and paste in the contents of this Gist.

     3. Paste the Page Access Token from the previous step into the FACEBOOK_PAGE_ACCESS_TOKEN variable.

     4. Run the server:

node server.js  

     5. Let's test out the webhook functionality with ngrok, which will create a publicly-accessible hostname that will tunnel traffic to your local Node app without having to deploy it remotely, by running:

npx ngrox http 3000  

     6. Copy the https forwarding address from the output:

Enabling the Lead Gen Webhook

  1. Visit the Facebook Developer Center, select your app, scroll down to Webhooks and click Set Up.

Callback URL: Paste in the https forwarding address from ngrok, followed by /webhook

Verify Token: Enter CUSTOM_WEBHOOK_VERIFY_TOKEN (you may change this string for security purposes, but also remember to modify it in server.js accordingly).

    3. Click Verify and Save.

    4. Search for the leadgen webhook, and click Test next to it, followed by Send to My Server. Observe the terminal which is running server.js for the following error output:

This error is expected in this case, as Facebook has sent us an invalid Lead ID (444444444444). For now, ignore the error and click Subscribe to receive leadgen webhook events.

    3. We now need to manually subscribe for the leadgen webhook event for the specific page we are advertising. Execute the following curl command in your terminal of choice, replacing INSERT_PAGE_ID with your Page ID (from your Facebook Page URL) and INSERT_PAGE_ACCESS_TOKEN with the Page Access Token (which you generated previously).

curl -X POST 'https://graph.facebook.com/v2.5/INSERT_PAGE_ID/subscribed_apps?access_token=INSERT_PAGE_ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d 'subscribed_fields=leadgen'

Check for a {"success": true} response.

Time to Test

Finally, let's make sure everything works!

Facebook provides a nifty Lead Ads Testing Tool which will invoke our webhook with a test lead. Select your Page and Form from the respective dropdown and click Create lead. If all went well, the Node.js console output should show the lead details!

Next Steps

To make this script actually notify you when a new lead submits their information, a final step is required to send out an e-mail or some other kind of notification to alert the relevant salesperson of the new lead, with the information entered from the form. I recommend using nodemailer for this, and AWS SES as the SMTP e-mail sending service. Check the sample code at the end of server.js for the nodemailer approach.

Finally, when you actually deploy this node app on a server, make sure to update the Callback URL in the Webhook Settings for your Facebook App to the server's address instead of the temporary ngrok address.

Let me know if you found this useful, and have any questions :)

Written by Elad Nava
Tagged under
Posted on