问题
I made and echo bot on AWS with Python and serverless.
I keep getting the same request again and again. I read the faq where it says u have to deliver a status code 200 else it will keep retrying the webhook.
I'm not sure How I do this.
I have noticed that the sequence number is always the same for the calls so I assume the reply I sent was not acknowledged. my code is here
import os
import json
import requests
import random
from datetime import datetime
######################
# helper functions
######################
##recursively look/return for an item in dict given key
def find_item(obj, key):
item = None
if key in obj: return obj[key]
for k, v in obj.items():
if isinstance(v,dict):
item = find_item(v, key)
if item is not None:
return item
##recursivley check for items in a dict given key
def keys_exist(obj, keys):
for key in keys:
if find_item(obj, key) is None:
return(False)
return(True)
##send txt via messenger to id
def send_message(send_id, msg_txt):
print("Send message called")
print (datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
params = {"statusCode": 200,"access_token": os.environment['accesstoken']}
headers = {"statusCode": "200","Content-Type": "application/json"}
data = json.dumps({"statusCode": "200","recipient": {"id": send_id},
"message": {"text": msg_txt}})
r = requests.post("https://graph.facebook.com/v2.9/me/messages", params=params, headers=headers, data=data)
print (r.text)
if r.status_code != 200:
print(r.status_code)
print(r.text)
#-----------------------------------------------------------
def hello(event, context):
#debug
event=json.loads(json.dumps(event))
print("event:" )
print(event)
# print("context")
# print(context)
#handle webhook challenge
try:
if keys_exist(event, ["queryStringParameters","hub.verify_token","hub.challenge"]):
print("subscribe to webhook invoked")
v_token = str(find_item(event, 'hub.verify_token'))
challenge = find_item(event, 'hub.challenge')
if ("strongtoken" == v_token):
response = {
"statusCode": 200,
"body": str(challenge)
}
print(challenge)
return response
#handle messaging events
if keys_exist(event, ['body']):
event_entry=json.loads(event['body'])
if ((len(event_entry['entry'])>0) & (keys_exist(event_entry['entry'][0],['messaging'])) ):
messaging_event = event_entry['entry'][0]['messaging'][0]
if (keys_exist(messaging_event,['message'])):
msg_txt = messaging_event['message']['text']
sender_id = messaging_event['sender']['id']
print(sender_id)
first_word = msg_txt.split(" ")[0]
send_message(sender_id, msg_txt)
else:
print("Did not send message")
pass
else:
print("Did not send message")
pass
else:
pass
except:
pass
I have given the status code 200 in soo many places and I'm not sure y I still keep getting the same problem.
回答1:
If you are getting multiple messages your server did not return 200 status code to webhook request from Facebook server. This means an error occurred on your part otherwise 200 should be returned. It looks to me that problems are in following lines:
params = {"statusCode": 200,"access_token": os.environment['accesstoken']}
headers = {"statusCode": "200","Content-Type": "application/json"}
data = json.dumps({"statusCode": "200","recipient": {"id": send_id},
"message": {"text": msg_txt}})
Firstly you are passing statusCode in a data body of message and according to this documentation message response should not contain it.
Another problem could be sending status code inside params. I would remove status code completely from send_message method. I doubt its needed there. You are basically trying to return status 200 on wrong end. You are trying to return it on output instead of input (from Facebooks point of view).
So its quite possible you are correctly getting message from Facebook but you are still returning wrong status code because you are calling send_message method from inside messaging event and send_message method should return status "400 bad request" because you are sending faulty request. Thus your server also returns wrong response code.
Just make sure your code works correctly and 200 should be returned.
EDIT: So i would try with following code:
params = {"access_token": os.environment['accesstoken']}
headers = {"Content-Type": "application/json"}
data = json.dumps({"recipient": {"id": send_id},
"message": {"text": msg_txt}})
回答2:
I'm working on a Facebook Messenger chatbot with a Node/Express server and was having the same exact issue. The server was appropriately sending 200 responses and yet the issue persisted. I resolved the problem by caching message ID's and checking for duplicates before processing:
var NodeCache = require('node-cache');
var myCache = new NodeCache();
app.post('/webhook/', function(req, res) {
var messageID = req.body.entry[0].messaging[0].message.mid;
var checkForDupe = myCache.get(messageID);
if (checkForDupe == undefined) {
var setID = myCache.set(req.body.entry[0].messaging[0].message.mid, req.body.entry[0].messaging[0].message.mid);
//Handle message .....
I hope this helps someone. It was driving me nuts.
回答3:
Your webhook callback should always return a 200 OK HTTP response when invoked by Facebook. Failing to do so may cause your webhook to be unsubscribed by the Messenger Platform. (copied from messenger docs.) You have to search problem from your returning response. It is not with the sending data.
response = requests.post(POST_MESSAGE_URL, headers={ 'Content-Type': 'application/json' }, params={ 'access_token': ACCESS_TOKEN }, data=json.dumps(DATA_JSON)
this code working fine for me
回答4:
I am from Java background but still I will try to help you.
In handle webhook challenge I can see you returning 200 status code
But in handle messaging block 200 is not returned You have set 200 status code in send message. But it will not work you have to return 200 from handle messaging block.
Also 200 should be returned even if any exception occurs in this block otherwise on exception it will get blocked. So may be in finally block you can return 200.
回答5:
As an alternative, you can use chatbotproxy.com which always return 200 in 1ms and pass the exact same request to your endpoint. Since immediate response is very important for Facebook Messenger platform, 1 millisecond time is a very promising feature. If you need help to try, let me know.
来源:https://stackoverflow.com/questions/44848406/facebook-webhook-making-multiple-calls-for-the-same-message