2016-05-05 15 views
1

Ich versuche, die FB-Messenger-API arbeitet mit Python-Flasche zu bekommen, die Anpassung der folgenden Anweisungen: https://developers.facebook.com/docs/messenger-platform/quickstartFacebook Messenger mit Flask

Bisher haben sich die Dinge ziemlich gut gelaufen. Ich habe meinen Rückruf bestätigt und kann die Nachrichten, die ich mit Messenger auf meiner Seite sende, empfangen, da in den Protokollen auf meinem Heroku-Server angegeben wird, dass die entsprechenden Datenpakete von meinem Server empfangen werden. Im Moment habe ich Schwierigkeiten, Antworten an den Kunden zu senden, die meine App signalisieren. Insbesondere, ich bin nicht sicher, wie das folgende Segment aus dem Tutorial in Flask auszuführen:

var token = "<page_access_token>"; 

function sendTextMessage(sender, text) { 
    messageData = { 
    text:text 
} 
request({ 
    url: 'https://graph.facebook.com/v2.6/me/messages', 
    qs: {access_token:token}, 
    method: 'POST', 
    json: { 
    recipient: {id:sender}, 
    message: messageData, 
    } 
}, function(error, response, body) { 
    if (error) { 
    console.log('Error sending message: ', error); 
    } else if (response.body.error) { 
    console.log('Error: ', response.body.error); 
    } 
}); 
} 

Bisher hat ich dieses Stück in meiner Server-Seite Flask-Modul:

@app.route('/', methods=["GET", "POST"]) 
def chatbot_response(): 
    data = json.loads(req_data) 
    sender_id = data["entry"][0]["messaging"][0]["sender"]["id"] 
    url = "https://graph.facebook.com/v2.6/me/messages" 
    qs_value = {"access_token": TOKEN_OMITTED} 
    json_response = {"recipient": {"id": sender_id}, "message": "this is a test response message"} 
    response = ("my response text", 200, {"url": url, "qs": qs_value, "method": "POST", "json": json_response}) 
    return response 

jedoch Wenn ich dies ausführe, finde ich, dass, während ich verarbeiten kann, was jemand meine Seite sendet, es keine Antwort zurückschickt (dh nichts erscheint in der Messenger-Chat-Box). Ich bin neu bei Flask, also würde jede Hilfe sehr geschätzt werden, wenn man das Äquivalent des Javascript-Bits oben in Flask tut.

Danke!

Antwort

-1

Wenn Sie Antworten in Flask machen, müssen Sie vorsichtig sein. Wenn Sie einfach eine return-Anweisung ausführen, wird dem Anforderer nichts zurückgegeben.

In Ihrem Fall möchten Sie vielleicht jsonify() betrachten. Es benötigt ein Python-Wörterbuch und gibt es als JSON-Objekt an Ihren Browser zurück.

from flask import jsonify 
return jsonify({"url": url, "qs": qs_value, "method": "POST", "json": json_response}) 

Wenn Sie mehr Kontrolle über die Antworten wollen, wie Codes einstellen, werfen Sie einen Blick auf make_response()

+0

"Einfach eine return-Anweisung tun wird nichts an den Anforderer zurückgeben" Das ist nicht richtig. Flask wandelt den Rückgabewert der Funktion automatisch in ein Response-Objekt um. http://flask.pooco.org/docs/0.10/quickstart/#about-responses –

0

In diesem Szenario in Ihrem Tutorial, die node.js Anwendung sendet eine HTTP-POST-Anfrage zurück zu Facebook Server, der den Inhalt dann an den Client weiterleitet.

Bisher klingt wie Ihre Flask App ist nur Empfang (AKA dient) HTTP-Anfragen. Der Grund ist, dass es in der Flask-Bibliothek darum geht, und das ist das Einzige, was Flask macht.

Um senden Sie eine HTTP-Anfrage zurück zu Facebook, können Sie jede Python HTTP-Client-Bibliothek, die Sie mögen. In der Standardbibliothek gibt es eine namens urllib, aber es ist ein wenig klobig zu verwenden ... versuchen Sie die Requests Bibliothek.

Da Ihr Anforderungshandler zu einem ausgehenden HTTP-Aufruf delegiert, müssen Sie auch die Antwort auf diese Unteranforderung überprüfen, um sicherzustellen, dass alles wie geplant ausgeführt wurde.

Der Handler kann am Ende so etwas wie

import json 
import os 
from flask import app, request 
# confusingly similar name, keep these straight in your head 
import requests 

FB_MESSAGES_ENDPOINT = "https://graph.facebook.com/v2.6/me/messages" 

# good practice: don't keep secrets in files, one day you'll accidentally 
# commit it and push it to github and then you'll be sad. in bash: 
# $ export FB_ACCESS_TOKEN=my-secret-fb-token 
FB_TOKEN = os.environ['FB_ACCESS_TOKEN'] 


@app.route('/', method="POST") 
def chatbot_response(): 
    data = request.json() # flasks's request object 
    sender_id = data["entry"][0]["messaging"][0]["sender"]["id"] 
    send_back_to_fb = { 
     "recipient": { 
      "id": sender_id, 
     }, 
     "message": "this is a test response message" 
    } 

    # the big change: use another library to send an HTTP request back to FB 
    fb_response = requests.post(FB_MESSAGES_ENDPOINT, 
           params={"access_token": FB_TOKEN}, 
           data=json.dumps(send_back_to_fb)) 

    # handle the response to the subrequest you made 
    if not fb_response.ok: 
     # log some useful info for yourself, for debugging 
     print 'jeepers. %s: %s' % (fb_response.status_code, fb_response.text) 

    # always return 200 to Facebook's original POST request so they know you 
    # handled their request 
    return "OK", 200 
+0

Danke für die Hilfe! Ich habe versucht, Ihr Beispiel zu laufen und bekam folgende Antwort vom FB: "jeepers. 400: {" error ": {" message ":" (# 100) param-Empfänger muss nicht leer sein. "," Type ":" OAuthException " , "code": 100, "fbtrace_id": ""} ". Ich habe auch versucht, Params Argument der Post-Anfrage oben mit dem Schlüssel (Wert "Empfänger": sender_id) zu ändern, aber ich bekomme immer noch den gleichen Fehler. Bizarr, da die sender_id definitiv ein tatsächlicher numerischer Wert ist. Irgendwelche Gedanken? – MEric

+0

zwei Wege zu verfolgen: erstens, debuggen mit 'print sender_id' oder' print send_back_to_fb' während des Aufrufs zu überprüfen, dass Sie tatsächlich senden einen Wert, der Sinn macht - immer eine gute Idee, die echte dumme Gesundheit Überprüfung zu tun. Zweitens, vielleicht benötigt FB den richtigen "application/json" -Header in Ihrer Anfrage, um den Inhalt, den Sie senden, zu verstehen. Versuchen Sie stattdessen, die Daten (unserialisiert) im 'json'-Kwarg zu übergeben:' requests.post (FB_MESSAGES_ENDPOINT, params = { "access_token": FB_TOKEN}, json = send_back_to_fb) ' –

+0

Ein weiteres praktisches Debug-Tool speziell für Facebook, schön, weil ihre Dokumente manchmal verwirrend oder veraltet sind: Probieren Sie das Graph-Explorer-Tool unter https://developers.facebook.com/ tools/explorer/... können Sie leicht rekonstruieren und mit der POST-Anfrage spielen, die Sie versuchen, während Sie die Komplexität Ihrer größeren bidirektionalen Interaktion beseitigen. –

0

suchen Dies ist der Code, der funktioniert für mich:

data = json.loads(request.data)['entry'][0]['messaging'] 
for m in data: 
    resp_id = m['sender']['id'] 
    resp_mess = { 
    'recipient': { 
     'id': resp_id, 
    }, 
    'message': { 
     'text': m['message']['text'], 
    } 
    } 
    fb_response = requests.post(FB_MESSAGES_ENDPOINT, 
           params={"access_token": FB_TOKEN}, 
           data=json.dumps(resp_mess), 
           headers = {'content-type': 'application/json'}) 

wichtigsten Unterschiede:

message braucht einen text Schlüssel für die eigentliche Antwortnachricht, und Sie müssen die application/jsoncontent-type Header hinzufügen.

Ohne die content-type Header erhalten Sie die The parameter recipient is required Fehlerreaktion und ohne die text Schlüssel unter message Sie erhalten die param message must be non-empty Fehlerreaktion.

1

Dies ist Flask Beispiel fbmq library verwenden, das funktioniert für mich:

Echo Beispiel:

from flask import Flask, request 
from fbmq import Page 

page = fbmq.Page(PAGE_ACCESS_TOKEN) 

@app.route('/webhook', methods=['POST']) 
def webhook(): 
    page.handle_webhook(request.get_data(as_text=True)) 
    return "ok" 

@page.handle_message 
def message_handler(event): 
    page.send(event.sender_id, event.message_text)