How to create a webhook using Node, Express and Ngrok
Here is a quick example of how to subscribe to a webhook with a dummy server using a Mac
Step 1
Install ngrok using Homebrew, as documented here.
For Homebrew v2.6.x and below:
brew cask install ngrok
For Homebrew v2.7.x and above:
brew install --cask ngrok
Sign up for a free ngrok account.
Install your authtoken. To find YOUR_TOKEN, go to your ngrok dashboard.
In terminal, run:
ngrok authtoken YOUR_TOKEN
If you receive a “No such file or directory” error, try navigating to the /usr/local/bin
directory and rerunning
the command as follows:
cd /usr/local/bin
ngrok authtoken YOUR_TOKEN
Please refer to ngrok’s documentation for further clarification.
Step 2
Install Node.js. We are using homebrew to install Node.js, but you can also download it here.
Open a terminal and run:
brew install node
Step 3
Create a new Node.js project in terminal:
mkdir strava-webhooks
cd strava-webhooks
touch index.js
npm init
npm install express body-parser --save
Step 4
This is is the code to run a dummy server that will help you complete a webhook subscription. It will not process webhook events for you. Please copy/paste the below into index.js:
'use strict';
// Imports dependencies and sets up http server
const
express = require('express'),
bodyParser = require('body-parser'),
// creates express http server
app = express().use(bodyParser.json());
// Sets server port and logs message on success
app.listen(process.env.PORT || 80, () => console.log('webhook is listening'));
// Creates the endpoint for our webhook
app.post('/webhook', (req, res) => {
console.log("webhook event received!", req.query, req.body);
res.status(200).send('EVENT_RECEIVED');
});
// Adds support for GET requests to our webhook
app.get('/webhook', (req, res) => {
// Your verify token. Should be a random string.
const VERIFY_TOKEN = "STRAVA";
// Parses the query params
let mode = req.query['hub.mode'];
let token = req.query['hub.verify_token'];
let challenge = req.query['hub.challenge'];
// Checks if a token and mode is in the query string of the request
if (mode && token) {
// Verifies that the mode and token sent are valid
if (mode === 'subscribe' && token === VERIFY_TOKEN) {
// Responds with the challenge token from the request
console.log('WEBHOOK_VERIFIED');
res.json({"hub.challenge":challenge});
} else {
// Responds with '403 Forbidden' if verify tokens do not match
res.sendStatus(403);
}
}
});
Step 5
Start the node server by running the following in terminal:
node index.js
Step 6
Open a new tab and start ngrok so your local server is reachable by internet:
ngrok http 80
Step 7
Log in or create a Strava account. After your account has been created, click here to link the Node server you created in Steps 3 - 6 to your Strava account.
After you create a subscription in step 8, webhook events will be pushed to this app when when an athlete revokes access to an application, or when an activity is created, deleted, or one of the following activity fields are updated, as documented here.
An important field in the App creation form is Authorization Callback Domain
; here you’ll want to use the
forwarding
url listed as the output from Step 6 (e.g. http://xyzabc123.ngrok.io) so that Strava
knows where to push webhook events.
Step 8
Finally, make a Postman or cURL request to subscribe to a webhook.
Please change the parameters as the following example includes dummy data:
- You can find your client secret and client id on your App info page.
- Use the same callback_url
that you used in Step 7, appended with /webhook
(e.g. http://xyzabc123.ngrok.io/webhook).
- Use the verify_token
from Step 4.
curl -X POST \
https://www.strava.com/api/v3/push_subscriptions \
-F client_id=12345 \
-F client_secret=1234567abcdefg \
-F callback_url=https://1234abcd.ngrok.io/webhook \
-F verify_token=STRAVA
You should see WEBHOOK_VERIFIED
printed to the terminal console if the request was successful.
Step 9
To test that your webhook is working, trigger any of the events listed in Step 7 that will result in the generation of a webhook push event.
If your webhook subscription worked, you’ll see EVENT_RECEIVED
printed to the terminal console.