Using Django to create Strava Webhook subscription

459 Views Asked by At

I am trying to create a Strava webhook subscription to recieve events from users who have authorised my Strava application. I was able to successfully create a subscription using the code in this Strava tutorial. However, I don't understand Javascript, so can't adapt the code to my needs. I am therefore trying to replicate it's functionality within Python using Django.

My basic approach has been to follow the setup outlined in the Django section of this webpage, then replace the code in the file views.py with the code below. I have tried to make the code function as similarly as possible to the Javascript function within the tutorial I linked above. However, I'm very new to web applications, so have taken shortcuts / 'gone with what works without understang why' in several places.

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.clickjacking import xframe_options_exempt
import json

@csrf_exempt
@xframe_options_exempt
def example(request):
    if request.method == "GET":
        verify_token = "STRAVA"
        str_request = str(request)
        try:
            mode      = str_request[str_request.find("hub.mode=") + 9 : len(str_request) - 2]
            token     = str_request[str_request.find("hub.verify_token=") + 17 : str_request.find("&hub.challenge")]
            challenge = str_request[str_request.find("hub.challenge=") + 14 : str_request.find("&hub.mode")]
        except:
            return HttpResponse('Could not verify. Mode, token or challenge not valid.')
        
        if (mode == 'subscribe' and token == verify_token):
            resp = json.dumps({"hub.challenge":challenge},separators=(',', ':'))
            return HttpResponse(resp, content_type='application/json; charset=utf-8')
        else:
            return HttpResponse('Could not verify mode or token.')

The Strava documentation says that the callback url must respond to a GET request within 2 seconds with a status of 200 and an echo of the hub.challenge json string. This function seems to do that. Yet when I try to create a POST request equivalent to the one below:

$  curl -X POST https://www.strava.com/api/v3/push_subscriptions \
      -F client_id=[MY-CLIENT-ID] \
      -F client_secret=[MY-CLIENT-SECRET] \
      -F 'callback_url=http://[MY-IP-ADDRESS]:8000/webhooks/example/' \
      -F 'verify_token=STRAVA'

I get the following response:

{
    "message": "Bad Request",
    "errors": [
        {
            "resource": "PushSubscription",
            "field": "callback url",
            "code": "not verifiable"
        }
    ]
}

Does anyone have any idea what might be going wrong?


P.S. Please let me know if there's anything I can do to make this example more reproducible. I don't really understand this area well enough to know whether I'm leaving out some crucial info!
0

There are 0 best solutions below