12

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

4

5 回答 5

14

当您的应用收到消息时,没有与之关联的有效负载或元数据。这与可以具有有效负载的快速回复或回发相反。将响应与问题相关联的唯一方法是按照@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转换为可调用函数,这些函数获取当前状态的答案,并根据用户的响应将用户传递到不同的状态,从而分支到不同的对话流中。

于 2017-04-14T03:37:35.997 回答
6

据我所知,在 Facebook 聊天机器人中,您只需按照API 参考中给出的回发按钮设置有效负载,就可以将数据从用户发送到聊天机器人。

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

所以,如果你真的想设置状态,你应该使用数据库。并且senderID每次都会保持不变,这样你就可以通过特定用户的特定 ID 处理来自数据库的数据。

有关更多详细信息,请在此处查看技术参考。

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

于 2016-09-07T06:40:12.733 回答
3

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

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

您可以有多个标志和状态代码来处理不同的对话流。

于 2016-08-30T10:52:15.270 回答
1

我自己也遇到了这个问题。尽管他们的文档中根本没有提到它,但我认为附加内存数据库并不是不可能的。user_id无论何时启动对话,似乎都是相同的。

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

于 2016-09-02T19:55:52.637 回答
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.'"';

}
于 2017-12-21T20:26:22.420 回答