Javascript v3 ボットをスキルに変換するConvert a JavaScript v3 bot to a skill

適用対象: SDK v4APPLIES TO: SDK v4

この記事では、2 つのサンプル JavaScript v3 ボットをスキルに変換し、これらのスキルにアクセスできる v4 スキル コンシューマーを作成する方法について説明します。This article describes how to convert 2 sample JavaScript v3 bots to skills and to create a v4 skill consumer that can access these skills. .NET v3 ボットをスキルに変換するには、「.NET v3 ボットをスキルに変換する」を参照してください。To convert a .NET v3 bot to a skill, see how to Convert a .NET v3 bot to a skill. JavaScript ボットを v3 から v4 に移行するには、「JavaScript v3 ボットを v4 ボットに移行する」を参照してください。To migrate a JavaScript bot from v3 to v4, see how to Migrate a Javascript v3 bot to a v4 bot.

前提条件Prerequisites

  • Visual Studio Code。Visual Studio Code.
  • Node.js.Node.js.
  • Azure サブスクリプション。An Azure subscription. Azure サブスクリプションをお持ちでない場合は、開始する前に 無料アカウント を作成してください。If you don't have an Azure subscription, create a free account before you begin.
  • スキルをテストするには、Bot Framework エミュレーターとボットのローカルコピーが必要です。To test the skills, you will need the Bot Framework Emulator and local copies of the bots:

ボットについてAbout the bots

この記事では、v3 ボットをそれぞれスキルとして機能するように作成します。In this article, each v3 bot is created to act as a skill. 変換されたボットをスキルとしてテストできるように、v4 のスキル コンシューマーが含まれています。A v4 skill consumer is included, so that you can test the converted bots as skills.

  • v3-skill-bot は、受信したメッセージをエコー バックします。The v3-skill-bot echoes back messages it receives. これは、スキルとして、"end" (終了) または "stop" (停止) メッセージを受信したときに "完了" します。As a skill, it completes when it receives an "end" or "stop" message. 変換するボットは、最小 v3 ボットに基づいています。The bot to convert is based on a minimal v3 bot.
  • v3-booking-bot-skill を使用すると、ユーザーはフライトやホテルを予約できます。The v3-booking-bot-skill allows the user to book a flight or a hotel. これは、スキルとして、収集された情報を、完了時に親に送り返します。As a skill, it sends collected information back to the parent when finished.

また、v4 スキル コンシューマー (v4-root-bot) では、スキルを利用する方法を示し、それらをテストすることができます。Also, a v4 skill consumer, the v4-root-bot, demonstrates how to consume the skills and allows you to test them.

スキル コンシューマーを使用してスキルをテストするには、3 つのボットをすべて同時に実行する必要があります。To use the skill consumer to test the skills, all 3 bots need to be running at the same time. ボットは、Bot Framework Emulator を使用し、ボットごとに異なるローカル ポートを使ってローカルでテストできます。The bots can be tested locally using the Bot Framework Emulator, with each bot using a different local port.

ボット用の Azure リソースを作成するCreate Azure resources for the bots

ボット間認証を行うには、参加するボットのそれぞれに有効なアプリ ID とパスワードが必要です。Bot-to-bot authentication requires that each participating bot has a valid app ID and password.

  1. 必要に応じて、これらのボットのボットチャンネル登録を作成します。Create a Bot Channels Registration for the bots as needed.
  2. それぞれのアプリ ID とパスワードを記録します。Record the app ID and password for each one.

V3 bot を変換するにはTo convert a v3 bot

既存のボットをスキル ボットに変換するには、以降のセクションで説明するように、いくつかの手順を実行するだけです。To convert an existing bot to a skill bot takes just a few steps, as outlined in the next couple sections. 詳細については、「スキルについて」を参照してください。For more in-depth information, see about skills.

  • ボットの .env ファイルを更新して、ボットのアプリ ID とパスワードを設定し、"ルート ボットのアプリ ID" プロパティを追加します。Update the bot's .env file to set the bot's app ID and password and to add a root bot app ID property.
  • 要求検証を追加します。Add claims validation. これにより、ユーザーまたはルート ボットだけがスキルにアクセスできるように、スキルへのアクセスが制限されます。This will restrict access to the skill so that only users or your root bot can access the skill. 既定およびカスタムの要求検証の詳細については、「関連情報」セクションを参照してください。See the additional information section for more information about default and custom claims validation.
  • ルート ボットからの endOfConversation アクティビティを処理するようにボットのメッセージ コントローラーを変更します。Modify the bot's messages controller to handle endOfConversation activities from the root bot.
  • スキルが完了したときに endOfConversation アクティビティを返すようにボットのコードを変更します。Modify the bot code to return an endOfConversation activity when the skill completes.
  • スキルは、完了したときに会話状態がある場合やリソースを保持している場合は必ず、会話状態をクリアし、リソースを解放する必要があります。Whenever the skill completes, if it has conversation state or maintains resources, it should clear its conversation state and release resources.
  • 必要に応じて、マニフェスト ファイルを追加します。Optionally add a manifest file. スキル コンシューマーは必ずしもスキル コードにアクセスできるわけではないため、スキル マニフェストを使用して、スキルが受信および生成できるアクティビティ、スキルの入力パラメーターと出力パラメーター、およびスキルのエンドポイントを記述します。Since a skill consumer does not necessarily have access to the skill code, use a skill manifest to describe the activities the skill can receive and generate, its input and output parameters, and the skill's endpoints. 現在のマニフェスト スキーマは skill-manifest-2.0.0.json です。The current manifest schema is skill-manifest-2.0.0.json.

エコー ボットを変換するConvert the echo bot

基本のスキルに変換された v3 エコー ボットの例については、Skills/v3-skill-bot に関するページを参照してください。See Skills/v3-skill-bot for an example of a v3 echo bot that has been converted to a basic skill.

  1. 単純な JavaScript v3 ボット プロジェクトを作成し、必要なモジュールをインポートします。Create a simple JavaScript v3 bot project and import required modules.

    v3-skill-bot/app.jsv3-skill-bot/app.js

    const restify = require('restify');
    const builder = require('botbuilder');
    require('dotenv').config();
    
  2. ポート 3979 でローカルに実行されるようにボットを設定します。Set the bot to run locally on port 3979.

    v3-skill-bot/app.jsv3-skill-bot/app.js

    // Setup Restify Server
    const server = restify.createServer();
    server.listen(process.env.port || process.env.PORT || 3979, function () {
       console.log('%s listening to %s', server.name, server.url); 
    });
    
  3. 構成ファイルに、エコー ボットのアプリ ID とパスワードを追加します。In the configuration file, add the echo bot's app ID and password. さらに、単純なルート ボットのアプリ ID を値として持つ ROOT_BOT_APP_ID プロパティを追加します。Also, add a ROOT_BOT_APP_ID property with the simple root bot's app ID as its value.

    v3-skill-bot/.envv3-skill-bot/.env

    # Bot Framework Credentials
    
    MICROSOFT_APP_ID=
    MICROSOFT_APP_PASSWORD=
    ROOT_BOT_APP_ID=
    
  4. ボット用のチャット コネクタを作成します。Create the chat connector for the bot. これは、既定の認証構成を使用します。This one uses the default authentication configuration. enableSkillstrue に設定して、ボットをスキルとして使用できるようにします。Set enableSkills to true to allow the bot to be used as a skill. allowedCallers は、このスキルを使用することが許可されているボットのアプリ ID の配列です。allowedCallers is an array of the app IDs of the bots allowed to use this skill. この配列の最初の値が ' * ' の場合、bot はこのスキルを使用できます。If the first value of this array is '*', then any bot can use this skill.

    v3-skill-bot/app.jsv3-skill-bot/app.js

    // Create chat connector for communicating with the Bot Framework Service
    const connector = new builder.ChatConnector({
        appId: process.env.MICROSOFT_APP_ID,
        appPassword: process.env.MICROSOFT_APP_PASSWORD,
        enableSkills: true,
        allowedCallers: [process.env.ROOT_BOT_APP_ID]
    });
    
  5. ユーザーがスキルを終了することを選択したときに endOfConversation アクティビティを送信するようにメッセージ ハンドラーを更新します。Update the message handler to send an endOfConversation activity when the user chooses to end the skill.

    v3-skill-bot/app.jsv3-skill-bot/app.js

    // Create your bot with a function to receive messages from the user
    const bot = new builder.UniversalBot(connector, function (session) {
        switch (session.message.text.toLowerCase()) {
            case 'end':
            case 'stop':
                session.endConversation();
                break;
            default:
                session.send("Echo (JS V3) You said: %s", session.message.text);
                session.send('Say "end" or "stop" and I\'ll end the conversation and back to the parent.');
        }
    }).set('storage', inMemoryStorage); // Register in memory storage
    
  6. このボットは会話状態を維持せず、会話のためのリソースを作成しないため、ボットは、スキル コンシューマーから受け取る endOfConversation アクティビティを処理する必要はありません。Since this bot does not maintain conversation state and does not create any resources for the conversation, the bot does not need to handle any endOfConversation activities that it receives from the skill consumer.

  7. このマニフェストをエコー ボットに使用します。Use this manifest for the echo bot. エンドポイントのアプリ ID をボットのアプリ ID に設定します。Set the endpoint app ID to the bot's app ID.

    v3-skill-bot/manifest/v3-skill-bot-manifest.jsonv3-skill-bot/manifest/v3-skill-bot-manifest.json

    {
        "$schema": "https://schemas.botframework.com/schemas/skills/skill-manifest-2.0.0.json",
        "$id": "v3-skill-bot",
        "name": "Echo Skill bot",
        "version": "1.0",
        "description": "This is a sample echo skill",
        "publisherName": "Microsoft",
        "privacyUrl": "https://echoskillbot.contoso.com/privacy.html",
        "copyright": "Copyright (c) Microsoft Corporation. All rights reserved.",
        "license": "",
        "iconUrl": "https://echoskillbot.contoso.com/icon.png",
        "tags": [
          "sample",
          "echo"
        ],
        "endpoints": [
          {
            "name": "default",
            "protocol": "BotFrameworkV3",
            "description": "Default endpoint for the skill",
            "endpointUrl": "http://echoskillbot.contoso.com/api/messages",
            "msAppId": "00000000-0000-0000-0000-000000000000"
          }
        ]
      }
    

    スキル マニフェスト スキーマについては、skill-manifest-2.0.0.json を参照してください。For the skill-manifest schema, see skill-manifest-2.0.0.json.

予約ボットを変換するConvert the booking bot

基本のスキルに変換された v3 予約ボットの例については、Skills/v3-booking-bot-skill に関するページを参照してください。See Skills/v3-booking-bot-skill for an example of a v3 booking bot that has been converted to a basic skill. 変換前のボットは、v3 core-MultiDialogs サンプルに似ていました。Before conversion, the bot was similar to the v3 core-MultiDialogs sample.

  1. 必要なモジュールをインポートします。Import required modules.

    v3-booking-bot-skill/app.jsv3-booking-bot-skill/app.js

    require('dotenv').config();
    
    var builder = require('botbuilder');
    var restify = require('restify');
    const skills = require('botbuilder/skills-validator');
    const { allowedCallersClaimsValidator } = require('./allowedCallersClaimsValidator');
    
  2. ポート 3980 でローカルに実行するようにボットを設定します。Set the bot to run locally on port 3980.

    v3-booking-bot-skill/app.jsv3-booking-bot-skill/app.js

    // Setup Restify Server
    var server = restify.createServer();
    server.listen(process.env.port || process.env.PORT || 3980, function () {
        console.log('%s listening to %s', server.name, server.url);
    });
    
  3. 構成ファイルに、予約ボットのアプリ ID とパスワードを追加します。In the configuration file, add the booking bot's app ID and password. さらに、単純なルート ボットのアプリ ID を値として持つ ROOT_BOT_APP_ID プロパティを追加します。Also, add a ROOT_BOT_APP_ID property with the simple root bot's app ID as its value.

    v3-booking-bot-skill/.envv3-booking-bot-skill/.env

    # Bot Framework Credentials
    
    MICROSOFT_APP_ID=
    MICROSOFT_APP_PASSWORD=
    ROOT_BOT_APP_ID=
    
  4. ボット用のチャット コネクタを作成します。Create the chat connector for the bot. これは、カスタム認証構成を使用します。This one uses a custom authentication configuration. enableSkillstrue に設定して、ボットをスキルとして使用できるようにします。Set enableSkills to true to allow the bot to be used as a skill. authConfiguration には、認証と要求検証に使用するカスタム認証構成オブジェクトが含まれています。authConfiguration contains the custom authentication configuration object to use for authentication and claims validation.

    v3-booking-bot-skill/app.jsv3-booking-bot-skill/app.js

    // Create chat bot and listen to messages
    var connector = new builder.ChatConnector({
        appId: process.env.MICROSOFT_APP_ID,
        appPassword: process.env.MICROSOFT_APP_PASSWORD,
        enableSkills: true,
        authConfiguration: new skills.AuthenticationConfiguration([], allowedCallersClaimsValidator)
    });
    

    v3-booking-bot-skill/allowedCallersClaimsValidator.jsv3-booking-bot-skill/allowedCallersClaimsValidator.js

    これは、カスタム要求検証を実装し、検証が失敗するとエラーをスローします。This implements custom claims validation and throws an error if validation fails.

    const skills = require('botbuilder/skills-validator');
    const path = require('path');
    
    // Import required bot configuration.
    const ENV_FILE = path.join(__dirname, '.env');
    require('dotenv').config({ path: ENV_FILE });
    
    // Load the AppIds for the configured callers (we will only allow responses from skills we have configured).
    // process.env.AllowedCallers is the list of parent bot Ids that are allowed to access the skill
    // to add a new parent bot simply go to the .env file and add
    // the parent bot's Microsoft AppId to the list under AllowedCallers, e.g.:
    //  AllowedCallers=195bd793-4319-4a84-a800-386770c058b2,38c74e7a-3d01-4295-8e66-43dd358920f8
    const allowedCallers = [process.env.ROOT_BOT_APP_ID]; // process.env.AllowedCallers ? process.env.AllowedCallers.split(',') : undefined;
    
    /**
     * Sample claims validator that loads an allowed list from configuration if present
     * and checks that requests are coming from allowed parent bots.
     * @param claims An array of Claims decoded from the HTTP request's auth header
     */
    const allowedCallersClaimsValidator = async (claims) => {
        if (!allowedCallers || allowedCallers.length == 0) {
            throw new Error(`DefaultAuthenticationConfiguration allowedCallers must contain at least one element of '*' or valid MicrosoftAppId(s).`);
        }
        if (!claims || claims.length < 1) {
            throw new Error(`DefaultAuthenticationConfiguration.validateClaims.claims parameter must contain at least one element.`);
        }
        // If allowedCallers is undefined we allow all calls
        // If allowedCallers contains '*' we allow all callers
        if (skills.SkillValidation.isSkillClaim(claims)) {
                    
            if(allowedCallers[0] === '*') {
                return;
            }
            // Check that the appId claim in the skill request is in the list of skills configured for this bot.
            const appId = skills.JwtTokenValidation.getAppIdFromClaims(claims);
            if (allowedCallers.includes(appId)) {
                return;
            }
            throw new Error(`Received a request from a bot with an app ID of "${ appId }". To enable requests from this caller, add the app ID to your configuration file.`);
        }
        throw new Error(`DefaultAuthenticationConfiguration.validateClaims called without a Skill claim in claims.`);
    };
    
    module.exports.allowedCallersClaimsValidator = allowedCallersClaimsValidator;
    
  5. スキルが終了したときに endOfConversation アクティビティを送信するようにメッセージ ハンドラーを更新します。Update the message handler to send an endOfConversation activity when the skill ends. session.endConversation()endOfConversation アクティビティを送信することに加え、会話状態をクリアすることに注意してください。Note that session.endConversation() clears conversation state in addition to sending an endOfConversation activity.

    v3-booking-bot-skill/app.jsv3-booking-bot-skill/app.js

    endOfConversation アクティビティの codevalue プロパティを設定し、会話状態をクリアするヘルパー関数を実装します。Implement a helper function to set the endOfConversation activity's code and value properties and clear conversation state. ボットが会話の他のリソースを管理していた場合は、それらもここで解放します。If the bot managed any other resources for the conversation, you would release them here, too.

    // Code enum can be found here: https://aka.ms/codeEnum
    function endConversation(session, value = null, code = null) {
        session.send('Ending conversation from the skill...');
        // Send endOfConversation with custom code and values
        const msg = {
            value,
            code,
            type: 'endOfConversation'
        };
        session.send(msg);
        // Call endConversation() to clear state
        session.endConversation();
    }
    

    ユーザーがプロセスを完了したら、ヘルパー メソッドを使用してスキルを終了し、ユーザーが収集したデータを返します。When the user completes the process, use the helper method to end the skill and return the user's collected data.

    var bot = new builder.UniversalBot(connector, [
        function (session) {
    
        },
        // Dialog has ended
        function(session, result) {
            endConversation(session, result, 'completedSuccessfully');
        }
    ]).set('storage', inMemoryStorage); // Register in memory storage
    

    ユーザーが代わりにプロセスを早期に終了した場合でも、ヘルパー メソッドは呼び出されます。If instead the user ends the process early, the helper method is still invoked.

    bot.recognizer({
        recognize: function (context, done) {
            var intent = { score: 0.0 };
            if (context.message.text) {
                switch (context.message.text.toLowerCase()) {
                    case 'help':
                        intent = { score: 1.0, intent: 'Help' };
                        break;
                    case 'end':
                        intent = { score: 1.0, intent: 'End' };
                        break;
                }
            }
            done(null, intent);
        }
    });
    
    // Add global endConversation() action bound to the 'Goodbye' intent
    bot.endConversationAction('endAction', "Ok... See you later.", { matches: 'End' });
    
  6. スキルがスキル コンシューマーによって取り消された場合、コンシューマーは endOfConversation アクティビティを送信します。If the skill is cancelled by the skill consumer, the consumer sends an endOfConversation activity. このアクティビティを処理し、会話に関連付けられているすべてのリソースを解放します。Handle this activity and release any resources associated with the conversation.

    v3-booking-bot-skill/app.jsv3-booking-bot-skill/app.js

    // Listen for endOfConversation activities from other sources
    bot.on('endOfConversation', (message) => {
        bot.loadSession(message.address, (err, session) => {
            endConversation(session, null, 'completedSuccessfully');
        });
    })
    
  7. このマニフェストを予約ボットに使用します。Use this manifest for the booking bot. エンドポイントのアプリ ID をボットのアプリ ID に設定します。Set the endpoint app ID to the bot's app ID.

    v3-booking-bot-skill/manifest/v3-booking-bot-skill-manifest.jsonv3-booking-bot-skill/manifest/v3-booking-bot-skill-manifest.json

    {
        "$schema": "https://schemas.botframework.com/schemas/skills/skill-manifest-2.0.0.json",
        "$id": "v3-booking-bot-skill",
        "name": "Booking Skill bot",
        "version": "1.0",
        "description": "This is a sample booking skill",
        "publisherName": "Microsoft",
        "privacyUrl": "https://bookingskillbot.contoso.com/privacy.html",
        "copyright": "Copyright (c) Microsoft Corporation. All rights reserved.",
        "license": "",
        "iconUrl": "https://bookingskillbot.contoso.com/icon.png",
        "tags": [
          "sample",
          "echo"
        ],
        "endpoints": [
          {
            "name": "default",
            "protocol": "BotFrameworkV3",
            "description": "Default endpoint for the skill",
            "endpointUrl": "http://bookingskillbot.contoso.com/api/messages",
            "msAppId": "00000000-0000-0000-0000-000000000000"
          }
        ]
      }
    

    スキル マニフェスト スキーマについては、skill-manifest-2.0.0.json を参照してください。For the skill-manifest schema, see skill-manifest-2.0.0.json.

v4 ルート ボットを作成するCreate the v4 root bot

単純なルート ボットでは 2 つのスキルが使用されます。ユーザーはこれを使用して、変換手順が計画どおりに機能したことを確認できます。The simple root bot consumes the 2 skills and lets you verify that the conversion steps worked as planned. このボットは、ポート 3978 でローカルに実行されます。This bot will run locally on port 3978.

  1. 構成ファイルに、ルート ボットのアプリ ID とパスワードを追加します。To the configuration file, add the root bot's app ID and password. v3 のスキルごとに、スキルのアプリ ID を追加します。For each of the v3 skills, add the skill's app ID.

    v4-root-bot/.envv4-root-bot/.env

    MicrosoftAppId=
    MicrosoftAppPassword=
    SkillHostEndpoint=http://localhost:3978/api/skills
    
    SkillSimpleId=v3-skill-bot
    SkillSimpleAppId=
    SkillSimpleEndpoint=http://localhost:3979/api/messages
    
    SkillBookingId=v3-booking-bot-skill
    SkillBookingAppId=
    SkillBookingEndpoint=http://localhost:3980/api/messages
    

ルート ボットのテストTest the root bot

最新の Bot Framework Emulator をダウンロードしてインストールします。Download and install the latest Bot Framework Emulator.

  1. 3 つのすべてのボットをマシン上でローカルに起動します。Start all three bots locally on your machine.
  2. エミュレーターを使用してルート ボットを接続します。Use the Emulator to connect to the root bot.
  3. スキルとスキル コンシューマーをテストします。Test the skills and skill consumer.

バージョン4.11 以降では、アプリ ID とパスワードを使用して、エミュレーターでスキルとスキルのコンシューマーをローカルにテストする必要はありません。Starting with version 4.11, you don't need an app ID and password to test a skill and skill consumer locally in the Emulator. Azure にスキルをデプロイするには、Azure サブスクリプションが必要です。An Azure subscription is still required to deploy your skill to Azure.

関連情報Additional information

ボット間認証Bot-to-bot authentication

ルートとスキルは HTTP を介して通信します。The root and skill communicate over HTTP. このフレームワークでは、ベアラー トークンとボット アプリケーション ID を使用して各ボットの ID が検証されます。The framework uses bearer tokens and bot application IDs to verify the identity of each bot. これは、認証構成オブジェクトを使用して、受信した要求の認証ヘッダーを検証します。It uses an authentication configuration object to validate the authentication header on incoming requests. 認証構成にクレーム検証コントロールを追加する必要があります。You must add a claims validator to the authentication configuration. 要求は認証ヘッダーの後に評価されます。The claims are evaluated after the authentication header. 要求を拒否する場合は、検証コードからエラーまたは例外をスローする必要があります。Your validation code should throw an error or exception to reject the request.

チャット コネクタを作成するときに、設定パラメーターに allowedCallers または authConfiguration のいずれかのプロパティを含めて、ボット間認証を有効にします。When creating a chat connector, include either an allowedCallers or an authConfiguration property in the settings parameter to enable bot-to-bot authentication.

チャット コネクタの既定の要求検証コントロールでは、allowedCallers プロパティが使用されます。The default claims validator for the chat connector uses the allowedCallers property. その値は、スキルの呼び出しが許可されているボットのアプリケーション ID の配列である必要があります。Its value should be an array of the application IDs of the bots that are allowed to call the skill. 最初の要素を ' * ' に設定して、すべてのボットがスキルを呼び出せるようにします。Set the first element to '*' to allow any bot to call the skill.

カスタム要求検証関数を使用するには、authConfiguration フィールドを検証関数に設定します。To use a custom claims validation function, set the authConfiguration field to your validation function. この関数は、要求オブジェクトの配列を受け取り、検証が失敗するとエラーをスローします。This function should accept an array of claim objects and throw an error if validation fails. 予約ボットを変換する」セクションの手順 4 に、要求検証コントロールの例があります。Step 4 of the convert the booking bot section has an example claims validator.