【问题标题】:How to handle user leaving conversation如何处理用户离开对话
【发布时间】:2021-08-07 07:39:01
【问题描述】:

我们欢迎使用 OnMembersAddedAsync 方法的示例,但没有显示如何处理用户离开对话的示例。我试图覆盖 OnMembersRemovedAsync 但它似乎没有被调用(至少在我使用机器人框架模拟器时)。

我需要在用户离开/离开对话时进行一些清理。 一个例子或任何提示将不胜感激。

更新:我正在使用 C# 和 Bot 框架 v4

【问题讨论】:

  • 你能提供你尝试过的代码吗(你可以编辑你原来的帖子)?而且,您能否详细说明您希望在用户离开时采取的行动?
  • 另外,您使用的是哪个 SDK(v3 或 v4,C# 或 Node)?
  • 我还没有任何代码。我只是重写了 OnMembersRemovedAsync 方法并尝试查看它何时被调用。到目前为止,我只能通过邮递员发送对话更新来做到这一点,如下所述:github.com/microsoft/BotFramework-Emulator/issues/…
  • 我试图弄清楚当用户关闭网络聊天或 Facebook 对话时是否正在发送此事件。所以我可以处理那个事件。我计划在机器人无法提供帮助时让人工代理介入,他们需要知道用户是否仍然存在或关闭网络聊天或 Facebook 聊天。

标签: botframework


【解决方案1】:

这将是特定于频道的,因为它依赖于提供在用户离开对话时发送更新的功能的频道。任何其他渠道,您都需要研究。

对于 Facebook,我无法找到涵盖此类操作的范围。这些是可用的范围,您可以更仔细地参考here

  • 消息
  • message_deliveries
  • message_echoes
  • message_reads
  • messaging_account_linking
  • messaging_checkout_updates(测试版)
  • messaging_game_plays
  • messaging_handovers
  • messaging_optins
  • messaging_payments(测试版)
  • messaging_policy_enforcement
  • messaging_postbacks
  • messaging_pre_checkouts(测试版)
  • messaging_referrals
  • 待机

网络聊天作为一项功能,也不包含此功能。但是,鉴于这是一个网页,您可以利用 onbeforeunload() 窗口函数来调度事件。事件侦听器将利用网络聊天的存储向机器人发送消息或事件。为了清楚起见,我通过SEND_MESSAGESEND_EVENT 发送不同类型的数据。

const store = window.WebChat.createStore( {}, ( { dispatch } ) => next => async action => {
  return next( action );
};

window.addEventListener( 'sendEventActivity', ( { data } ) => {
  store.dispatch({
    type: 'WEB_CHAT/SEND_MESSAGE',
    payload: {
      text: data
    }
  } )
  ,
  store.dispatch( {
    type: 'WEB_CHAT/SEND_EVENT',
    payload: {
      name: 'user_event',
      value: {
        name: 'end_conversation',
        value: 'user ended conversation'
      },
      text: 'The user has left the conversation.'
    }
  } )
} );

window.onbeforeunload = function() {
  const eventSendActivity = new Event( 'sendEventActivity' );
  eventSendActivity.data = 'User left conversation';
  window.dispatchEvent( eventSendActivity );
}
{ type: 'message',
  id: '4uPdpZhlTFfBMziBE7EmEI-f|0000004',
  timestamp: 2020-01-10T18:21:26.767Z,
  serviceUrl: 'https://directline.botframework.com/',
  channelId: 'directline',
  from: { id: 'dl_123', name: 'johndoe', role: 'user' },
  conversation: { id: '4uPdpZhlTFfBMziBE7EmEI-f' },
  recipient: { id: 'botberg@QaeuoeEamLg', name: 'Dungeon Runner' },
  textFormat: 'plain',
  locale: 'en-US',
  text: 'User left conversation',
  channelData:
  { clientActivityID: '15786804807910gegwkp2kai',
    clientTimestamp: '2020-01-10T18:21:20.792Z' }
}

{ type: 'event',
  id: '4uPdpZhlTFfBMziBE7EmEI-f|0000005',
  timestamp: 2020-01-10T18:21:26.780Z,
  serviceUrl: 'https://directline.botframework.com/',
  channelId: 'directline',
  from: { id: 'dl_123', name: 'johndoe', role: 'user' },
  conversation: { id: '4uPdpZhlTFfBMziBE7EmEI-f' },
  recipient: { id: 'botberg@QaeuoeEamLg', name: 'Dungeon Runner' },
  locale: 'en-US',
  channelData:
  { clientActivityID: '1578680480821h7kgfm9cyz',
    clientTimestamp: '2020-01-10T18:21:20.821Z' },
  value:
  { name: 'end_conversation', value: 'user ended conversation' },
  name: 'user_event'
}

希望有帮助!


更新(2021 年 8 月 6 日):

作为 Chrome 和其他浏览器,在 onbeforeunload() 期间不允许阻塞/延迟关闭窗口,使用事件处理程序或侦听器发送事件通常是不可靠的,充其量。在最坏的情况下,它根本不起作用。

但是,通过使用“window.navigator.sendBeacon()”(如果它受支持),确实可以使用另一种方法。

sendBeacon 是 fetch 的低级简化版本,它“通过 HTTP 将少量数据异步发送到 Web 服务器”。它仅作为 POST 发送,仅将 URL 或 URL + 数据作为属性,并且不等待响应。正如文档所述:

  • 数据发送可靠
  • 异步发送
  • 不影响下一页的加载

在测试中,我已将它与我的机器人中的 proactive messaging 端点结合起来,它似乎工作得很好。 (下面我的代码示例是用 JS 编写的,从一个项目中提取 - 作为参考,这里是主动消息传递 C# sample,也有其他语言版本。

当我导航到另一个页面或关闭浏览器时,sendBeacon 将消息发布到创建主动消息的端点,而后者又将活动发送到机器人。当我返回 Web 聊天页面时,该消息现在在聊天窗口中可见。请记住,我还在网络聊天中设置了persistence,允许我返回之前开始的对话。

在下图中,我演示了加载网络聊天,导航到浏览器的主页,然后返回 - 主动消息现在在聊天中可见。

(网络聊天)托管页面:

window.onbeforeunload = () => {
    let body = { user: { userName: 'McUser', userId: 'abc123' } };

    const headers = { type: 'application/json', 'Access-Control-Allow-Origin': '*' };
    const blob = new Blob( [ JSON.stringify( body ) ], headers )
    navigator.sendBeacon( 'http://localhost:3978/api/notify', blob )
}

Bot 的主动消息传递端点:

server.post('/api/notify', async (req, res) => {
    const userName = req.body.user.userName;
    const userId = req.body.user.userId;
    for (const conversationReference of Object.values(conversationReferences)) {
      await adapter.continueConversation(conversationReference, async (turnContext) => {
        await turnContext.sendActivity(`${ userName } (userId: ${ userId }) exited chat.`);
      });
    }
  });

【讨论】:

  • 是否有事件有效负载的架构?为什么名称/值这样嵌套:有效负载:{名称:'user_event',值:{名称:'end_conversation',值:'用户结束对话'}?如果要发送自定义事件,我应该为外部和内部“名称”设置什么?
  • 我如何从机器人端接收这个事件?我重写了 OnEventActivityAsync 方法,但它没有触发。
  • 抱歉,@zape。我没有看到你的cmets。这是可用调度actions 的列表,包括SEND_EVENT。架构在每个内部都有详细说明。有效负载按原样嵌套,因为这就是网络聊天开发人员对其进行编码的方式。至于任何命名,这完全取决于你。遵循你已经遵循的任何惯例。
  • 关于接收活动的机器人,它可以被活动处理程序拾取。它们位于您的 [bot].cs 文件中,可通过 ActivityHandler 类访问。在那里你可能会找到OnTurnAsync() 和/或OnMessageAsync()。还有其他可以添加以更好地满足您的需求。查看可用处理程序列表here
  • 必须将 store 传递给 WebChat.createDirectLine 才能使其正常工作。花了一段时间才弄明白
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-06
  • 1970-01-01
  • 1970-01-01
  • 2017-08-30
  • 1970-01-01
  • 2015-11-10
  • 1970-01-01
相关资源
最近更新 更多