【问题标题】:Facebook Messenger with Flask带有 Flask 的 Facebook Messenger
【发布时间】:2016-09-28 12:00:37
【问题描述】:

我正在尝试使用 Python 的 Flask 让 FB messenger API 工作,调整以下说明:https://developers.facebook.com/docs/messenger-platform/quickstart

到目前为止,一切进展顺利。我已经验证了我的回调并且能够在我的页面上接收我使用 Messenger 发送的消息,因为在我的 heroku 服务器中的日志中表明我的服务器正在接收适当的数据包。现在我正在努力向发送我的应用程序的客户端发送响应。特别是,我不确定如何在 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);
  }
});
}

到目前为止,我的服务器端 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

但是,运行此程序时,我发现虽然我可以处理某人发送给我的页面的内容,但它不会发回响应(即,在信使聊天框中没有显示任何内容)。我是 Flask 的新手,因此在 Flask 中执行与上面的 Javascript 位等效的任何帮助将不胜感激。

谢谢!

【问题讨论】:

    标签: python facebook heroku flask facebook-messenger


    【解决方案1】:

    这是适合我的代码:

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

    主要区别:

    message 需要一个 text 键用于实际响应消息,并且您需要添加 application/json content-type 标头。

    如果没有content-type 标头,您将获得The parameter recipient is required 错误响应,如果没有message 下的text 键,您将获得param message must be non-empty 错误响应。

    【讨论】:

      【解决方案2】:

      这是使用 fbmq library 的 Flask 示例,适用于我:

      回显示例:

      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)
      

      【讨论】:

        【解决方案3】:

        在您教程中的那个场景中,node.js 应用程序将 HTTP POST 请求发送回 Facebook 的服务器,然后将内容转发到客户端。

        到目前为止,听起来您的 Flask 应用程序仅接收(AKA 服务)HTTP 请求。原因是这就是 Flask 库的全部意义所在,也是 Flask 唯一要做的事情。

        要将 HTTP 请求发送回 Facebook,您可以使用任何您喜欢的 Python HTTP 客户端库。标准库中有一个叫urllib,但使用起来有点笨拙……试试Requests 库。

        由于您的请求处理程序委托给传出 HTTP 调用,您还需要查看对此子请求的响应,以确保一切按计划进行。

        您的处理程序最终可能看起来像

        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
        

        【讨论】:

        • 感谢您的帮助!我尝试运行您的示例并从 FB 得到以下响应:“jeepers。400: {"error":{"message":"(#100) 参数收件人必须为非空。","type":"OAuthException" “代码”:100,“fbtrace_id”:“}”。我还尝试使用 ("recipient": sender_id) 键/值对修改上面发布请求的 params 参数,但我仍然遇到相同的错误。奇怪的是 sender_id 绝对是一个实际的数值。有什么想法吗?
        • 两种途径:首先,在调用过程中使用print sender_idprint send_back_to_fb 进行调试以仔细检查您是否发送了一个有意义的值——做真实的总是一个好主意愚蠢的健全性检查。其次,也许 FB 在您的请求中需要正确的“application/json”标头以了解您发送的内容,请尝试在 json kwarg 中传递数据(未序列化):requests.post(FB_MESSAGES_ENDPOINT, params={"access_token": FB_TOKEN}, json=send_back_to_fb)
        • 另一个方便的 Facebook 调试工具,很好,因为有时他们的文档令人困惑或过时:尝试developers.facebook.com/tools/explorer 的图形浏览器工具...您可以轻松地重建和使用 POST请求您尝试同时消除较大的双向交互的一些复杂性。
        【解决方案4】:

        在 Flask 中进行响应时,必须小心。简单地执行return 语句不会向请求者返回任何内容。

        在您的情况下,您可能想查看jsonify()。它将接受一个 Python 字典并将其作为 JSON 对象返回到您的浏览器。

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

        如果您想对响应进行更多控制,例如设置代码,请查看make_response()

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-11-24
        • 1970-01-01
        • 1970-01-01
        • 2018-11-09
        • 2016-08-28
        • 1970-01-01
        • 2017-07-22
        • 2017-05-26
        相关资源
        最近更新 更多