2016-05-05 1 views
1

J'essaie d'obtenir l'API messager de FB de travail en utilisant Flask Python, adapter les instructions suivantes: https://developers.facebook.com/docs/messenger-platform/quickstartFacebook Messenger avec Flask

Jusqu'à présent, les choses ont été assez bien va. J'ai vérifié mon rappel et suis capable de recevoir les messages que j'envoie en utilisant Messenger sur ma page, comme dans les journaux de mon serveur heroku indiquent que les paquets de données appropriés sont reçus par mon serveur. En ce moment, je me bats un peu pour envoyer des réponses au client de messagerie mon application. En particulier, je ne sais pas comment effectuer le segment suivant du tutoriel en Flask:

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); 
    } 
}); 
} 

Jusqu'à présent, j'ai ce bit dans mon côté serveur module Flask:

@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 

Cependant, En cours d'exécution, je trouve que même si je peux traiter ce que quelqu'un envoie à ma page, il n'envoie pas de réponse (c'est-à-dire que rien ne s'affiche dans la boîte de dialogue Messenger). Je suis nouveau à Flask donc toute aide serait grandement appréciée en faisant l'équivalent du bit Javascript ci-dessus dans Flask.

Merci!

Répondre

-1

Lorsque vous faites des réponses dans Flask, vous devez faire attention. Faire simplement une instruction return ne retournera rien au demandeur. Dans votre cas, vous pouvez regarder jsonify(). Il faudra un dictionnaire Python et le retourner dans votre navigateur en tant qu'objet JSON.

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

Si vous voulez plus de contrôle sur les réponses, comme le réglage des codes, jetez un oeil à make_response()

+0

«Il suffit de faire une déclaration de retour ne retournera rien au demandeur » Ce n'est pas correct. Flask transforme automatiquement la valeur de retour de la fonction en un objet Response. http://flask.pocoo.org/docs/0.10/quickstart/#about-responses –

0

Dans ce scénario dans votre tutoriel, l'application Node.js envoie une requête HTTP POST retour à Facebook de serveurs, qui transmet ensuite le contenu au client.

Jusqu'à présent, ressemble à votre application Flask est seulement recevoir (AKA au service) requêtes HTTP. La raison en est que c'est ce à quoi sert la bibliothèque Flask, et c'est la seule chose que fait Flask.

Pour envoyez une requête HTTP de nouveau à Facebook, vous pouvez utiliser n'importe quelle bibliothèque client HTTP Python que vous aimez. Il y en a un appelé urllib dans la bibliothèque standard, mais c'est un peu maladroit à utiliser ... essayez la bibliothèque Requests.

Étant donné que votre gestionnaire de requêtes délègue à un appel HTTP sortant, vous devez également consulter la réponse à cette sous-demande pour vous assurer que tout s'est déroulé comme prévu.

Votre gestionnaire peut finir par quelque chose comme

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

Merci pour l'aide! J'ai essayé d'exécuter votre exemple et j'ai reçu la réponse suivante de FB: "jeepers 400: {" error ": {" message ":" (# 100) le destinataire de param doit être non vide. "," Type ":" OAuthException " , "code": 100, "fbtrace_id": ""} ". J'ai également essayé de modifier l'argument params de la requête de publication ci-dessus avec la paire clé/valeur ("recipient": sender_id), mais je reçois toujours la même erreur. Bizarre puisque le sender_id est définitivement une valeur numérique réelle. Des pensées? – MEric

+0

deux pistes à explorer: tout d'abord, déboguer avec 'print sender_id' ou' print send_back_to_fb' lors de l'appel pour vérifier que vous envoyez réellement une valeur logique - toujours une bonne idée de faire la vraie vérification stupide. Deuxièmement, peut-être que FB a besoin de l'en-tête "application/json" correct dans votre requête pour comprendre le contenu que vous envoyez, essayez plutôt de passer les données (non sérialisées) dans le fichier 'json' kwarg:' requests.post (FB_MESSAGES_ENDPOINT, params = { "access_token": FB_TOKEN}, json = send_back_to_fb) ' –

+0

Un autre outil de débogage pratique pour Facebook spécifiquement, sympa parce que parfois leurs documents sont confus ou périmés: essayez l'outil d'exploration graphique à https://developers.facebook.com/ tools/explorer/... vous pouvez facilement reconstruire et jouer avec la requête POST que vous tentez tout en supprimant une partie de la complexité de votre plus grande interaction bidirectionnelle. –

0

Ceci est le code qui fonctionne pour moi:

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'}) 

principales différences:

message a besoin d'une clé text pour la réelle message de réponse, et vous devez ajouter l'en-tête application/jsoncontent-type.

Sans l'en-tête content-type vous obtenez la réponse d'erreur The parameter recipient is required, et sans text clé sous message vous obtenez la réponse d'erreur param message must be non-empty.

1

Ceci est l'exemple à l'aide Flask fbmq library qui fonctionne pour moi:

exemple écho:

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)