代理通过直线转至全渠道客户服务

问题描述 投票:0回答:1

我在将 Copilot Studio 机器人连接到全渠道客户服务(客服人员交接)时遇到问题

上下文:

我使用 copilot studio 构建了一个聊天机器人并将其集成到我的 Web 应用程序中。我必须为此机器人使用 Direct Line 和自定义画布,因为:

  1.我想完全自定义机器人的外观和感觉以匹配应用程序风格

  2. 当用户单击我在页面上创建的按钮时,我想初始化聊天(并首先显示机器人消息)。 

  3. 我也这样做是因为我需要在初始化时将令牌从我的应用程序传递到聊天机器人 - 该令牌由机器人接收,并调用一个强大的自动化流程来解码令牌并将一堆变量存储在全局上下文(最值得注意的是我的 api 的身份验证令牌,机器人可以使用它来调用我的 api 并使用特定于客户端的信息响应客户端。)

这是设置该功能的工作代码片段:

  useEffect(() => {
    const getFromLocalStorage = async () => {
      const channel = await AsyncStorage.getItem(DIRECT_CHANNEL_STORAGE_KEY);
      if (channel) {
        setDirectLineChannel(JSON.parse(channel));
        setIsChatWindowOpen(true);
      }
    };
    getFromLocalStorage();

    return () => AsyncStorage.removeItem(DIRECT_CHANNEL_STORAGE_KEY);
  }, []);

  useEffect(() => {
    if (!isChatWindowOpen) return;
    const styleSet = window.WebChat.createStyleSet(webChatStyleSet);

    const handleDirectLineToken = async () => {
      const now = Date.now();
      if (isEmpty(directLineChannel)
        || loanNumber !== directLineChannel.id
        || now > directLineChannel.expiration
      ) {
        try {
          const res = await fetch(process.env.PVA_TOKEN_ENDPOINT);
          const result = await res.json();
          const newDirectLineChannel = {
            expiration: now + result.expires_in * 1000,
            id: loanNumber,
            token: result.token,
          };
          setDirectLineChannel(newDirectLineChannel);
          await AsyncStorage.setItem(
            DIRECT_CHANNEL_STORAGE_KEY, JSON.stringify(newDirectLineChannel)
          );
        } catch (err) {
          setDirectLineChannel({});
          await AsyncStorage.removeItem(DIRECT_CHANNEL_STORAGE_KEY);
        }
      }
    };

    const store = window.WebChat.createStore({},
      ({ dispatch }) => (next) => (action) => {
        const { type } = action;
        if (type === 'DIRECT_LINE/CONNECT_FULFILLED') {
          new Promise((resolve) => {
            dispatch({
              payload: {
                name: 'pvaSetContext',
                value: { token: pvaToken },
              },
              type: 'WEB_CHAT/SEND_EVENT',
            });
            setTimeout(() => resolve(1), 1000);
          }).then(() => {
            dispatch({
              meta: { method: 'keyboard' },
              payload: {
                activity: {
                  channelData: { postBack: true },
                  name: 'startConversation',
                  type: 'event',
                },
              },
              type: 'DIRECT_LINE/POST_ACTIVITY',
            });
          });
        }
        return next(action);
      });

    const renderChat = async () => {
      if (prevLoanNumber === loanNumber && isChatConnected) return;
      try {
        await handleDirectLineToken();
        if (!isEmpty(directLineChannel)) {
          const { token } = directLineChannel;
          window.WebChat.renderWebChat(
            {
              cardActionMiddleware: () => (next) => async ({ cardAction }) => {
                const { type, value } = cardAction;
                if (type === 'openUrl') {
                  const { pathname } = new URL(value);
                  return handleNav(pathname);
                }
                return next({ cardAction });
              },
              directLine: window.WebChat.createDirectLine({ token }),
              store,
              styleOptions,
              styleSet,
            },
            document.getElementById('webchat')
          );
          if (prevLoanNumber !== loanNumber) {
            setIsChatConnected(false);
            setShouldShowSkeleton(true);
            setShouldShowCloseConfirmationScreen(false);
          } else {
            setIsChatConnected(true);
            dispatchPVAChatInitiated();
          }
        }
      } catch {
        await handleDisconnectChat();
      }
    };

    renderChat();
  }, [
    directLineChannel,
    dispatchPVAChatInitiated,
    handleNav,
    isChatConnected,
    isChatWindowOpen,
    loanNumber,
    prevLoanNumber,
    pvaToken,
    styleOptions,
    webChatStyleSet,
  ]);

  useEffect(() => {
    if (shouldShowSkeleton) {
      setTimeout(() => {
        setShouldShowSkeleton(false);
      }, 2500);
    }
  }, [shouldShowSkeleton]);

  const handleDisconnectChat = async () => {
    setIsChatWindowOpen(false);
    setShouldShowCloseConfirmationScreen(false);
    setIsChatConnected(false);
    setDirectLineChannel({});
    await AsyncStorage.removeItem(DIRECT_CHANNEL_STORAGE_KEY);
  };

  const handleInitiateChat = () => {
    setShouldShowSkeleton(true);
    setIsChatWindowOpen(true);
  };

我已经部署了聊天机器人的应用程序并且运行良好。

现在,如果遇到升级主题,我想实施代理切换。这就是我遇到问题的地方。我能够将全渠道客户服务连接到该聊天机器人(据我所知),并且我获得了一个嵌入脚本。

- 如果我将该脚本嵌入到我的代码中,我就可以开始聊天并连接到全渠道仪表板中的实时代理,但是,问题是如果没有提供所需的令牌,机器人将无法运行。另外,我设置的任何样式都不会出现。 (使用这个脚本不是一个可行的解决方案)

- 如果我按原样使用我的机器人并启动座席切换,它永远不会连接到全渠道(它只是挂在“将您转移到实时座席...”文本上。

那么,我的问题是如何在我当前的实施中实现这一点?显然,我一定缺少一些东西。我能够拦截来自机器人的移交活动(

handoff.initiate
),但我不知道一旦拦截后该怎么办。 

提前谢谢您。

-莫里斯

我尝试过查看无数的文档,但数量太多,而且都非常模糊。

dynamics-365 power-virtual-agents
1个回答
0
投票

您最终找到解决方案了吗?目前有完全相同的问题。

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