Facebook webhook多次调用同一条消息?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Facebook webhook多次调用同一条消息?相关的知识,希望对你有一定的参考价值。
我使用Python和无服务器在AWS上创建并回显了bot。
我一次又一次地得到同样的要求。我读了faq,它说你必须提供一个状态代码200,否则它将继续重试webhook。
我不确定我是怎么做到的。
我注意到呼叫的序列号总是相同的,所以我假设我发送的回复没有被确认。我的代码在这里
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
我已经在很多地方给出了状态代码200,我不确定我是否仍然会遇到同样的问题。
如果您收到多条消息,则服务器未将200状态代码返回给Facebook服务器的webhook请求。这意味着您的部件发生错误,否则应返回200。在我看来,问题在于以下几点:
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}})
首先,您在消息的数据主体中传递statusCode,并根据此documentation消息响应不应包含它。
另一个问题可能是在params内发送状态代码。我将从send_message方法中完全删除状态代码。我怀疑它需要它。你基本上试图在错误的一端返回状态200。您试图在输出而不是输入(从Facebook的角度)返回它。
因此,您很可能正确地从Facebook获取消息,但您仍然返回错误的状态代码,因为您正在从消息传递事件内部调用send_message方法,而send_message方法应该返回状态“400错误请求”,因为您发送错误请求。因此您的服务器也返回错误的响应代码。
只需确保您的代码正常工作,就应该返回200。
编辑:所以我会尝试使用以下代码:
params = {"access_token": os.environment['accesstoken']}
headers = {"Content-Type": "application/json"}
data = json.dumps({"recipient": {"id": send_id},
"message": {"text": msg_txt}})
我正在使用Node / Express服务器开发Facebook Messenger聊天机器人,并且遇到了同样的问题。服务器正在适当地发送200个响应但问题仍然存在。我通过缓存消息ID并在处理之前检查重复项来解决问题:
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 .....
我希望这可以帮助别人。这让我疯了。
当您调用Facebook时,您的webhook回调应始终返回200 OK HTTP响应。如果不这样做,可能会导致您的webhook被Messenger平台取消订阅。 (从messenger docs复制。)您必须从返回的响应中搜索问题。它不是发送数据。
response = requests.post(POST_MESSAGE_URL, headers={ 'Content-Type': 'application/json' }, params={ 'access_token': ACCESS_TOKEN }, data=json.dumps(DATA_JSON)
这段代码对我来说很好
我来自Java背景,但我仍会尽力帮助你。
在处理webhook挑战中,我可以看到你返回200状态代码
但是在句柄消息传递块200中没有返回您已在发送消息中设置200状态代码。但是你必须从句柄消息块中返回200才行。
即使在此块中发生任何异常,也应返回200,否则将被阻止。所以可能在最后一块你可以返回200。
作为替代方案,您可以使用chatbotproxy.com,它始终在1ms内返回200并将完全相同的请求传递给您的端点。由于即时响应对于Facebook Messenger平台非常重要,1毫秒时间是一个非常有前途的功能。如果您需要帮助尝试,请告诉我。
以上是关于Facebook webhook多次调用同一条消息?的主要内容,如果未能解决你的问题,请参考以下文章
Facebook Messenger Delivery 回调随机丢失
Android:内容观察者的“onChange()”方法被多次调用
Facebook API页面提要没有向我的webhook发送信息?