Facebook Messenger Webhook设置,但未触发

45

我正在尝试为新的Facebook Messenger API设置机器人。

我正在遵循快速入门指南

我成功设置了Webhook,并在我的Webhooks中看到它。

我调用了这个:

https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=%3Ctoken%3E

并且它没有抛出任何错误,

但是当我转到生成访问令牌的页面并发送消息时,它不会调用我的 Webhook。 我检查了 httpaccess,它也没有调用它。

有什么方法可以调试这个问题或者有什么想法吗?

另外,仍然困惑的一件事是如何支持从一个 Facebook 应用程序管理多个页面?有人知道答案吗?还是你需要创建一个新应用程序并为每个页面获取权限?

7个回答

66
我最近使用了新的聊天机器人API,有很多事情可能会出错。所以,这里有一些想法。
- 确保您在产品设置选项卡下验证了您的Webhook。 - 使用您的页面访问令牌订阅您的应用程序到页面上。如果一切顺利,它会返回{"success" : "true"}。
重要提示:
请确保您发送消息的Facebook用户在您的应用角色(https://developers.facebook.com/apps/YOUR_APP_ID/roles/)中被列为管理员开发者测试人员。除非您的应用已获批准并公开发布,否则来自其他用户的消息将无法正常工作。
您是否收到了来自Facebook API的任何回调?还是只有消息?请查看您的Web服务器日志,检查是否有任何Webhook的命中。同时,请检查错误日志。
尝试手动触发您的Webhook并查看是否有响应。您可以使用curl生成手动请求。以下是来自Facebook的请求示例: 命令:
curl -i -X POST -H 'Content-Type: application/json' -d '{"object":"page","entry":[{"id":43674671559,"time":1460620433256,"messaging":[{"sender":{"id":123456789},"recipient":{"id":987654321},"timestamp":1460620433123,"message":{"mid":"mid.1460620432888:f8e3412003d2d1cd93","seq":12604,"text":"Testing Chat Bot .."}}]}]}' https://www.YOUR_WEBHOOK_URL_HERE

1
另一个问题是:PageId必须是数字页面ID,而不是友好的URL ID。我唯一能找到这个的方法是查看页面源代码,并在JavaScript中搜索page_id。 - Rick Love
3
@Rick ...或者你可以简单地点击你页面的“关于”选项卡,你的“Facebook Page ID”会列在“页面信息”部分的底部。 - Mukarram Khalid
1
我的应用程序已经上线,不在开发中。我可以在管理员角色下写入时触发Webhook,但在另一个Facebook帐户下写入时无法触发。可能是什么问题? - kkica
1
确保这个Facebook用户解决了问题!我在那里卡了3个小时! - Tamil Vendhan Kanagarasu

16

我的问题是在尝试订阅时调用了GET而不是POST。

https://graph.facebook.com/v2.6/:pageid/subscribed_apps?access_token=:token

GET将返回当前订阅(空{[]}),POST将返回{"success":"true"}

我遇到的一些其他注意事项是,

我仍然困惑的一件事是如何支持从一个Facebook应用程序管理多个页面? 有人知道答案吗?还是您需要为每个页面创建新的应用程序并获得权限?


提醒一下,您可以接受自己的答案(http://blog.stackoverflow.com/2009/01/accept-your-own-answers/)。这将把它从“未回答”类别中移除。 - gar
如果你的 Webhook 抛出错误,Facebook 将暂停向你发送消息,这个提示对我很有帮助。 - Jason Logsdon

8
另一个可能导致某些响应无法发送到您的Webhook的原因是消息类型在队列中被阻止。如果某个特定的消息类型被传递到您的Webhook,但在20秒内没有收到其200响应,则它将不断尝试发送该消息,直到数小时后。此外,Facebook Messenger会停止向您发送任何该类型的消息,直到第一个消息已被确认。它实际上将它们放入队列中。同时,其他消息类型将继续正常发送。当我在处理标准消息的代码中意外引入一个未声明的变量时,就发生了这种情况。这意味着后退消息都能正常工作,但快速回复和普通消息将永远无法发送到我的Webhook。只要你修复了错误,它们就会一下子涌现出来。正如其他人所提到的,使用像POSTMAN这样的服务向您的Webhook发送消息是发现此类错误的好方法,否则Messenger将默默地失败。

1
嘿!非常感谢你!你救了我的一天!我花了10多个小时解决一个Messenger API问题,看到了你的答案,意识到我的消息被FB连续阻止,因为我没有用状态码200进行响应。 - 尤川豪
1
你如何让 Messenger 继续推送队列?看起来队列卡住了,Webhook 没有触发任何其他事件。一旦代码修复,有没有办法让 Messenger “重试”呢? - Marchy
@Marchy,它应该已经在持续向您的应用程序发送这些请求。您无需告诉它重试。最有可能的是它没有得到令人满意的200响应。我猜它最终会放弃,但此时将不再有队列,并且不会被阻止。 尝试复制Facebook发送到您的Webhook的内容,并使用CURL或Postman自己发送并检查响应。我怀疑仍然存在错误。 - elMarquis
1
我的应用程序已经上线,很可能有一些消息被卡在队列中。偶尔会有一两条消息传送成功。如何清除这些消息,以便至少能够发送新的消息? - shanti
@shanti,你是怎么解决这个错误的?我正在使用ngrok来暴露我的本地端口。它连接到Facebook的webhook。但是如果我向Facebook发送任何消息,它不会向我的服务器发送http请求。我认为我面临着和你一样的问题。 - Maharun Afroz

5

如果您使用的是框架,将机器人路由从CSRF验证中排除可以帮助您。这对于我来说很有用(例如Laravel 5.4,app / Http / Middleware / VerifyCsrfToken.php):

protected $except = [
        '/your_bot_route'
    ];

哥们,你救了我了!我已经很长时间一直在寻找解决方案,而你的回答解决了我的问题,非常感谢! - softya

1

几天前我在开发一个机器人时也遇到了同样的问题。按照这个 gist 进行修改,代码如下所示,现在一切正常工作。

public function index()
    {

        $challenge = $_REQUEST['hub_challenge'];
        $verify_token = $_REQUEST['hub_verify_token'];
        // Set this Verify Token Value on your Facebook App
        if ($verify_token === 'MyVerifyToken!') {
            echo $challenge;
        }
        $input = json_decode(file_get_contents('php://input'), true);
        // Get the Senders Graph ID
        $sender = $input['entry'][0]['messaging'][0]['sender']['id'];
        // Get the returned message
        $message = $input['entry'][0]['messaging'][0]['message']['text'];
        //$senderName = $input['entry'][0]['messaging'][0]['sender']['name'];

        $reply="Sorry, I don't understand you";

        switch($message)
        {
            case 'hello':
                $reply = "Hello, Greetings from MyApp.";
                break;
            case 'pricing':
                $reply = "Sample reply for pricing";
                break;
            case 'contact':
                $reply = "Sample reply for contact query";
                break;
            case 'webinar':
                $reply = "Sample reply for webinar";
                break;
            case 'support':
                $reply = "sample reply for support";
                break;
            default:
                $reply="Sorry, I don't understand you";
        }
        //API Url and Access Token, generate this token value on your Facebook App Page
        $url = 'https://graph.facebook.com/v2.6/me/messages?access_token=MYACCESSTOKEN';
        //Initiate cURL.
        $ch = curl_init($url);
        //The JSON data.
        $jsonData = '{
        "recipient":{
        "id":"' . $sender . '"
        },
        "message":{
            "text":"'.$reply.'"
            }
        }';
//Tell cURL that we want to send a POST request.
        curl_setopt($ch, CURLOPT_POST, 1);
//Attach our encoded JSON string to the POST fields.
        curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
//Set the content type to application/json
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
//Execute the request but first check if the message is not empty.
        if (!empty($input['entry'][0]['messaging'][0]['message'])) {
            $result = curl_exec($ch);
        }

    }

注意:确保应用程序页面中的用户角色可以从 Web 钩子获取响应。我已设置管理员和测试用户。只有他们能够获得响应。其他用户将在发布后获得。此外,相应更改验证令牌和页面令牌。
在发布应用程序时会询问有多少个企业将使用此机器人的选项。但我不知道如何使用它。尽管如此,我仍在搜索。

0
如果您仍然无法解决问题,请尝试检查并更新您的隐私政策链接。
我已经更新了隐私政策链接,但Facebook显示404错误,即使Webhook已经验证...

-1

您可以在 Messenger 设置的“添加或删除页面”选项卡下,将多个页面链接到您的应用程序中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接