Невозможно опубликовать активность. Unauthorize. Ошибка эмулятора бота - PullRequest
1 голос
/ 12 апреля 2019

Я добавил эти строки кодов в Startup.cs моего бота, чтобы он работал в веб-чате Azure:

var appid = Configuration.GetSection("microsoftappid").Value;
var apppassword = Configuration.GetSection("microsoftapppassword").Value;
options.CredentialProvider = new SimpleCredentialProvider(appid, apppassword);

Однако, когда у меня есть эти строки, мой бот не работает в эмуляторе бота,Как я могу интегрировать его с моим ботом, чтобы мне не нужно комментировать / раскомментировать строку кодов при публикации и открытии моего бота в эмуляторе.Я не так хорош в чтении кода, так что извините за вопросСпасибо!

public class Startup
{
    private ILoggerFactory _loggerFactory;
    private bool _isProduction = false;

    public Startup(IHostingEnvironment env)
    {
        _isProduction = env.IsProduction();

        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();

        Configuration = builder.Build();
    }

    public IConfiguration Configuration { get; }


    public void ConfigureServices(IServiceCollection services)
    {
        var secretKey = Configuration.GetSection("botFileSecret")?.Value;
        var botFilePath = Configuration.GetSection("botFilePath")?.Value;
        if (!File.Exists(botFilePath))
        {
            throw new FileNotFoundException($"The .bot configuration file was not found. botFilePath: {botFilePath}");
        }

        BotConfiguration botConfig = null;
        try
        {
            botConfig = BotConfiguration.Load(botFilePath, secretKey);
        }
        catch
        {
            var msg = @"Error reading bot file. Please ensure you have valid botFilePath and botFileSecret set for your environment.
            - You can find the botFilePath and botFileSecret in the Azure App Service application settings.
            - If you are running this bot locally, consider adding a appsettings.json file with botFilePath and botFileSecret.
            - See https://aka.ms/about-bot-file to learn more about .bot file its use and bot configuration.
            ";
            throw new InvalidOperationException(msg);
        }

        services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot configuration file could not be loaded. botFilePath: {botFilePath}"));

        var connectedServices = InitBotServices(botConfig);
        services.AddSingleton(sp => connectedServices);

        var environment = _isProduction ? "production" : "development";
        var service = botConfig.Services.FirstOrDefault(s => s.Type == "endpoint" && s.Name == environment);
        if (service == null && _isProduction)
        {

            service = botConfig.Services.Where(s => s.Type == "endpoint" && s.Name == "development").FirstOrDefault();
        }

        if (!(service is EndpointService endpointService))
        {
            throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
        }

        services.AddBot<CoreBot>(options =>
        {
            options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);
            options.ChannelProvider = new ConfigurationChannelProvider(Configuration);

            var appid = Configuration.GetSection("microsoftappid").Value;
            var apppassword = Configuration.GetSection("microsoftapppassword").Value;
            options.CredentialProvider = new SimpleCredentialProvider(appid, apppassword);

            ILogger logger = _loggerFactory.CreateLogger<CoreBot>();
            options.OnTurnError = async (context, exception) =>
            {
                logger.LogError($"Exception caught : {exception}");
                await context.SendActivityAsync($"Oops Sorry, it looks like something went wrong.");
            };

            IStorage dataStore = new MemoryStorage();

            var conversationState = new ConversationState(dataStore);
            options.State.Add(conversationState);

            var userState = new UserState(dataStore);
            options.State.Add(userState);

        });

        services.AddSingleton<BasicAccessors>(sp =>
        {
            var options = sp.GetRequiredService<IOptions<BotFrameworkOptions>>().Value;
            if (options == null)
            {
                throw new InvalidOperationException("BotFrameworkOptions must be configured prior to setting up the state accessors");
            }

            var conversationState = options.State.OfType<ConversationState>().FirstOrDefault();
            if (conversationState == null)
            {
                throw new InvalidOperationException(
                    "ConversationState must be defined and added before adding conversation-scoped state accessors.");
            }

            var userState = options.State.OfType<UserState>().FirstOrDefault();
            if (userState == null)
            {
                throw new InvalidOperationException(
                    "UserState must be defined and added before adding user-scoped state accessors.");
            }

            var accessors = new BasicAccessors(conversationState, userState)
            {
                DialogStateAccessor = conversationState.CreateProperty<DialogState>(BasicAccessors.DialogStateAccessorName),
                UserStateAccessor = userState.CreateProperty<UserProfile>(BasicAccessors.UserStateAccessorName),
                ComplaintTicketAccessor = conversationState.CreateProperty<ComplaintTicket>(BasicAccessors.ComplaintTicketName),
            };

            return accessors;
        });
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        _loggerFactory = loggerFactory;

        app.UseDefaultFiles()
            .UseStaticFiles()
            .UseBotFramework();
    }

    private static BotServices InitBotServices(BotConfiguration config)
    {
        var qnaServices = new Dictionary<string, QnAMaker>();
        var luisServices = new Dictionary<string, LuisRecognizer>();

        foreach (var service in config.Services)
        {
            switch (service.Type)
            {
                case ServiceTypes.Luis:
                    {
                        if (!(service is LuisService luis))
                        {
                            throw new InvalidOperationException("The LUIS service is not configured correctly in your '.bot' file.");
                        }

                        var app = new LuisApplication(luis.AppId, luis.SubscriptionKey, luis.GetEndpoint());
                        var recognizer = new LuisRecognizer(app);
                        luisServices.Add(luis.Name, recognizer);
                        break;
                    }

                case ServiceTypes.Dispatch:

                    if (!(service is DispatchService dispatch))
                    {
                        throw new InvalidOperationException("The Dispatch service is not configured correctly in your '.bot' file.");
                    }        

                    var dispatchApp = new LuisApplication(dispatch.AppId, dispatch.AuthoringKey, dispatch.GetEndpoint());

                    var dispatchARecognizer = new LuisRecognizer(dispatchApp);
                    luisServices.Add(dispatch.Name, dispatchARecognizer);
                    break;

                case ServiceTypes.QnA:
                    {

                        if (!(service is QnAMakerService qna))
                        {
                            throw new InvalidOperationException("The QnA service is not configured correctly in your '.bot' file.");
                        }

                        var qnaEndpoint = new QnAMakerEndpoint()
                        {
                            KnowledgeBaseId = qna.KbId,
                            EndpointKey = qna.EndpointKey,
                            Host = qna.Hostname,
                        };

                        var qnaMaker = new QnAMaker(qnaEndpoint);
                        qnaServices.Add(qna.Name, qnaMaker);

                        break;
                    }
            }
        }

        return new BotServices(qnaServices, luisServices);
    }
}

}

Ответы [ 2 ]

1 голос
/ 12 апреля 2019

Используйте 2 .bot файла (например, dev.bot & prod.bot)

В dev.bot добавьте конечную точку для эмулятора следующим образом:

{
  "type": "endpoint",
  "name": "dev",
  "endpoint": "http://localhost:3978/api/messages",
  "appId": "",
  "appPassword": "",
  "id": "1"
},

Вы бы добавили appIdи appPassword в prod.bot вместе с правильной конечной точкой (например, размещенной в Azure: ***. azurewebsites.net/api/messages).

Используйте appSettings.json + create appSettings.dev.json &appSettings.prod.json.Убедитесь, что .dev.json устанавливает

"botFilePath": ".\\dev.bot"

Аналогично для appSettings.prod.json.

Я обнаружил, что вы получаете неавторизованную ошибку в эмуляторе, когда переменная среды ASPNETCORE_ENVIRONMENT имеет значениене равно параметру конечной точки "name" в используемом файле .bot .Поэтому при локальной отладке на эмуляторе установите ASPNETCORE_ENVIRONMENT равным (в данном случае) 'dev'.

Это можно установить, щелкнув правой кнопкой мыши основной веб-проект .NET -> Свойства -> Отладка (вкладка) -> Переменные среды.

Set env vars in .NET core web project

0 голосов
/ 12 апреля 2019

Вы можете использовать этот код для удовлетворения ваших потребностей. Если вы запускаете код в своей локальной среде, значение _isProduction равно false. Если вы запускаете код в Azure, значение _isProduction равно true.

       var appid = Configuration.GetSection("microsoftappid").Value;
       var apppassword = Configuration.GetSection("microsoftapppassword").Value;
       if (_isProduction)
       {
           options.CredentialProvider = new SimpleCredentialProvider(appid, apppassword);
       }
       else
       {
           options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);
       }

Добавьте botFileSecret и botFilePath, которые были в вашем локальном файле бота appsettings.json, в новый файл appsettings.json.

enter image description here

Теперь код будет работать как на Azure, так и на эмуляторе. Кроме того, я заметил, что вы используете Memory Storage, который предназначен только для локальной отладки ботов. При перезапуске бота все, что хранится в памяти, исчезнет.

IStorage dataStore = new MemoryStorage();

Для производственных ботов вы можете использовать провайдеры хранилища Azure Blob или Azure CosmosDB.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...