0
votes

I'm trying to register my web app in Microsoft azure ,to get notification about users one-drive change . to do so I need to register my app for getting notification.

I've been following these instructions:Create subscription

and here Handling webhook validation requests

but I need some help with the validation of the webhook. When a new subscription is created, OneDrive will POST a request to the registered URL(my web app or maybe I'll use azure function) in the following format:

POST https://contoso.azurewebsites.net/your/webhook/service?validationtoken={randomString}

Content-Length: 0

For the subscription to be created successfully, my service must respond to this request by returning the value of the validationtoken query string parameter as a plain-text response.

HTTP/1.1 200 OK
Content-Type: text/plain

{randomString}

I'm using django , how do I make response in python like they asked?

this is how I send the first post request

def create_subscription(token):
  payload = {
    "changeType": "updated",
    "notificationUrl": notification_url,
    "resource": "/me/drive/root",
    "expirationDateTime": "2030-01-01T11:23:00.000Z",
    "clientState": "client-specific string"
  }

  headers = {
    "Authorization": token['access_token'],
    "Host": "graph.microsoft.com",
    "Content-Type": "application/json"
  }

  response = requests.post("https://graph.microsoft.com/v1.0/subscriptions".format(graph_url),
                           data=json.dumps(payload), headers=headers)

this is how I make the response for the POST request of Microsoft

def validate_subscription(request):

    if request.method == 'POST':
      url = request.get_full_path()
      parsed = urlparse.urlparse(url)
      validation_string = parsed.query['validationtoken']

      headers = {
        "Host": "graph.microsoft.com",
        "Content-Type": "text/plain"
      }
      r = requests.post("{0}/subscriptions".format(graph_url),
                           data=validation_string, headers=headers)
      if (r.status_code == 200):
        return HttpResponse("Subscription suceeded")

we keep getting error that says 'validation error'

thank you guys

2

2 Answers

1
votes

You shouldn't be sending a POST request back to Graph, you should be responding to Graph's request with the token it passed in:

  1. You create a subscription
  2. Graph issues a POST to your notification endpoint with a validation token.
  3. Your notification endpoint responds to that POST with:

    def validate_subscription(request):
        if request.method == 'POST':
            url = request.get_full_path()
            parsed = urlparse.urlparse(url)
            validation_string = parsed.query['validationtoken']
            return HttpResponse(validation_string, content_type="text/plain")
    
0
votes

so what I did was to to use a capital 'v' for 'validationtoken' so the request should look like this :

def validate_subscription(request):

if request.method == 'POST':
  url = request.get_full_path()
  parsed = urlparse.urlparse(url)
  validation_string = parsed.query['Validationtoken']

  headers = {
    "Host": "graph.microsoft.com",
    "Content-Type": "text/plain"
  }
  r = requests.post("{0}/subscriptions".format(graph_url),
                       data=validation_string, headers=headers)
  if (r.status_code == 200):
    return HttpResponse("Subscription suceeded")