我找不到有关此主题的任何信息,而且我不想使用Azure。
是的,你可以像这里所解释的那样在IIS或任何其他主机服务(包括Azure以外的云托管)上运行你的机器人。你需要确保你的机器人具有可访问互联网的终端点和有效的HTTPS证书。
关于HTTPS证书的要求,我把此线程的信息复制在下面供你参考:
Bot Framework要求你终端点公开的x.509v3证书是当前和有效的。 "当前和有效"的大多数检查都是服务器证书的标准检查:CN必须匹配主机名,它不能过期,不能列入CRL,必须具有正确的EKU集等等。
最重要的是,你的证书必须链接到Microsoft信任的根证书颁发机构。这些CA的最新列表在这里提供。
另外,你甚至可以在不部署到Azure或任何其他主机服务的情况下注册你的机器人并启用通道。你可以临时使用ngrok创建到本地主机环境的安全隧道,在将其公开给其他用户之前在电子邮件通道中测试机器人。顺便说一句,你不需要在BotFramework门户发布你的机器人,只需注册即可。发布仅适用于那些想要出现在机器人目录中的机器人。
您需要在Azure上拥有一个账户,但是不需要直接在Azure上托管您的机器人。当您登录到Azure仪表板时,有三个选项可供选择:Web App Bot、Functions Bot和Bot Channels Registration。选择Bot Channels Registration并在设置中输入您的机器人的https URL(部署位置)。
或者如果您想要直接从Messenger(而不是模拟器)调试您的机器人,可以下载ngrok,然后在命令行中输入:
ngrok.exe http <your port> -host-header="localhost:<your port>
然后在Bot Channels Registration设置中输入ngrok代理URL(不带端口)。 几个小时后,临时地址将转发到您的本地主机。
是的,开发机器人完全可以不使用Azure Cloud门户。
在Microsoft提供的机器人仿真器上进行测试
但是,要在渠道或Web应用程序上发布机器人,您必须在Azure机器人服务中注册机器人。 在这里查看更多信息:https://thewebspark.com/2018/04/15/is-microsoft-bot-framework-without-azure-possible/
它是完全可能的。
我以两种方式运行它。 第一种 - 在 Docker 容器中使用 restify 服务 - 本地运行并使用 ngrok 和 AWS。
// Create HTTP server.
const server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, () => {
console.log(`\n${server.name} listening to ${server.url}`);
});
async function main(req: WebRequest, context: TurnContext) {
logger.json("Request ->", req.body);
try {
for (const bot of allBots) {
await bot.run(context);
}
} catch (error) {
logger.error("Error processing request[server.ts]");
logger.error(error);
}
}
// Listen for incoming requests.
server.post("/api/messages", (req: WebRequest, res: WebResponse) => {
adapter.processActivity(req, res, async (context: TurnContext) => {
await main(req, context);
});
});
第二步 - 使用Serverless框架在AWS Lambda上运行。这是适配器。
export function lambda(bots: ActivityHandler[]) {
const handler: Handler = async (event: any, _: Context, callback: Callback) => {
logger.json("Event to bot framework: ", event);
const reqWrapper: WebRequest = {
body: event.body,
headers: event.headers,
method: event.method,
query: event.query,
on: (_1: string, ..._2: any[]): any => {
// it needs to be empty
},
};
let statusCode: number;
const resWrapper: WebResponse = {
status: (code: number) => {
statusCode = code;
},
send: (body) => {
callback(null, {statusCode, body});
},
end: () => {
callback(null, { statusCode });
},
};
const adapter = await getAdapter();
adapter.processActivity(reqWrapper, resWrapper, async (context: TurnContext) => {
await main(context, bots);
});
};
return handler;
}