Share via


Een vaardigheidsconsumer implementeren

VAN TOEPASSING OP: SDK v4

U kunt vaardigheden gebruiken om een andere bot uit te breiden. Een vaardigheid is een bot die een set taken voor een andere bot kan uitvoeren en een manifest gebruikt om de interface ervan te beschrijven. Een hoofdbot is een gebruikersgerichte bot die een of meer vaardigheden kan aanroepen. Een hoofdbot is een soort vaardigheidsconsumer.

  • Een consument van vaardigheden moet claimvalidatie gebruiken om te beheren welke vaardigheden er toegang toe hebben.
  • Een vaardigheidsconsumer kan meerdere vaardigheden gebruiken.
  • Ontwikkelaars die geen toegang hebben tot de broncode van de vaardigheid, kunnen de informatie in het manifest van de vaardigheid gebruiken om hun vaardigheidsgebruiker te ontwerpen.

In dit artikel wordt gedemonstreert hoe u een vaardigheidsconsumer implementeert die gebruikmaakt van de echovaardigheid om de invoer van de gebruiker te echoën. Zie hoe u een vaardigheid implementeert voor een voorbeeldmanifest en informatie over het implementeren van de echovaardigheid.

Voor informatie over het gebruik van een vaardigheidsdialoogvenster om een vaardigheid te gebruiken, raadpleegt u hoe u een dialoogvenster gebruikt om een vaardigheid te gebruiken.

Sommige typen vaardigheidsgebruikers kunnen bepaalde typen vaardigheidsbots niet gebruiken. In de volgende tabel wordt beschreven welke combinaties worden ondersteund.

  Vaardigheid voor meerdere tenants Vaardigheid met één tenant Door de gebruiker toegewezen vaardigheden voor beheerde identiteit
Consument met meerdere tenants Ondersteund Niet ondersteund Niet ondersteund
Consument met één tenant Niet ondersteund Ondersteund als beide apps deel uitmaken van dezelfde tenant Ondersteund als beide apps deel uitmaken van dezelfde tenant
Door de gebruiker toegewezen beheerde identiteitgebruiker Niet ondersteund Ondersteund als beide apps deel uitmaken van dezelfde tenant Ondersteund als beide apps deel uitmaken van dezelfde tenant

Notitie

De Sdk's voor Bot Framework JavaScript, C# en Python blijven ondersteund, maar de Java SDK wordt buiten gebruik gesteld met definitieve langetermijnondersteuning die eindigt op november 2023.

Bestaande bots die zijn gebouwd met de Java SDK blijven functioneren.

Voor het bouwen van nieuwe bots kunt u Power Virtual Agents gebruiken en lezen over het kiezen van de juiste chatbotoplossing.

Zie De toekomst van botbouw voor meer informatie.

Vereisten

Notitie

Vanaf versie 4.11 hebt u geen app-id en wachtwoord nodig om een vaardigheidsconsumer lokaal te testen in de Bot Framework Emulator. Een Azure-abonnement is nog steeds vereist om uw consument te implementeren in Azure of om een geïmplementeerde vaardigheid te gebruiken.

Over dit voorbeeld

Het eenvoudige bot-naar-bot-voorbeeld bevat projecten voor twee bots:

  • De bot met echovaardigheden, waarmee de vaardigheid wordt geïmplementeerd.
  • De eenvoudige hoofdbot, waarmee een hoofdbot wordt geïmplementeerd die de vaardigheid verbruikt.

Dit artikel richt zich op de hoofdbot, met ondersteuningslogica in de bot- en adapterobjecten en bevat objecten die worden gebruikt om activiteiten uit te wisselen met een vaardigheid. Deze omvatten:

  • Een vaardigheidsclient, die wordt gebruikt om activiteiten naar een vaardigheid te verzenden.
  • Een vaardigheidshandler, die wordt gebruikt om activiteiten van een vaardigheid te ontvangen.
  • Een vaardigheid gespreks-id factory, gebruikt door de vaardigheidsclient en handler om te vertalen tussen de gespreksverwijzing van de gebruiker en de gespreksverwijzing op basis van de basisvaardigheden.

Zie hoe u een vaardigheid implementeert voor informatie over de bot met echovaardigheden.

Resources

Voor geïmplementeerde bots is verificatie van bot-naar-bot vereist dat elke deelnemende bot geldige identiteitsgegevens heeft. U kunt echter gebruikers met meerdere tenants lokaal testen met de emulator zonder app-id en wachtwoord.

Toepassingsconfiguratie

  1. Voeg eventueel de identiteitsgegevens van de hoofdbot toe aan het configuratiebestand. Als de gebruiker van de vaardigheid of vaardigheid identiteitsinformatie verstrekt, moeten beide informatie bevatten.
  2. Voeg het hosteindpunt voor vaardigheden (de service- of callback-URL) toe waaraan de vaardigheden moeten reageren op de vaardigheidsgebruiker.
  3. Voeg een vermelding toe voor elke vaardigheid die de consument gaat gebruiken. Elke vermelding omvat:
    • Een id die de consument gebruikt om elke vaardigheid te identificeren.
    • Optioneel, de app of client-id van de vaardigheid.
    • Het berichteindpunt van de vaardigheid.

Notitie

Als de gebruiker van de vaardigheid of vaardigheid identiteitsinformatie verstrekt, moeten beide informatie bevatten.

SimpleRootBot\appsettings.json

Voeg eventueel de identiteitsgegevens van de hoofdbot toe en voeg de app- of client-id voor de bot met echovaardigheden toe.

{
  "MicrosoftAppType": "",
  "MicrosoftAppId": "",
  "MicrosoftAppPassword": "",
  "MicrosoftAppTenantId": "",
  "SkillHostEndpoint": "http://localhost:3978/api/skills/",
  "BotFrameworkSkills": [
    {
      "Id": "EchoSkillBot",
      "AppId": "",
      "SkillEndpoint": "http://localhost:39783/api/messages"
    }
  ]
}

Vaardighedenconfiguratie

In dit voorbeeld wordt informatie voor elke vaardigheid in het configuratiebestand gelezen in een verzameling vaardigheidsobjecten .

SimpleRootBot\SkillsConfiguration.cs

public class SkillsConfiguration
{
    public SkillsConfiguration(IConfiguration configuration)
    {
        var section = configuration?.GetSection("BotFrameworkSkills");
        var skills = section?.Get<BotFrameworkSkill[]>();
        if (skills != null)
        {
            foreach (var skill in skills)
            {
                Skills.Add(skill.Id, skill);
            }
        }

        var skillHostEndpoint = configuration?.GetValue<string>(nameof(SkillHostEndpoint));
        if (!string.IsNullOrWhiteSpace(skillHostEndpoint))
        {
            SkillHostEndpoint = new Uri(skillHostEndpoint);
        }
    }

    public Uri SkillHostEndpoint { get; }

    public Dictionary<string, BotFrameworkSkill> Skills { get; } = new Dictionary<string, BotFrameworkSkill>();
}

Gespreks-id factory

Hiermee wordt de gespreks-id gemaakt voor gebruik met de vaardigheid en kan de oorspronkelijke gespreks-id van de gebruiker worden hersteld van de gespreks-id van de vaardigheid.

De gespreks-id factory voor dit voorbeeld ondersteunt een eenvoudig scenario waarbij:

  • De hoofdbot is ontworpen om één specifieke vaardigheid te gebruiken.
  • De hoofdbot heeft slechts één actief gesprek met een vaardigheid tegelijk.

De SDK biedt een SkillConversationIdFactory klasse die kan worden gebruikt voor elke vaardigheid zonder dat de broncode hoeft te worden gerepliceerd. De gespreks-id factory is geconfigureerd in Startup.cs.

Als u complexere scenario's wilt ondersteunen, ontwerpt u uw gespreks-id factory zodat:

  • Met de methode gespreks-id voor vaardigheden maken wordt de juiste gespreks-id voor vaardigheden gegenereerd of gegenereerd.
  • Met de get-gespreksreferentiemethode wordt het juiste gebruikersgesprek opgehaald.

Vaardigheidsclient en vaardigheidshandler

De gebruiker van de vaardigheid gebruikt een vaardigheidsclient om activiteiten door te sturen naar de vaardigheid. De client gebruikt hiervoor de informatie over de configuratie van vaardigheden en gespreks-id's.

De gebruiker van de vaardigheid gebruikt een vaardigheidshandler om activiteiten van een vaardigheid te ontvangen. De handler maakt gebruik van de gespreks-id factory, de verificatieconfiguratie en een referentieprovider om dit te doen, en heeft ook afhankelijkheden van de adapter en activiteitshandler van de hoofdbot

SimpleRootBot\Startup.cs

services.AddSingleton<IBotFrameworkHttpAdapter>(sp => sp.GetService<CloudAdapter>());
services.AddSingleton<BotAdapter>(sp => sp.GetService<CloudAdapter>());

HTTP-verkeer van de vaardigheid komt binnen in het service-URL-eindpunt dat de gebruiker van de vaardigheid aan de vaardigheid adverteert. Gebruik een taalspecifieke eindpunthandler om verkeer door te sturen naar de vaardigheidshandler.

De standaardhandler voor vaardigheden:

  • Als er een app-id en wachtwoord aanwezig zijn, gebruikt u een verificatieconfiguratieobject om zowel bot-naar-bot-verificatie als claimvalidatie uit te voeren.
  • Gebruikt de gespreks-id factory om te vertalen van het gesprek met consumentenvaardigheden terug naar het gesprek van de hoofdgebruiker.
  • Genereert een proactief bericht zodat de gebruiker van de vaardigheid context kan omzetten en activiteiten naar de gebruiker kan doorsturen.

Logica voor activiteitshandler

Opmerking: de consumentenlogica voor vaardigheden moet:

  • Vergeet niet of er actieve vaardigheden zijn en activiteiten naar hen doorsturen, indien van toepassing.
  • U ziet wanneer een gebruiker een aanvraag indient die moet worden doorgestuurd naar een vaardigheid en de vaardigheid moet starten.
  • Zoek naar een endOfConversation activiteit van elke actieve vaardigheid om te zien wanneer deze is voltooid.
  • Voeg indien van toepassing logica toe om de gebruiker of gebruiker van vaardigheden een vaardigheid te laten annuleren die nog niet is voltooid.
  • Sla de status op voordat u de aanroep naar een vaardigheid maakt, omdat elk antwoord kan terugkeren naar een ander exemplaar van de vaardigheidsgebruiker.

SimpleRootBot\Bots\RootBot.cs

De hoofdbot heeft afhankelijkheden van de gespreksstatus, de informatie over vaardigheden, de vaardigheidsclient en de algemene configuratie. ASP.NET biedt deze objecten via afhankelijkheidsinjectie. De hoofdbot definieert ook een toegangsbeheerobject voor gespreksstatus om bij te houden welke vaardigheid actief is.

public static readonly string ActiveSkillPropertyName = $"{typeof(RootBot).FullName}.ActiveSkillProperty";
private readonly IStatePropertyAccessor<BotFrameworkSkill> _activeSkillProperty;
private readonly string _botId;
private readonly ConversationState _conversationState;
private readonly BotFrameworkAuthentication _auth;
private readonly SkillConversationIdFactoryBase _conversationIdFactory;
private readonly SkillsConfiguration _skillsConfig;
private readonly BotFrameworkSkill _targetSkill;

public RootBot(BotFrameworkAuthentication auth, ConversationState conversationState, SkillsConfiguration skillsConfig, SkillConversationIdFactoryBase conversationIdFactory, IConfiguration configuration)
{
    _auth = auth ?? throw new ArgumentNullException(nameof(auth));
    _conversationState = conversationState ?? throw new ArgumentNullException(nameof(conversationState));
    _skillsConfig = skillsConfig ?? throw new ArgumentNullException(nameof(skillsConfig));
    _conversationIdFactory = conversationIdFactory ?? throw new ArgumentNullException(nameof(conversationIdFactory));

    if (configuration == null)
    {
        throw new ArgumentNullException(nameof(configuration));
    }

    _botId = configuration.GetSection(MicrosoftAppCredentials.MicrosoftAppIdKey)?.Value;

    // We use a single skill in this example.
    var targetSkillId = "EchoSkillBot";
    _skillsConfig.Skills.TryGetValue(targetSkillId, out _targetSkill);

    // Create state property to track the active skill
    _activeSkillProperty = conversationState.CreateProperty<BotFrameworkSkill>(ActiveSkillPropertyName);
}

Dit voorbeeld heeft een helpermethode voor het doorsturen van activiteiten naar een vaardigheid. Hiermee wordt de gespreksstatus opgeslagen voordat de vaardigheid wordt aangeroepen en wordt gecontroleerd of de HTTP-aanvraag is geslaagd.

private async Task SendToSkill(ITurnContext turnContext, BotFrameworkSkill targetSkill, CancellationToken cancellationToken)
{
    // NOTE: Always SaveChanges() before calling a skill so that any activity generated by the skill
    // will have access to current accurate state.
    await _conversationState.SaveChangesAsync(turnContext, force: true, cancellationToken: cancellationToken);

    // Create a conversationId to interact with the skill and send the activity
    var options = new SkillConversationIdFactoryOptions
    {
        FromBotOAuthScope = turnContext.TurnState.Get<string>(BotAdapter.OAuthScopeKey),
        FromBotId = _botId,
        Activity = turnContext.Activity,
        BotFrameworkSkill = targetSkill
    };
    var skillConversationId = await _conversationIdFactory.CreateSkillConversationIdAsync(options, cancellationToken);

    using var client = _auth.CreateBotFrameworkClient();

    // route the activity to the skill
    var response = await client.PostActivityAsync(_botId, targetSkill.AppId, targetSkill.SkillEndpoint, _skillsConfig.SkillHostEndpoint, skillConversationId, turnContext.Activity, cancellationToken);

    // Check response status
    if (!(response.Status >= 200 && response.Status <= 299))
    {
        throw new HttpRequestException($"Error invoking the skill id: \"{targetSkill.Id}\" at \"{targetSkill.SkillEndpoint}\" (status is {response.Status}). \r\n {response.Body}");
    }
}

Opmerking: de hoofdbot bevat logica voor het doorsturen van activiteiten naar de vaardigheid, het starten van de vaardigheid bij de aanvraag van de gebruiker en het stoppen van de vaardigheid wanneer de vaardigheid is voltooid.

protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
    if (turnContext.Activity.Text.Contains("skill"))
    {
        await turnContext.SendActivityAsync(MessageFactory.Text("Got it, connecting you to the skill..."), cancellationToken);

        // Save active skill in state
        await _activeSkillProperty.SetAsync(turnContext, _targetSkill, cancellationToken);

        // Send the activity to the skill
        await SendToSkill(turnContext, _targetSkill, cancellationToken);
        return;
    }

    // just respond
    await turnContext.SendActivityAsync(MessageFactory.Text("Me no nothin'. Say \"skill\" and I'll patch you through"), cancellationToken);

    // Save conversation state
    await _conversationState.SaveChangesAsync(turnContext, force: true, cancellationToken: cancellationToken);
}

protected override async Task OnEndOfConversationActivityAsync(ITurnContext<IEndOfConversationActivity> turnContext, CancellationToken cancellationToken)
{
    // forget skill invocation
    await _activeSkillProperty.DeleteAsync(turnContext, cancellationToken);

    // Show status message, text and value returned by the skill
    var eocActivityMessage = $"Received {ActivityTypes.EndOfConversation}.\n\nCode: {turnContext.Activity.Code}";
    if (!string.IsNullOrWhiteSpace(turnContext.Activity.Text))
    {
        eocActivityMessage += $"\n\nText: {turnContext.Activity.Text}";
    }

    if ((turnContext.Activity as Activity)?.Value != null)
    {
        eocActivityMessage += $"\n\nValue: {JsonConvert.SerializeObject((turnContext.Activity as Activity)?.Value)}";
    }

    await turnContext.SendActivityAsync(MessageFactory.Text(eocActivityMessage), cancellationToken);

    // We are back at the root
    await turnContext.SendActivityAsync(MessageFactory.Text("Back in the root bot. Say \"skill\" and I'll patch you through"), cancellationToken);

    // Save conversation state
    await _conversationState.SaveChangesAsync(turnContext, cancellationToken: cancellationToken);
}

Fouthandler inschakelen

Wanneer er een fout optreedt, wist de adapter de gespreksstatus om het gesprek opnieuw in te stellen met de gebruiker en te voorkomen dat een foutstatus behouden blijft.

Het is een goede gewoonte om een einde van de gespreksactiviteit naar een actieve vaardigheid te verzenden voordat de gespreksstatus in de vaardigheidsconsumer wordt gewist. Hiermee kan de vaardigheid alle resources vrijgeven die zijn gekoppeld aan het gesprek over consumentenvaardigheden voordat de consument van de vaardigheid het gesprek vrijgeeft.

SimpleRootBot\AdapterWithErrorHandler.cs

In dit voorbeeld wordt de logica voor turnfouten opgesplitst in een aantal helpermethoden.

private async Task HandleTurnError(ITurnContext turnContext, Exception exception)
{
    // Log any leaked exception from the application.
    // NOTE: In production environment, you should consider logging this to
    // Azure Application Insights. Visit https://aka.ms/bottelemetry to see how
    // to add telemetry capture to your bot.
    _logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}");

    await SendErrorMessageAsync(turnContext, exception);
    await EndSkillConversationAsync(turnContext);
    await ClearConversationStateAsync(turnContext);
}

private async Task SendErrorMessageAsync(ITurnContext turnContext, Exception exception)
{
    try
    {
        // Send a message to the user
        var errorMessageText = "The bot encountered an error or bug.";
        var errorMessage = MessageFactory.Text(errorMessageText, errorMessageText, InputHints.IgnoringInput);
        await turnContext.SendActivityAsync(errorMessage);

        errorMessageText = "To continue to run this bot, please fix the bot source code.";
        errorMessage = MessageFactory.Text(errorMessageText, errorMessageText, InputHints.ExpectingInput);
        await turnContext.SendActivityAsync(errorMessage);

        // Send a trace activity, which will be displayed in the Bot Framework Emulator
        await turnContext.TraceActivityAsync("OnTurnError Trace", exception.ToString(), "https://www.botframework.com/schemas/error", "TurnError");
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, $"Exception caught in SendErrorMessageAsync : {ex}");
    }
}

private async Task EndSkillConversationAsync(ITurnContext turnContext)
{
    if (_skillsConfig == null)
    {
        return;
    }

    try
    {
        // Inform the active skill that the conversation is ended so that it has
        // a chance to clean up.
        // Note: ActiveSkillPropertyName is set by the RooBot while messages are being
        // forwarded to a Skill.
        var activeSkill = await _conversationState.CreateProperty<BotFrameworkSkill>(RootBot.ActiveSkillPropertyName).GetAsync(turnContext, () => null);
        if (activeSkill != null)
        {
            var botId = _configuration.GetSection(MicrosoftAppCredentials.MicrosoftAppIdKey)?.Value;

            var endOfConversation = Activity.CreateEndOfConversationActivity();
            endOfConversation.Code = "RootSkillError";
            endOfConversation.ApplyConversationReference(turnContext.Activity.GetConversationReference(), true);

            await _conversationState.SaveChangesAsync(turnContext, true);

            using var client = _auth.CreateBotFrameworkClient();

            await client.PostActivityAsync(botId, activeSkill.AppId, activeSkill.SkillEndpoint, _skillsConfig.SkillHostEndpoint, endOfConversation.Conversation.Id, (Activity)endOfConversation, CancellationToken.None);
        }
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, $"Exception caught on attempting to send EndOfConversation : {ex}");
    }
}

private async Task ClearConversationStateAsync(ITurnContext turnContext)
{
    try
    {
        // Delete the conversationState for the current conversation to prevent the
        // bot from getting stuck in a error-loop caused by being in a bad state.
        // ConversationState should be thought of as similar to "cookie-state" in a Web pages.
        await _conversationState.DeleteAsync(turnContext);
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, $"Exception caught on attempting to Delete ConversationState : {ex}");
    }
}

Eindpunt voor vaardigheden

De bot definieert een eindpunt dat binnenkomende vaardigheidsactiviteiten doorstuurt naar de vaardigheidshandler van de hoofdbot.

SimpleRootBot\Controllers\SkillController.cs

[ApiController]
[Route("api/skills")]
public class SkillController : ChannelServiceController
{
    public SkillController(ChannelServiceHandlerBase handler)
        : base(handler)
    {
    }
}

Serviceregistratie

Neem een verificatieconfiguratieobject op met claimsvalidatie, plus alle aanvullende objecten. In dit voorbeeld wordt dezelfde verificatieconfiguratielogica gebruikt voor het valideren van activiteiten van zowel gebruikers als vaardigheden.

SimpleRootBot\Startup.cs

// Register the skills configuration class
services.AddSingleton<SkillsConfiguration>();

// Register AuthConfiguration to enable custom claim validation.
services.AddSingleton(sp =>
{
    var allowedSkills = sp.GetService<SkillsConfiguration>().Skills.Values.Select(s => s.AppId).ToList();

    var claimsValidator = new AllowedSkillsClaimsValidator(allowedSkills);

    // If TenantId is specified in config, add the tenant as a valid JWT token issuer for Bot to Skill conversation.
    // The token issuer for MSI and single tenant scenarios will be the tenant where the bot is registered.
    var validTokenIssuers = new List<string>();
    var tenantId = sp.GetService<IConfiguration>().GetSection(MicrosoftAppCredentials.MicrosoftAppTenantIdKey)?.Value;

    if (!string.IsNullOrWhiteSpace(tenantId))
    {
        // For SingleTenant/MSI auth, the JWT tokens will be issued from the bot's home tenant.
        // Therefore, these issuers need to be added to the list of valid token issuers for authenticating activity requests.
        validTokenIssuers.Add(string.Format(CultureInfo.InvariantCulture, AuthenticationConstants.ValidTokenIssuerUrlTemplateV1, tenantId));
        validTokenIssuers.Add(string.Format(CultureInfo.InvariantCulture, AuthenticationConstants.ValidTokenIssuerUrlTemplateV2, tenantId));
        validTokenIssuers.Add(string.Format(CultureInfo.InvariantCulture, AuthenticationConstants.ValidGovernmentTokenIssuerUrlTemplateV1, tenantId));
        validTokenIssuers.Add(string.Format(CultureInfo.InvariantCulture, AuthenticationConstants.ValidGovernmentTokenIssuerUrlTemplateV2, tenantId));
    }

    return new AuthenticationConfiguration
    {
        ClaimsValidator = claimsValidator,
        ValidTokenIssuers = validTokenIssuers
    };
});

De hoofdbot testen

U kunt de vaardigheidsconsumer in de emulator testen alsof het een normale bot is; U moet echter tegelijkertijd zowel de vaardigheid als de vaardigheid van consumentenbots uitvoeren. Lees hoe u een vaardigheid implementeert voor informatie over het configureren van de vaardigheid.

De nieuwste Bot Framework Emulator downloaden en installeren

  1. Voer de bot voor echovaardigheden en een eenvoudige hoofdbot lokaal uit op uw computer. Als u instructies nodig hebt, raadpleegt u het bestand voor het READMEC#-, JavaScript-, Java- of Python-voorbeeld.
  2. Gebruik de emulator om de bot te testen zoals hieronder wordt weergegeven. Wanneer u een end of stop meer berichten naar de vaardigheid verzendt, verzendt de vaardigheid een activiteit naar de hoofdbot endOfConversation , naast het antwoordbericht. De endOfConversation code-eigenschap van de activiteit geeft aan dat de vaardigheid is voltooid.

Voorbeeldtranscriptie van een interactie met de vaardigheidsconsumer.

Meer informatie over foutopsporing

Omdat verkeer tussen vaardigheden en vaardigheidsgebruikers wordt geverifieerd, zijn er extra stappen bij het opsporen van fouten in dergelijke bots.

Anders kunt u fouten opsporen in een vaardigheidsconsumer of vaardigheid, net zoals bij het opsporen van fouten in andere bots. Zie Fouten opsporen in een bot en fouten opsporen met de Bot Framework Emulator voor meer informatie.

Aanvullende informatie

Hier volgen enkele aandachtspunten bij het implementeren van een complexere hoofdbot.

De gebruiker toestaan een vaardigheid met meerdere stappen te annuleren

De hoofdbot moet het bericht van de gebruiker controleren voordat het naar de actieve vaardigheid wordt doorgestuurd. Als de gebruiker het huidige proces wil annuleren, kan de hoofdbot een endOfConversation activiteit naar de vaardigheid verzenden in plaats van het bericht door te sturen.

Gegevens uitwisselen tussen de hoofd- en vaardigheidsbots

Als u parameters naar de vaardigheid wilt verzenden, kan de gebruiker van de vaardigheid de eigenschap waarde instellen voor berichten die naar de vaardigheid worden verzonden. Als u retourwaarden van de vaardigheid wilt ontvangen, moet de gebruiker van de vaardigheid de waarde-eigenschap controleren wanneer de vaardigheid een endOfConversation activiteit verzendt.

Meerdere vaardigheden gebruiken

  • Als een vaardigheid actief is, moet de hoofdbot bepalen welke vaardigheid actief is en het bericht van de gebruiker doorsturen naar de juiste vaardigheid.
  • Als er geen vaardigheid actief is, moet de hoofdbot bepalen welke vaardigheid moet worden gestart, indien van toepassing, op basis van de botstatus en de invoer van de gebruiker.
  • Als u wilt dat de gebruiker kan schakelen tussen meerdere gelijktijdige vaardigheden, moet de hoofdbot bepalen met welke van de actieve vaardigheden die de gebruiker wil gebruiken voordat het bericht van de gebruiker wordt doorgestuurd.

Een bezorgingsmodus van verwachte antwoorden gebruiken

Ga als volgende te werk om de verwachte leveringsmodus voor antwoorden te gebruiken:

  • Kloon de activiteit vanuit de turncontext.
  • Stel de eigenschap leveringsmodus van de nieuwe activiteit in op 'ExpectReplies' voordat u de activiteit van de hoofdbot naar vaardigheid verzendt.
  • Lees verwachte antwoorden uit de hoofdtekst van het aanroepende antwoord dat is geretourneerd door het antwoord van de aanvraag.
  • Verwerkt elke activiteit, binnen de hoofdbot of door deze naar het kanaal te verzenden dat de oorspronkelijke aanvraag heeft gestart.

U kunt verwachten dat antwoorden nuttig kunnen zijn in situaties waarin de bot die antwoordt op een activiteit hetzelfde exemplaar moet zijn van de bot die de activiteit heeft ontvangen.