Bot Application が Azure Functions で作れるようになっていました。
Node.js か C# のいくつかのテンプレートから選択できます。
Node.js → Basic を選択して作った Functions は JavaScript なので、これを TypeScript に変えてみます。
Bot を作成したあと、ビルド → zip ファイルをダウンロード でソースコード一式がダウンロードできます。
そのディレクトリ構成は次の図に。
/messages
ディレクトリが Function のソースなので、ターミナルでここに移動し、
tsc init
を実行します。すると tsconfig.json
が作成されるので、それを次のように書き換えます。
messages/tsconfig.json
{
"compilerOptions": {
"target": "es2015",
"module": "commonjs",
"sourceMap": true,
"strict": false,
"esModuleInterop": true
}
}
コメント行や説明のコメントは省略しています。既定値から変えたのは次の通り。
"target": "es2015"
- Azure Functions の実行環境は node.js v8.4.0 以上を推奨 とのことで、node v8.2.0 は ES2016 までの API をすべてサポートしています"sourceMap": true
- ソースマップを有効にし、ローカルでの TypeScript デバッグを可能にします。"strict": false
- とりあえず厳密な型チェックはOFFで次に TypeScript で必要なモジュールをインストールします。
ターミナルで messages
ディレクトリに移動し、
npm install @types/node --save-dev
を実行します。実行後、 package.json
に @types/node
が追加されます。
messages/package.json
{
"name": "emptybot",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"botbuilder": "^3.13.1",
"botbuilder-azure": "^3.0.4"
},
"devDependencies": {
"@types/node": "^10.5.1", <-- ここが追加された
"restify": "^5.0.0"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
次に index.js
をリネームし index.ts
とし、内容を次のように書き換えます。
messages/index.ts
import { ChatConnector, MemoryBotStorage, UniversalBot, Session } from 'botbuilder';
import { BotServiceConnector, AzureTableClient, AzureBotStorage } from 'botbuilder-azure';
import * as path from 'path';
const useEmulator = (process.env.NODE_ENV == 'development');
const connector = useEmulator ? new ChatConnector() : new BotServiceConnector({
appId: process.env['MicrosoftAppId'],
appPassword: process.env['MicrosoftAppPassword'],
openIdMetadata: process.env['BotOpenIdMetadata']
});
/*----------------------------------------------------------------------------------------
* Bot Storage: This is a great spot to register the private state storage for your bot.
* We provide adapters for Azure Table, CosmosDb, SQL Azure, or you can implement your own!
* For samples and documentation, see: https://github.com/Microsoft/BotBuilder-Azure
* ---------------------------------------------------------------------------------------- */
const tableName = 'botdata';
const azureTableClient = new AzureTableClient(tableName, process.env['AzureWebJobsStorage']);
const storage = useEmulator ? new MemoryBotStorage() : new AzureBotStorage({ gzipData: false }, azureTableClient);
const bot = new UniversalBot(connector);
bot.localePath(path.join(__dirname, './locale'));
bot.set('storage', storage);
bot.dialog('/', function (session: Session) {
session.send('あなたは ' + session.message.text + 'と言いましたね。');
});
if (useEmulator) {
const restify = require('restify');
const server = restify.createServer();
server.listen(3978, function() {
console.log('test bot endpont at http://localhost:3978/api/messages');
});
server.post('/api/messages', connector.listen());
} else {
module.exports = connector.listen();
}
処理内容はほぼ変えず、文法を TypeScript にしただけです(MemoryBotStorage
を使うとこだけ処理を追加してます、これをしないとローカルで動かなかったので)。
messages
ディレクトリで
tsc
を実行します。すると同じディレクトリに index.js
と index.js.mmap
が生成されます。
この index.js
をこれまでの index.js
の代わりに Azure にアップロードすれば、関数はいままでどおり動作します。
launch.json
の定義が古いのでちょっと追記します。
messages/.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch",
"type": "node",
"request": "launch",
"protocol": "inspector", <-- この行を追加
"program": "${workspaceRoot}/index.js",
"cwd": "${workspaceRoot}",
"env": {
"NODE_ENV": "development"
}
}
]
}
index.ts
(.js じゃないよ) の適当な行にブレークポイントを仕掛けて、メニュー -> デバッグ -> デバッグの開始 をします。
ちゃんと止まるはずです。
BotFramework-Emulator にローカルのエンドポイントである http://localhost:3978/api/messages
を指定すれば、ボットのデバッグができます。