Skip to content
This repository was archived by the owner on Nov 1, 2018. It is now read-only.
This repository was archived by the owner on Nov 1, 2018. It is now read-only.

Webhooks #2

@doria90

Description

@doria90

Hi guys,
I'm trying to use this sample to write a similar program which uses webhooks on heroku.
here's my code:

import uuid
import redis
from flask import *
import os
import json
from flask_oauthlib.client import OAuth
import requests

redis_url = os.environ['REDISTOGO_URL']
redis_client = redis.from_url(redis_url)
 
CLIENT_ID = os.environ['CLIENT_ID']
CLIENT_SECRET = os.environ['CLIENT_SECRET']
REDIRECT_URI = URL
RESOURCE = 'https://graph.microsoft.com/'
API_VERSION = 'v1.0'
SCOPES = ['User.Read','Files.Read.All', 'Files.ReadWrite.All'] 
AUTHORITY_URL = 'https://login.microsoftonline.com/common'
AUTH_ENDPOINT = '/oauth2/v2.0/authorize'
TOKEN_ENDPOINT = '/oauth2/v2.0/token'




app = Flask(__name__, template_folder='static/templates')
app.debug = True
 

app.secret_key = os.environ['FLASK_SECRET_KEY']


OAUTH = OAuth(app)
MSGRAPH = OAUTH.remote_app(
    'microsoft', consumer_key=CLIENT_ID, consumer_secret=CLIENT_SECRET,
    request_token_params={'scope': SCOPES},
    base_url=RESOURCE + API_VERSION + '/',
    request_token_url=None, access_token_method='POST',
    access_token_url=AUTHORITY_URL + TOKEN_ENDPOINT,
    authorize_url=AUTHORITY_URL + AUTH_ENDPOINT)

@app.route('/')
@app.route('/welcome')
def homepage():
    """Render the home page."""
    return render_template('homepage.html', sample='Flask-OAuthlib')

@app.route('/login')
def login():
    """Prompt user to authenticate."""
    session['state'] = str(uuid.uuid4())
    return MSGRAPH.authorize(callback=REDIRECT_URI, state=session['state'])


@app.route('/login/authorized')
def authorized():
    """Handler for the application's Redirect Uri."""

    if str(session['state']) != str(request.args['state']):
        raise Exception('state returned to redirect URL does not match!')
    response = MSGRAPH.authorized_response()
    session['access_token'] = response['access_token']
    
    endpoint = 'me'
    headers = {'SdkVersion': 'sample-python-flask',
               'x-client-SKU': 'sample-python-flask',
               'client-request-id': session.get('state'),
               'return-client-request-id': 'true'
               }
    graphdata = MSGRAPH.get(endpoint, headers=headers).data
    redis_client.hset('tokens', graphdata["id"], response['access_token'])
    
    endpoint = 'subscriptions'
    data = """{"changeType": "updated",
            "notificationUrl": "https://onedrive-votiro.herokuapp.com/webhook",
            "resource": "/me/drive/root",
            "expirationDateTime": "2018-02-02T11:23:00.000Z",
            "clientState": "STATE" 
            }""" 
            
    subscription = MSGRAPH.post(endpoint, headers=headers, content_type='application/json', data = data).data
    redis_client.hset('tokens', subscription["id"], response['access_token'])
    
    return redirect('/graphcall')


def getDelta(id):

    print 'in delta'
    location = "me/drive/root/delta"
    '''
    headers = {'SdkVersion': 'sample-python-flask',
           'x-client-SKU': 'sample-python-flask',
           'client-request-id': str(uuid.uuid4()),
           'return-client-request-id': 'true'
           }
    '''
    token = redis_client.hget('tokens', id)
    return json.loads(MSGRAPH.get(location, token=token).data)

@app.route('/webhook', methods=['POST'])
def webhook():
    '''Respond to the webhook challenge (POST request) by echoing back the challenge parameter.'''
    if request.args.has_key('validationToken'):
        rv = (request.args.get('validationToken'), 200, {'Content-Type':'text/plain'})
        resp = make_response(rv)
        return resp
    else:
        data = json.loads(request.data)["value"]
        print data
        for item in data:
            clientState = item["clientState"]
            if clientState == "STATE":
                id = item["subscriptionId"]
                response = getDelta(id)
            else:
                pass
                #false notification, do nothing
            return status.HTTP_201_CREATED
            
@app.route('/graphcall')
def graphcall():
    """Confirm user authentication by calling Graph and displaying some data."""
    return render_template('graphcall.html') #redirect to onedrive

@MSGRAPH.tokengetter
def get_token():
    """Called by flask_oauthlib.client to retrieve current access token."""
    return (session.get('access_token'), '')
    

if __name__ == '__main__':
    app.run()

The main issue, one whice i cannot find any reference online, is when Posting a subscription request (for the webhook), I'm getting the following error:

{u'error': {u'code': u'ExtensionError', u'message': u'Operation: Create; Exception: [Status Code: Forbidden; Reason: Forbidden]', u'innerError': {u'request-id': u'79709ce8-b29d-41ed-9452-607ecab7e48d', u'date': u'2018-01-03T09:03:41'}}}

This tells me nothing basically and I'm currently stuck on this..
Any ideas what am I doing wrong?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions