Search code examples
python-3.xrestflaskfacebook-messengerfacebook-chatbot

Messenger Send API


I am creating a self built Python chatbot that does not use a chatbot platform such as Dialogflow. The issue is that there is no easy integration with messaging apps such as Messenger to connect it too. I am trying to create a webhook to Messenger using the Messenger Send API. I am looking at the documentation and it shows me how to request a POST api call. However when I look at examples online they all seem to deal with json values called "entry" and "messaging" which I can't find anywhere and can't seem to see why it is necessary. I was wondering how exactly the input body of a Messenger Send API looks like so I can call it appropriately and what json objects are in its body. This is what I have so far from following online examples. I am using Flask. And am using Postman to test this

@app.route("/webhook", methods=['GET','POST'])
def listen():
    if request.method == 'GET':
        return verify_webhook(request)

    if request.method == 'POST':
        payload = request.json
        event = payload['entry'][0]['messaging']
        for x in event:
            if is_user_message(x):
                text = x['message']['text']
                sender_id = x['sender']['id']
                respond(sender_id, text)

        return "ok"

Below is what I think the body of the request looks like:

{
  "object":"page",
  "entry":[
    {
      "id":"1234",
      "time":1458692752478,
      "messaging":[
        {
          "message":{
            "text":"book me a cab"
          },
          "sender":{
            "id":"1234"
          }
        }
      ]
    }
  ]
}

But it is unable to read this and gives me an error of:

File"/Users/raphael******/Documents/*****_Project_Raphael/FacebookWebHookEdition.py", line 42, in listen event = payload['entry'][0]['messaging']

TypeError: 'NoneType' object is not subscriptable

Where am I going wrong that the webhook is not registering the body correctly as json objects?


Solution

  • Here is how we do it:

    # GET: validate facebook token
    if request.method == 'GET':
        valid = messenger.verify_request(request)
        if not valid:
            abort(400, 'Invalid Facebook Verify Token')
        return valid
    
    # POST: process message
    output = request.get_json()
    if 'entry' not in output:
        return 'OK'
    
    for entry in output['entry']:
        if 'messaging' not in entry:
            continue
    
        for item in entry['messaging']:
    
            # delivery notification (skip)
            if 'delivery' in item:
                continue
    
            # get user
            user = item['sender'] if 'sender' in item else None
            if not user:
                continue
            else:
                user_id = user['id']
    
            # handle event
            messenger.handle(user_id, item)
    
    # message processed
    return 'OK'
    

    EDIT:

    If you are using postman, please make sure to also set Content-Type header to application/json, otherwise Flask can't decode it with request.json. I guess that's where None comes from in your case.