在Facebook Messenger机器人中保存/跟踪状态的正确方法是什么?

问题描述 投票:10回答:5

如果我的机器人提出不同的问题,如果用户回答了每个问题,我如何找出哪个答案与哪个问题相关。有一个称为元数据的字段,您可以将其附加到sendTextMessage API,但是当用户响应时,此元数据将以未定义的形式出现。你们是否使用任何节点缓存来跟踪状态或FSM,如machina.js?我怎样才能最好地弄清楚我们目前陷入的对话?

bots chatbot facebook-chatbot
5个回答
9
投票

当您的应用收到消息时,没有与之关联的有效负载或元数据。这与可以具有有效载荷的快速回复或后回复相反。将响应与问题相关联的唯一方法是按照@ anshuman-dhamoon的建议手动跟踪应用中的会话状态

为此,最好为每个用户维护一个状态,以及每个状态的下一个状态。

// optionally store this in a database
const users = {}

// an object of state constants
const states = {
    question1: 'question1',
    question2: 'question2',
    closing: 'closing',
}

// mapping of each to state to the message associated with each state
const messages = {
    [states.question1]: 'How are you today?',
    [states.question2]: 'Where are you from?',
    [states.closing]: 'That\'s cool. It\'s nice to meet you!',
}

// mapping of each state to the next state
const nextStates = {
    [states.question1]: states.question2,
    [states.question2]: states.closing,
}

const receivedMessage = (event) => {
    // keep track of each user by their senderId
    const senderId = event.sender.id
    if (!users[senderId].currentState){
        // set the initial state
        users[senderId].currentState = states.question1
    } else {
        // store the answer and update the state
        users[senderId][users[senderId].currentState] = event.message.text
        users[senderId].currentState = nextStates[users[senderId.currentState]]
    }
    // send a message to the user via the Messenger API
    sendTextMessage(senderId, messages[users[senderId].currentState])
}

注意如果您需要,您甚至可以将nextStates的值设置为可调用函数,这些函数将获取当前状态的答案,并根据用户的响应将用户传递到其他状态,从而分支到不同的会话流中。


3
投票

您可以在代码中包含状态代码,以跟踪用户与机器人的对话位置。

例如。如果你有10个问题,最初保持statuscode = 0,并询问第一个问题。当您收到向webhook发送的消息时,请检查statuscode == 0,并将该用户消息存储为对第一个问题的回复。然后递增statusCode = 1并询问下一个问题。

您可以使用多个标志和statusCodes来处理不同的会话流。


2
投票

据我所知,在Facebook聊天机器人中,您可以通过设置API reference中提供的回发按钮的有效负载,将数据从用户发送到聊天机器人。

并且聊天机器人不会存储您的会话或任何状态/标志。您可以设置状态或标志或数组,但是当您更新应用程序或重新启动服务器时,所有这些都将丢失。

所以,如果你真的想设置状态,你应该使用数据库。每次senderID都将保持相同,这样你就可以通过特定用户的特定id处理数据库中的数据。

有关详细信息,请查看technical referance here

我希望这会对你有所帮助。如果是这样,请将其标记为答案。


1
投票

我自己也遇到过这个问题。虽然在他们的文档中根本没有提到它,但我不认为附加内存数据库是不可能的。无论何时开始谈话,似乎user_id都是一样的。

每次用户重新加入会话时进行API调用都可能会降低机器人的性能。此外,我注意到,如果您正在建议的话,您无法通过使用API​​中的元数据键来构建“伪分布式数据库”。元数据标签可以从服务器 - >客户端(Messenger)发送,但不能从客户端 - >服务器发送文档所说的内容。


1
投票

我花了一些时间来处理这件事。最好的解决方案是使用数据库来跟踪用户的会话流。 POST对象包含发件人ID。您可以使用此ID在数据库中创建一行,您肯定需要在该行中存储此ID,问题的任何答案以及用于跟踪对话中哪个步骤的字段。

然后,您可以在代码中使用if语句来返回正确的响应。下面是一些示例代码:

if( $currentStep == '1' ){

    // Ask Next Question
    $message_to_reply = "Thank you! What's your name?";
    $message_to_reply = '"text":"'.$message_to_reply.'"';

} elseif( $currentStep == '2' ){

    // Ask Next Question
    $message_to_reply = "Thank you! What's your email address?";
    $message_to_reply = '"text":"'.$message_to_reply.'"';


} elseif( $currentStep == '3' ){

    // Ask Next Question
    $message_to_reply = "Thank you! What's your address?";
    $message_to_reply = '"text":"'.$message_to_reply.'"';

}
© www.soinside.com 2019 - 2024. All rights reserved.