通过 Azure 部署 Javascript Microsoft Botframework 模板后,提供的 URL returns 出现错误

After deploying a Javascript Microsoft Botframework template via Azure the provided URL returns an error

按照 Microsoft 提供的从头到尾的所有步骤(此处的教程:https://docs.microsoft.com/en-us/azure/bot-service/javascript/bot-builder-javascript-quickstart?view=azure-bot-service-4.0)我已经通过 GIT 设置了持续部署,效果很好。

我已经能够 运行 我的本地主机和 Bot Framework Emulator 上的代码没有任何问题。我还能够使用 Azure 平台上提供的网络聊天频道 iframe 运行 机器人。 ( https:// webchat.botframework.com/embed/{your-bot}?s={secret})

最后,我还能够通过 Azure 使用 "test in web chat" 选项 运行 机器人。

但是,当我尝试使用 azure 提供的 URL 来测试我的机器人时,我得到以下信息:

https://{您的域}.azurewebsites.net/api/messages {"code":"MethodNotAllowed","message":"GET is not allowed"}

来自 https://{您的域}。azurewebsites.net

{"code":"ResourceNotFound","message":"/ does not exist"}

我在互联网上搜索以寻找解决方案,我找到的所有解决方案都使用旧版本的框架,并指向 index.js 中不存在的 server.get 方法.

如果我能提供更多信息,请告诉我。

这是来自 index.js

的代码
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// index.js is used to setup and configure your bot

// Import required packages
const path = require('path');
const restify = require('restify');

// Import required bot services. See https://aka.ms/bot-services to learn more about the different parts of a bot.
const { BotFrameworkAdapter, ConversationState, InputHints, MemoryStorage, UserState } = require('botbuilder');
const { FlightBookingRecognizer } = require('./dialogs/flightBookingRecognizer');

// This bot's main dialog.
const { DialogAndWelcomeBot } = require('./bots/dialogAndWelcomeBot');
const { MainDialog } = require('./dialogs/mainDialog');

// the bot's booking dialog
const { BookingDialog } = require('./dialogs/bookingDialog');
const BOOKING_DIALOG = 'bookingDialog';

// Note: Ensure you have a .env file and include LuisAppId, LuisAPIKey and LuisAPIHostName.
const ENV_FILE = path.join(__dirname, '.env');
require('dotenv').config({ path: ENV_FILE });

// Create adapter.
// See https://aka.ms/about-bot-adapter to learn more about adapters.
const adapter = new BotFrameworkAdapter({
    appId: process.env.MicrosoftAppId,
    appPassword: process.env.MicrosoftAppPassword
});

// Catch-all for errors.
adapter.onTurnError = async (context, error) => {
    // This check writes out errors to console log
    // NOTE: In production environment, you should consider logging this to Azure
    //       application insights.
    console.error(`\n [onTurnError]: ${ error }`);
    // Send a message to the user
    const onTurnErrorMessage = `Sorry, it looks like something went wrong!`;
    await context.sendActivity(onTurnErrorMessage, onTurnErrorMessage, InputHints.ExpectingInput);
    // Clear out state
    await conversationState.delete(context);
};

// Define a state store for your bot. See https://aka.ms/about-bot-state to learn more about using MemoryStorage.
// A bot requires a state store to persist the dialog and user state between messages.

// For local development, in-memory storage is used.
// CAUTION: The Memory Storage used here is for local bot debugging only. When the bot
// is restarted, anything stored in memory will be gone.
const memoryStorage = new MemoryStorage();
const conversationState = new ConversationState(memoryStorage);
const userState = new UserState(memoryStorage);

// If configured, pass in the FlightBookingRecognizer.  (Defining it externally allows it to be mocked for tests)
const { LuisAppId, LuisAPIKey, LuisAPIHostName } = process.env;
const luisConfig = { applicationId: LuisAppId, endpointKey: LuisAPIKey, endpoint: `https://${ LuisAPIHostName }` };

const luisRecognizer = new FlightBookingRecognizer(luisConfig);

// Create the main dialog.
const bookingDialog = new BookingDialog(BOOKING_DIALOG);
const dialog = new MainDialog(luisRecognizer, bookingDialog);
const bot = new DialogAndWelcomeBot(conversationState, userState, dialog);

// Create HTTP server
const server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function() {
    console.log(`\n${ server.name } listening to ${ server.url }`);
    console.log(`\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator`);
    console.log(`\nTo test your bot, see: https://aka.ms/debug-with-emulator`);
});

// Listen for incoming activities and route them to your bot main dialog.
server.post('/api/messages', (req, res) => {
    // Route received a request to adapter for processing
    adapter.processActivity(req, res, async (turnContext) => {
        // route to bot activity handler.
        await bot.run(turnContext);
    });
});

Bot Framework /api/messages 端点配置为接受 POST 请求。导航到 https://{your-domain}.azurewebsites.net/api/messages 是一个 GET 请求,这就是得到 "Resource not found" 响应的原因。 "Resource not found" 响应实际上告诉您您的机器人是 运行。如果 Web 应用不是 运行 或初始部署失败,您将看到 "The resource you are looking for has been removed, had its name changed, or is temporarily unavailable" 消息。只要网络聊天中的测试有效,您就可以开始了!

如果您想将静态 HTML 页面添加到您的服务器,我建议您对您的机器人进行一些更改。

直线令牌端点

首先,您应该向您的机器人添加另一个端点以生成直线令牌。这是一个基本的实现。有关详细信息,我建议您查看 Direct Line Authentication 文档。

// DirectLine Token
server.post('/directline/token', async (req, res) => {

    const id = (req.body && req.body.id)? `dl_${req.body.id}`: `dl_default_user`

    const options = {
        method: 'POST',
        headers: { 
            'Authorization': `Bearer ${process.env.directLineSecret}`,
            'Content-Type': 'application/json',
         },
        url: 'https://directline.botframework.com/v3/directline/tokens/generate', 
        data: {
            user: { id }
        }
    };

    try {
        const { data } = await axios(options);
        res.send(data);
    } catch ({ message }) {
        res.status(403);
        res.send({ message });
    }
});

提供静态文件 接下来,在您的根目录中创建一个 public 文件,并使用 Restify serveStatic 插件向您的机器人添加一个新端点。查看 Restify Plugin 文档了解更多详情。

server.get('/*', restify.plugins.serveStatic({
    directory: path.join(__dirname, 'public'),
    default: 'index.html'
}));

index.html 最后,在您的 public 目录中,创建一个 index.html 并添加以下代码。它被配置为从您的 /directline/token 端点请求令牌并呈现网络聊天实例。

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <title>Web Chat: Full-featured bundle</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
    <style>
      html, body { height: 100% }
      body { margin: 0 }

      #webchat {
        height: 100%;
        width: 100%;
      }
    </style>
  </head>
  <body>
    <div id="webchat" role="main"></div>
    <script>
      (async function () {

        const res = await fetch('/directline/token', { method: 'POST' });
        const { token } = await res.json();

        window.WebChat.renderWebChat({
          directLine: window.WebChat.createDirectLine({ token })
        }, document.getElementById('webchat'));

        document.querySelector('#webchat > *').focus();
      })().catch(err => console.error(err));
    </script>
  </body>
</html>

希望对您有所帮助!