You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BotFramework WebChat v4:JS向C# Bot回传位置信息报错求助

解决Web Chat v4回传位置信息到Bot Framework机器人的异常问题

我来帮你排查下这个问题!从你的代码来看,触发异常的核心原因大概率是store的作用域限制以及发送活动的参数不完整,咱们一步步来修正:

1. 修复store作用域问题

你定义的showPosition是全局函数,而store变量可能处于局部作用域(比如DOM加载完成的回调里),导致showPosition无法正确调用store.dispatch。解决方法是把showPosition放到store定义的同一作用域内,利用闭包直接访问dispatch:

const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
    // 把showPosition定义在store作用域内,直接访问dispatch
    function showPosition(position) {
        console.log(`Latitude: ${position.coords.latitude} Longitude: ${position.coords.longitude}`);
        const locationValue = `${position.coords.latitude};${position.coords.longitude}`;
        
        // 用dispatch发送消息,避免store作用域问题
        dispatch({
            type: 'WEB_CHAT/SEND_MESSAGE_BACK',
            payload: {
                text: locationValue,
                value: locationValue,
                // 关键:必须关联触发此操作的原始event活动ID
                activityId: action.payload.activity.id
            }
        });
    }

    if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
        const activityOut = action.payload.activity;
        if (activityOut.type === 'message') {
            return next(action);
        }
        if (activityOut.type === 'event') {
            if (activityOut.name === 'getLocation') {
                if (navigator.geolocation) {
                    navigator.geolocation.getCurrentPosition(showPosition);
                } else {
                    console.log("Geolocation is not supported by this browser.");
                }
            }
            return next(action);
        }
    } else if (action.type === 'DIRECT_LINE/POST_ACTIVITY') {
        return next(action);
    } else {
        return next(action);
    }
});

2. 更推荐的方式:直接发送Event活动回传

既然机器人是通过event类型活动触发位置获取,回传event类型活动会让业务逻辑更清晰,也更容易在C#端处理。你可以替换成DIRECT_LINE/POST_ACTIVITY来发送:

const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
    function showPosition(position) {
        const locationValue = `${position.coords.latitude};${position.coords.longitude}`;
        
        dispatch({
            type: 'DIRECT_LINE/POST_ACTIVITY',
            payload: {
                activity: {
                    type: 'event',
                    name: 'locationReceived', // 自定义事件名,和机器人端约定
                    value: locationValue,
                    from: { id: chatUser.id, name: chatUser.name },
                    locale: 'fr-FR'
                }
            }
        });
    }

    // 其余原有逻辑不变...
});

对应的C#机器人端处理代码:

protected override async Task OnEventActivityAsync(ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken)
{
    if (turnContext.Activity.Name.Equals("locationReceived", StringComparison.OrdinalIgnoreCase))
    {
        var locationData = turnContext.Activity.Value.ToString();
        // 这里处理位置信息,比如解析经纬度、存储等
        await turnContext.SendActivityAsync(MessageFactory.Text($"已收到你的位置信息:{locationData}"), cancellationToken);
    }
    await base.OnEventActivityAsync(turnContext, cancellationToken);
}

3. 备选方案:直接使用DirectLine实例发送

如果你觉得通过store处理太复杂,也可以直接保存DirectLine实例,在showPosition里调用postActivity:

// 提前保存DirectLine实例
const directLine = window.WebChat.createDirectLine({ secret: 'your-secret-token' });

// 定义showPosition时直接使用directLine
function showPosition(position) {
    const locationValue = `${position.coords.latitude};${position.coords.longitude}`;
    directLine.postActivity({
        type: 'message',
        text: locationValue,
        from: { id: chatUser.id, name: chatUser.name }
    }).subscribe(
        activityId => console.log(`位置消息已发送,ID:${activityId}`),
        error => console.error('发送位置失败:', error)
    );
}

// 渲染WebChat时传入directLine
window.WebChat.renderWebChat(
    {
        directLine,
        store,
        userID: chatUser.id,
        username: chatUser.name,
        locale: 'fr-FR',
        styleOptions
    },
    document.getElementById('BotChatGoesHere')
);

关键注意点

  • 确保chatUser.id和WebChat初始化时的userID一致,避免身份不匹配
  • 如果浏览器有位置权限限制,要先引导用户授权,否则getCurrentPosition会失败
  • 检查WebChat版本,确保使用的v4版本支持你调用的action类型(建议使用最新稳定版)

内容的提问来源于stack exchange,提问作者Shamrock

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 12:27:50