Dela via


Azure Bot Framework SDK till Microsoft 365 Agents SDK migreringsvägledning för Node.js

I den här artikeln beskrivs vilka ändringar som krävs för att migrera från SDK för Bot Framework SDK för Node.js.

Förutsättningar

  • Node.js version 20 eller senare
  • Befintligt Bot Framework SDK-projekt
  • Azure Bot Service resurs (förblir oförändrad under migreringen)

Ändringar av SDK-kod för NodeJS

Ändringarna i det här avsnittet beror på skillnader mellan Azure Bot Framework SDK och Microsoft 365 Agents SDK JavaScript .

Azure resurser

Dina Azure resurser förblir oförändrade. Du måste referera till appsettings-egenskaperna för MicrosoftAppType, MicrosoftAppId, MicrosoftAppPassword och MicrosoftAppTenantId. Dessa inställningsnamn används dock inte längre och kan tas bort senare. Läs mer om miljökonfiguration

De första stegen

Använd följande ändringar först för att åtgärda de flesta skillnaderna. Du måste fortfarande felsöka och söka efter andra skillnader när du har tillämpat ändringarna.

Uppdatera paketberoenden

Den här ändringen åtgärdar inte alla nödvändiga namnområden, men den omfattar huvuddelen av dem.

Scenarium Bot Frameworks utvecklingskit Agent-SDK
Grundläggande hosting botbuilder @microsoft/agents-hosting
Aktivitetsschema botframework-schema @microsoft/agents-activity
Dialogrutor botbuilder-dialogs @microsoft/agents-hosting-dialogs
Azure Cosmos DB botbuilder-azure @microsoft/agents-hosting-storage-cosmos
Microsoft Azure Blob Storage-tjänst botbuilder-azure-blobs @microsoft/agents-hosting-storage-blob
Express-serververktyg Manuell konfiguration @microsoft/agents-hosting-express

Robotar som använder Teams

Om din robot använder Teams lägger du till ett paketberoende för @microsoft/agents-hosting-extensions-teams

Uppdatera importer/kräv

Använd sök och ersätt för att göra följande ändringar:

Bot Framework Agent-SDK
require('botframework-schema'); require('@microsoft/agents-activity')
require('botbuilder'); require('@microsoft/agents-hosting')
require('botbuilder-dialogs'); require('@microsoft/agents-hosting-dialogs')

Aktivitetsklass för Agent-SDK

Paketet @microsoft/agents-activity innehåller klassen Aktivitet för att utföra parsning baserat på zod. Du kan parsa och validera dina anpassade aktiviteter från JSON med Activity.fromJson() eller från literala JavaScript-objekt med Activity.fromObject().

Dessutom Activity centraliserar klassen alla åtgärder relaterade till aktivitetens nyttolast, till exempel getConversationReference. Metoderna i följande tabell har flyttats från TurnContext och fungerar nu i hela den aktuella aktivitetsinstansen:

Statisk Bot Framework-metod Agent-SDK-instansmetod
TurnContext.applyConversationReference activity.applyConversationReference
TurnContext.getConversationReference activity.getConversationReference
TurnContext.getReplyConversationReference activity.getReplyConversationReference
TurnContext.removeRecipientMention activity.removeRecipientMention
TurnContext.getMentions activity.getMentions
TurnContext.removeMentionText activity.removeMentionText

Start och konfiguration

Agenternas SDK-konfigurationssystem ersätter klassen ConfigurationBotFrameworkAuthentication med gränssnittet AuthConfiguration.

Om du vill läsa in konfigurationen från standardfilen .env används loadAuthConfigFromEnv.

Viktigt!

Konfigurationsvariablerna beskrivs i Konfigurera autentisering i JavaScript.

Miljökonfiguration

Skapa en .env-fil med följande variabler:

# Required for Azure Bot Service
clientId=your-app-id
clientSecret=your-app-secret  
tenantId=your-tenant-id

# Optional - for local debugging
PORT=3978
DEBUG=true

Migreringskommentar: Uppdatera miljövariabelnamnen enligt följande tabell:

Bot Frameworks utvecklingskit Agent-SDK
MicrosoftAppId clientId
MicrosoftAppPassword clientSecret
MicrosoftAppTenantId tenantId

Autentisering och säkerhet

När Bot Framework SDK auktoriserar inkommande begäranden innehåller den JWT- auktoriseringstoken (JSON Web Token) i stacken. Agent-SDK gör det inte. När du använder en webbserverkörning, till exempel Express, måste du konfigurera ett JWT-mellanprogram för att auktorisera inkommande begäranden baserat på JWT Bearer-token, Agent-SDK tillhandahåller metoden authorizeJWT(AuthConfiguration).

JWT-mellanprogram (krävs för produktion):

import { authorizeJWT, loadAuthConfigFromEnv } from '@microsoft/agents-hosting'

const authConfig = loadAuthConfigFromEnv()
server.use(authorizeJWT(authConfig))

Lokal utveckling:

För lokal felsökning kan JWT-validering inaktiveras:

// Only for local development - NEVER in production
if (process.env.NODE_ENV === 'development') {
    // JWT validation disabled for local testing
} else {
    server.use(authorizeJWT(authConfig))
}

Alternativ för serverkonfiguration

Agent-SDK innehåller två metoder för att konfigurera servern:

Använda startServer-metoden

Använd den här förenklade metoden för nya projekt när du vill ha en minimal konfiguration och inte behöver anpassade mellanprogram.

Uppdatera initieringskoden från botbuilder:

const { EchoBot } = require('./bot');
const {
    CloudAdapter,
    ConfigurationBotFrameworkAuthentication
} = require('botbuilder');
const botFrameworkAuthentication = new ConfigurationBotFrameworkAuthentication(process.env);
const adapter = new CloudAdapter(botFrameworkAuthentication);
const myBot = new EchoBot();
const server = express();
server.use(express.json());
server.post('/api/messages', async (req, res) => 
    await adapter.process(req, res, (context) => 
      myBot.run(context));
);

Till agenthosting med startServer():

const { EchoBot } = require('./bot');
const { startServer } = require('@microsoft/agents-hosting-express')
startServer(new EchoBot());

Manuell Express-konfiguration

Använd den här metoden när du migrerar befintliga robotar, behöver anpassade mellanprogram och vill ha fullständig kontroll över Express-konfigurationen

const { EchoBot } = require('./bot');
const {
    CloudAdapter,
    loadAuthConfigFromEnv, // Update
    authorizeJWT // Update
} = require('@microsoft/agents-hosting'); // Update
const authConfig = loadAuthConfigFromEnv(); // Update
const adapter = new CloudAdapter(authConfig); // Update
const myBot = new EchoBot();
const server = express();
server.use(express.json());
server.use(authorizeJWT(authConfig)); // Update
server.post('/api/messages', async (req, res) => 
    await adapter.process(req, res, (context) => 
      myBot.run(context));
);

const port = process.env.PORT || 3978;
server.listen(port, () => {
    console.log(`Server listening on port ${port}`);
}).on('error', (err) => {
    console.error('Server failed to start:', err);
    process.exit(1);
});

Stöd för ActivityHandler

De flesta robotar som skapats med Bot Framework SDK baseras på basklassen botbuilder-core.ActivityHandler.

Agent-SDK tillhandahåller en kompatibel agents-hosting.ActivityHandler som underhåller samma API-yta för enklare migrering.

Viktiga skillnader

Några viktiga skillnader mellan Bot Framework SDK och Agent-SDK är:

Hanteringsparametrar:

SDK Typ av hanterare
Bot Frameworks utvecklingskit BotHandler
Agent-SDK AgentHandler

Ytterligare metoder i Agent-SDK:

Metod Beskrivning
onMessageDelete Hanterar aktiviteter för borttagning av meddelanden
onMessageUpdate Hanterar aktiviteter för meddelandeuppdatering
onSignInInvoke Hanterar aktiviteter för inloggningsanrop

Metoder som saknas i Agent-SDK:

Metod Förnuft
onCommand Kommandoaktiviteter stöds inte
onCommandResult Aktiviteter för kommandoresultat stöds inte
onEvent Allmän händelsehantering (specifika händelsetyper som onTokenResponseEvent stöds fortfarande)
onTokenResponseEvent Svarshändelser för OAuth-token

Ändringar i metodsignatur:

Alla hanteringsmetoder returneras ActivityHandler i stället this för metodlänkning. Hanteringsfunktioner använder typen AgentHandler, som har samma signatur som BotHandler

Migreringsexempel:

Bot Framework SDK:

const { ActivityHandler } = require('botbuilder');

class MyBot extends ActivityHandler {
    constructor() {
        super();
        this.onMessage(async (context, next) => {
            await context.sendActivity('Hello!');
            await next();
        });
    }
}

Migreringen är mestadels enkel, där huvudändringen är importinstruktionen och hanterartypen. De flesta befintliga ActivityHandler-baserade robotar bör fungera med minimala ändringar.

Viktigt!

ActivityHandler har fasats ut till förmån för den nya klassen AgentApplication

Migrera från ActivityHandler till AgentApplication

Även om ActivityHandler stöds för bakåtkompatibilitet är den rekommenderade metoden att använda AgentApplication:

Att använda ActivityHandler:

import { ActivityHandler } from '@microsoft/agents-hosting'

class MyBot extends ActivityHandler {
    constructor() {
        super()
        this.onMessage(async (context, next) => {
            await context.sendActivity('Hello!')
            await next()
        })
        
        this.onMembersAdded(async (context, next) => {
            await context.sendActivity('Welcome!')
            await next()
        })
    }
}

Viktiga skillnader

I följande tabell beskrivs de viktigaste skillnaderna mellan ActivityHandler och AgentApplication:

Feature ActivityHandler AgentApplication
Tillståndshantering Manuell tillståndshantering krävs Inbyggd tillståndshantering tillhandahålls
Händelsehantering Allmänna händelsehanterare (till exempel onMembersAdded) Mer specifika händelsehanterare (till exempel membersAdded)
Nästa funktion Hanterare kräver anrop av next() Hanterare kräver inte anrop av next()
Förvaring Manuell lagringskonfiguration Inbyggt lagringsstöd med automatisk tillståndsbeständighet

Vanliga migreringsmönster

Några vanliga migreringsmönster är:

Enkel ekorobot

Bot Framework

const { ActivityHandler } = require('botbuilder')

class EchoBot extends ActivityHandler {
    constructor() {
        super()
        this.onMessage(async (context, next) => {
            await context.sendActivity(`You said: ${context.activity.text}`)
            await next()
        })
    }
}

Tillståndshantering

Att använda AgentApplication:

import { AgentApplication, MemoryStorage } from '@microsoft/agents-hosting'

const agent = new AgentApplication({
    storage: new MemoryStorage()
})

agent.onMessage('/count', async (context, state) => {
    const count = state.conversation.count ?? 0
    state.conversation.count = count + 1
    await context.sendActivity(`Count: ${state.conversation.count}`)
})

Ärver från AgentApplication

Vid mer komplexa scenarier kan du skapa en klass som ärver från AgentApplication:

import { AgentApplication, MemoryStorage, MessageFactory } from '@microsoft/agents-hosting'

class MyAgent extends AgentApplication {
    constructor() {
        super({
            storage: new MemoryStorage()
        })
        this.setupRoutes()
    }
    
    setupRoutes() {
        this.onMessage('/help', this.handleHelp)
        this.onMessage('/status', this.handleStatus)
        this.onMessage('/reset', this.handleReset)
        
        this.onActivity('message', this.handleDefault)
        this.onConversationUpdate('membersAdded', this.handleWelcome)
    }
    
    handleHelp = async (context, state) => {
        const helpText = `
                Available commands:
                - /help - Show this help message
                - /status - Show current status
                - /reset - Reset conversation state
        `
        await context.sendActivity(MessageFactory.text(helpText))
    }
    
    handleStatus = async (context, state) => {
        const messageCount = state.conversation.messageCount ?? 0
        await context.sendActivity(`Messages processed: ${messageCount}`)
    }
    
    handleReset = async (context, state) => {
        state.deleteConversationState()
        await context.sendActivity('Conversation state has been reset.')
    }
    
    handleWelcome = async (context, state) => {
        const welcomeText = 'Welcome! Type /help to see available commands.'
        await context.sendActivity(MessageFactory.text(welcomeText))
    }
    
    handleDefault = async (context, state) => {
        // Increment message counter
        const messageCount = (state.conversation.messageCount ?? 0) + 1
        state.conversation.messageCount = messageCount
        
        const replyText = `Echo: ${context.activity.text} (Message #${messageCount})`
        await context.sendActivity(MessageFactory.text(replyText))
    }
}

export default new MyAgent()

Fördelar med det här mönstret

Förmån Beskrivning
Bättre organisation Separata metoder för olika hanterare
Återanvändbarhet Kan enkelt utökas eller ärvas ytterligare
Kan testas Enskilda metoder kan enhetstestas
Maintainability Tydligare kodstruktur för komplexa robotar
Pilfunktioner Bind kontext automatiskt this utan att behöva .bind()