使用.NET Framework开发:Bot Framework聊天机器人集成Bing Maps API实现周边搜索
嘿,很高兴你已经搞定了基础的地点搜索集成!要实现“查找附近医生”这类周边搜索功能,咱们可以借助Bing Maps的Nearby Search API来完成,下面我一步步给你说怎么在Bot Framework里落地:
1. 先搞懂周边搜索的API端点
周边搜索不用你之前的Locations接口啦,改用这个专门的端点:https://dev.virtualearth.net/REST/v1/Locations/{point}/Nearby?keyword={keyword}&radius={radius}&key={BingKey}
这里几个关键参数得注意:
{point}:用户当前的地理位置,格式是纬度,经度,比如39.9042,116.4074(北京天安门的坐标){keyword}:要搜索的类别,比如英文的Doctors、中文的医生都可以(建议测试下中文关键词的匹配效果){radius}:搜索半径,单位是米,比如5000就是5公里范围,你也可以让用户自己选择{BingKey}:就是你已经拿到的Bing Maps密钥
2. 在Bot里获取用户的位置
要做周边搜索,第一步得拿到用户在哪。在Bot Framework里有两种方式:
- 主动请求位置:如果用户没主动提供,就发个位置卡片让用户共享
- 自动提取位置:像Teams、微信这些渠道,用户发送位置后,你可以直接从活动实体里提取出来
给你个.NET Framework里提取位置的代码示例:
// 从Activity里查找位置实体 var locationEntity = activity.Entities?.FirstOrDefault(e => e.Type == "Place"); if (locationEntity != null) { if (locationEntity.Properties.TryGetValue("geo", out var geoObj) && geoObj is JObject geo) { double latitude = geo.Value<double>("latitude"); double longitude = geo.Value<double>("longitude"); // 成功拿到经纬度,接下来就可以调用API了 } }
如果用户还没给位置,发个请求卡片就行:
var reply = activity.CreateReply("麻烦共享下你的位置,我帮你找附近的医生~"); var locationCard = new Attachment { ContentType = "application/vnd.microsoft.card.location", Content = new { Title = "点击共享位置", Geo = new { Latitude = 0, Longitude = 0 }, Address = new { Country = "" } } }; reply.Attachments.Add(locationCard); await context.PostAsync(reply);
3. 调用API并把结果返回给用户
拿到经纬度后,就可以用HttpClient发请求啦,解析完结果再整理成用户能看懂的消息:
using (var client = new HttpClient()) { string point = $"{latitude},{longitude}"; string keyword = "医生"; // 可以根据用户输入动态修改,比如用户说"牙医"就换成"牙医" int radius = 5000; // 默认5公里,也可以让用户自行选择 string apiUrl = $"https://dev.virtualearth.net/REST/v1/Locations/{point}/Nearby?keyword={Uri.EscapeDataString(keyword)}&radius={radius}&key={yourBingMapsKey}"; var response = await client.GetAsync(apiUrl); if (response.IsSuccessStatusCode) { var result = await response.Content.ReadAsStringAsync(); var jsonObj = JObject.Parse(result); // 从返回的JSON里提取有用的地点信息 var nearbyPlaces = jsonObj["resourceSets"][0]["resources"] .Select(res => new { Name = res["name"].ToString(), FullAddress = res["address"]["formattedAddress"].ToString(), Lat = res["point"]["coordinates"][0].Value<double>(), Lng = res["point"]["coordinates"][1].Value<double>() }).ToList(); // 整理成友好的消息返回给用户 if (nearbyPlaces.Any()) { var replyContent = new StringBuilder("找到这些附近的医生:\n"); // 只返回前5个结果,避免消息太长 foreach (var place in nearbyPlaces.Take(5)) { replyContent.AppendLine($"- *{place.Name}*:{place.FullAddress}"); } await context.PostAsync(replyContent.ToString()); } else { await context.PostAsync("抱歉,附近没找到相关的医生哦😅"); } } else { await context.PostAsync("哎呀,暂时没法获取位置信息,你稍后再试试呗~"); } }
4. 几个优化体验的小建议
- 自然语言适配:把用户的口语化请求(比如“找离我近的牙科诊所”)映射成API能识别的关键词,简单点用字典匹配,复杂点可以加个LUIS做意图识别
- 可视化结果:除了文字列表,还可以发个带地图的卡片,把找到的地点标在上面,用户看着更直观
- 可选半径:给用户几个半径选项(比如3公里/5公里/10公里),让用户自己选择搜索范围
内容的提问来源于stack exchange,提问作者Sandy
相关产品推荐
相关产品推荐

