【问题标题】:Bot Framework v4 Node.js LocationBot Framework v4 Node.js 位置
【发布时间】:2021-05-22 07:53:55
【问题描述】:

我正在设计一个聊天机器人,并试图找到一些 Node.js 示例代码和/或有关如何将 Azure Maps 服务作为 Bot Framework V4 的一部分实施的文档。在 V3 中如何实现这一点的示例有很多,但似乎没有针对 Node.js 的 V4 解决方案的示例。我希望在我的 botbuilder-dialog 流程中创建一个步骤,该步骤将启动一个简单的“我们也在哪里运送它”位置对话框,该对话框将引导用户完成对话框并将地址结果存储为该用户配置文件的一部分。对此的任何帮助或建议将不胜感激。

【问题讨论】:

  • 您的首选频道是什么? Facebook、WebChat、Teams 等
  • 除了@Mick 的问题,你要显示地图吗?您提到收集用户的地址结果,这些结果通常来自用户键入的输入,而不是地图。你能详细说明一下流程吗?只是澄清一下。
  • 感谢您的回复。地图需求本身可以比作兴趣点或商店定位器。这实际上只是一般地图功能的演示,可以应用于多个用例。
  • 我想复制的流程在这里,除了这似乎与 sdk v4 github.com/microsoft/BotBuilder-Location 中的对话流程不太兼容。
  • 接受/赞成一个答案服务于更大的 Stack Overflow 社区和任何有类似问题的人。如果您觉得我的回答足够,请“接受”并点赞。如果没有,请告诉我我还能提供哪些帮助!

标签: node.js botframework azure-maps


【解决方案1】:

是的,这是可行的。我创建了一个类(可能有点矫枉过正,但很好),我在其中使用我提供的参数调用 API 来获取地图。我决定使用Azure Maps(与Bing Maps)只是因为我很好奇它的不同之处。您也没有任何理由不能使用 Bing 地图做到这一点。

在机器人中,我使用component dialog,因为我是如何设计机器人的其余部分的。当对话框结束时,它会从堆栈中掉下来并返回到父对话框。

在我的场景中,机器人为用户提供了几个选择。 “向我发送地图”生成地图并将其在活动中发送给客户端/用户。其他任何事情都会让用户继续结束对话。

您需要决定如何获取用户的位置。我在开发这个时考虑到了Web Chat,所以我从浏览器获取地理位置并将其返回给机器人,以便在调用getMap() 时使用。

const { ActivityTypes, InputHints } = require('botbuilder');
const fetch = require('node-fetch');

class MapHelper {
  async getMap(context, latitude, longitude) {
    var requestOptions = {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json'
      },
      redirect: 'follow'
    };

    const result = await fetch(`https://atlas.microsoft.com/map/static/png?subscription-key=${ process.env.AZURE_MAPS_KEY }&api-version=1.0&layer=basic&zoom=13&center=${ longitude },${ latitude }&language=en-US&pins=default|al.67|la12 3|lc000000||'You!'${ longitude } ${ latitude }&format=png`, requestOptions)
      .then(response => response.arrayBuffer())
      .then(async result => {
        const bufferedData = Buffer.from(result, 'binary');
        const base64 = bufferedData.toString('base64');
        const reply = { type: ActivityTypes.Message };
        const attachment = {
          contentType: 'image/png',
          contentUrl: `data:image/png;base64,${ base64 }`
        };

        reply.attachments = [attachment];
        await context.sendActivity(reply, null, InputHints.IgnoringInput);
      })
      .catch(error => {
        if (error) throw new Error(error);
      });

    return result;
  };
};

module.exports.MapHelper = MapHelper;
const { ChoicePrompt, ChoiceFactory, ComponentDialog, ListStyle, WaterfallDialog } = require('botbuilder-dialogs');
const { MapHelper } = require('./mapHelper');

const CONFIRM_LOCALE_DIALOG = 'confirmLocaleDialog';
const CHOICE_PROMPT = 'confirmPrompt';

class ConfirmLocaleDialog extends ComponentDialog {
  constructor() {
    super(CONFIRM_LOCALE_DIALOG);

    this.addDialog(new ChoicePrompt(CHOICE_PROMPT))
      .addDialog(new WaterfallDialog(CONFIRM_LOCALE_DIALOG, [
        this.askLocationStep.bind(this),
        this.getMapStep.bind(this)
    ]));

    this.initialDialogId = CONFIRM_LOCALE_DIALOG;
  }

  async askLocationStep(stepContext) {
    const choices = ['Send me a map', "I'll have none of this nonsense!"];
    return await stepContext.prompt(CHOICE_PROMPT, {
      prompt: 'Good sir, may I pinpoint you on a map?',
      choices: ChoiceFactory.toChoices(choices),
      style: ListStyle.suggestedAction
    });
  }

  async getMapStep(stepContext) {
    const { context, context: { activity } } = stepContext;
    const text = activity.text.toLowerCase();
    if (text === 'send me a map') {
      const { latitude, longitude } = activity.channelData;
      const mapHelper = new MapHelper();
      await mapHelper.getMap(context, latitude, longitude);

      const message = 'Thanks for sharing!';
      await stepContext.context.sendActivity(message);
      return await stepContext.endDialog();
    } else {
      await stepContext.context.sendActivity('No map for you!');
      return await stepContext.endDialog();
    }
  }
}

module.exports.ConfirmLocaleDialog = ConfirmLocaleDialog;
module.exports.CONFIRM_LOCALE_DIALOG = CONFIRM_LOCALE_DIALOG;

希望有帮助!

---- 编辑----

根据请求,可以使用以下方法从浏览器获取位置数据。当然,这取决于用户授予对位置数据的访问权限。

navigator.geolocation.getCurrentPosition( async (position) => {
  const { latitude, longitude } = position.coords;
  // Do something with the data;
  console.log(latitude, longitude)
})

【讨论】:

  • 你好。您能分享一下您是如何从浏览器中获取纬度和经度的吗?谢谢你!
  • 欣赏它。非常感谢你
猜你喜欢
  • 1970-01-01
  • 2021-01-27
  • 1970-01-01
  • 2019-07-27
  • 2019-05-26
  • 1970-01-01
  • 1970-01-01
  • 2019-06-04
  • 1970-01-01
相关资源
最近更新 更多