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

Posted

技术标签:

【中文标题】在 Facebook Messenger 机器人中保存/跟踪状态的正确方法是啥?【英文标题】:What is the right way to save/track state inside a Facebook Messenger bot?在 Facebook Messenger 机器人中保存/跟踪状态的正确方法是什么? 【发布时间】:2016-12-28 18:23:37 【问题描述】:

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

【问题讨论】:

【参考方案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.'"';


【讨论】:

【参考方案2】:

当您的应用收到消息时,没有与之关联的有效负载或元数据。这与可以具有有效负载的快速回复或回发相反。将响应与问题相关联的唯一方法是按照@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】:

据我所知,在 Facebook 聊天机器人中,您只需像 API reference 中给出的那样设置 来自回发按钮的有效负载,即可将数据从用户发送到聊天机器人。

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

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

更多详情请查看technical referance here。

希望对您有所帮助。如果可以,请将其标记为答案。

【讨论】:

元数据不起作用,它返回未定义,我试过了 只需通过回传按钮在有效负载中传递数据 只有订阅echo时才会返回元数据,我不清楚它有什么用-developers.facebook.com/docs/messenger-platform/…【参考方案4】:

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

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

【讨论】:

不错,到目前为止运气好吗? db 是保存状态的唯一方法吗?【参考方案5】:

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

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

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

【讨论】:

以上是关于在 Facebook Messenger 机器人中保存/跟踪状态的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Facebook Messenger 机器人反应通知

Facebook Messenger Bot:会话变量

“正在输入...”指示在 bot 框架 + facebook Messenger 中不会消失

来自 Facebook Messenger 机器人对话的 API 身份验证

Facebook Messenger 聊天机器人显示“检查您的连接并重试”。

Facebook Messenger bot 的消息大小限制