Azure EchoBot 未发送任何消息。没有问候也没有回应

问题描述 投票:0回答:1

我创建了 Azure EchoBot 的最小设置。我的解决方案包括 ASP.NET Core 8 Web API 和 Angular 应用程序。我遵循 EchoBot 模板并将其部署到 Azure 应用服务

/linux/

Angular 应用程序安装了 WebChat 控件,我可以发送消息,这些消息显示在聊天中。但是,机器人在首次打开时不会返回任何答案或发送问候语。

这是 Chrome 中开发者控制台的屏幕截图:

enter image description here

这是我的 EchoBot 课程:

using Microsoft.Bot.Builder;
using Microsoft.Bot.Schema;

namespace limbo.dating.Server.Bots
{
    public class EchoBot : ActivityHandler
    {
        public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken)
        {
            // Log the activity type
            Console.WriteLine($"Activity Type: {turnContext.Activity.Type}");

            await base.OnTurnAsync(turnContext, cancellationToken);
        }

        protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            var replyText = $"Echo: {turnContext.Activity.Text}";
            await turnContext.SendActivityAsync(MessageFactory.Text(replyText, replyText), cancellationToken);
        }

        protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
        {
            var welcomeText = "Hello and welcome!";

            // Log the number of members added
            Console.WriteLine($"Members added count: {membersAdded.Count}");

            foreach (var member in membersAdded)
            {
                // Log each member added
                Console.WriteLine($"Member added: {member.Id}");

                if (member.Id != turnContext.Activity.Recipient.Id)
                {
                    await turnContext.SendActivityAsync(MessageFactory.Text(welcomeText, welcomeText), cancellationToken);
                }
            }
        }
    }
}

这是

Program.cs
中的配置:

using limbo.dating.Server.Bots;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Integration.AspNet.Core;
using Microsoft.Bot.Connector.Authentication;
using Microsoft.Identity.Web;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: "AllowedCorsOrigins",
        builder =>
        {
            builder.AllowAnyHeader()
                .AllowAnyOrigin()
                .AllowAnyMethod();
            //.AllowCredentials();
        });
});

// Add services to the container.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));

builder.Services.AddAuthorization(options =>
{
    options.FallbackPolicy = options.DefaultPolicy;
});

builder.Services.AddControllers();

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddHttpClient();

// Create the Bot Framework Authentication to be used with the Bot Adapter.
builder.Services.AddSingleton<BotFrameworkAuthentication, ConfigurationBotFrameworkAuthentication>();

// Create the Bot Adapter with error handling enabled.
builder.Services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();

// Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
builder.Services.AddTransient<IBot, limbo.dating.Server.Bots.EchoBot>();

var app = builder.Build();

app.UseDefaultFiles();
app.UseStaticFiles();
app.UseWebSockets();
app.UseRouting();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseCors();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.MapFallbackToFile("/index.html");

app.Run();

Appsettings.json

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "<mydomain>.onmicrosoft.com",
    "TenantId": "<mytenantid>",
    "ClientId": "<myclientid>",
    "CallbackPath": "/signin-oidc"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "MicrosoftAppType": "MultiTenant",
    "MicrosoftAppId": "<mymicrosoftappid>",
    "MicrosoftAppPassword": "mymicrosoftapppassword",
    "MicrosoftAppTenantId": ""
}

在 Angular 应用程序中,我有以下内容

app.component.ts

import { HttpClient } from '@angular/common/http';
import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import * as BotChat from "botframework-webchat";
import { createDirectLine } from 'botframework-webchat';
import { TokenService } from './services/token.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'] // Corrected property name
})
export class AppComponent implements AfterViewInit, OnInit {

  @ViewChild('botWindow')
  botWindowElement!: ElementRef;

  token!: string;

  constructor(private tokenService: TokenService) { }

  ngOnInit(): void {
    // Fetch the token when the component initializes
    this.tokenService.getDirectLineToken().subscribe(
      (data) => {
        this.token = data.token; // Assign the token
        console.log('Token fetched:', this.token);
        this.initializeWebChat(); // Initialize WebChat after token is fetched
      },
      (error) => {
        console.error('Error fetching token:', error);
      }
    );
  }

  ngAfterViewInit(): void {
    // Initialization moved to initializeWebChat method
  }

  initializeWebChat(): void {
    const directLine = createDirectLine({
      token: this.token
    });

    interface Action {
      type: string;
      payload?: any;
    }

    interface StoreAPI {
      dispatch: (action: Action) => void;
    }

    const store = BotChat.createStore({},
      (storeAPI: StoreAPI) => (next: (action: Action) => void) => (action: Action) => {
      if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
        storeAPI.dispatch({
          type: 'WEB_CHAT/SEND_EVENT',
          payload: {
            name: 'webchat/join',
            value: { language: window.navigator.language }
          }
        });
      }
      return next(action);
    });

    BotChat.renderWebChat({
      directLine: directLine,
      store: store,
      userID: '[email protected]',
      botID: 'limbo-dating-bot',
      withCredential: true,
    }, this.botWindowElement.nativeElement);

    directLine.connectionStatus$.subscribe(status => {
      if (status === 2) {
        console.log('DirectLine connected');
      } else if (status === 4) {
        console.error('DirectLine connection failed');
      }
    });

    directLine.connectionStatus$.subscribe(status => {
      if (status === 2) {
        console.log('DirectLine connected');

        // Send a test message to the bot
        directLine.postActivity({
          from: { id: '[email protected]', name: 'User' },
          type: 'message',
          text: 'Hello, bot!'
        }).subscribe(
          id => console.log('Message sent, activity id:', id),
          error => console.error('Error sending message:', error)
        );
      } else if (status === 4) {
        console.error('DirectLine connection failed');
      }
    });

    directLine.activity$.subscribe(activity => {
      if (activity.from.id !== '[email protected]') {
        console.log('Incoming message:', activity);
      } else {
        console.log('Outgoing message:', activity);
      }
    });
  }
}

我希望 EchoBot 回复“Echo:”+我在聊天窗口中输入的任何内容。

任何帮助将不胜感激!

angular azure asp.net-core-webapi .net-8.0 azure-bot-service
1个回答
0
投票

浏览器控制台:(

Uncaught (in promise) Error: A listener indicated an asynchronous response...
)

机器人的端点

/api/messages
可能无法正确响应或连接过早关闭,这是导致上述错误的唯一原因。

通过向

 发出 
POST

请求来测试端点 URL
https://limbo-dating-server-app-service.azurewebsites.net/api/messages

JSON 正文:

{
  "type": "message",
  "from": {
    "id": "test-user"
  },
  "text": "Hello, bot!"
}

设置标题:

  •  Authorization
    Bearer <DirectLineToken>
  • Content-Type
    application/json

Azure Bot Service 中,确认

Messaging endpoint
就像

enter image description here

更新自定义适配器 (

AdapterWithErrorHandler
) 以记录有关错误的更多详细信息。

public class AdapterWithErrorHandler : BotFrameworkHttpAdapter
{
    public AdapterWithErrorHandler(IConfiguration configuration, ILogger<BotFrameworkHttpAdapter> logger)
        : base(configuration, logger)
    {
        OnTurnError = async (turnContext, exception) =>
        {
            logger.LogError(exception, "Unhandled error: {Message}", exception.Message);
            
            // Send error message to user
            await turnContext.SendActivityAsync("Sorry, something went wrong.");
        };
    }
}
  • 监控
    activity$
    可观察对象以确认是否从机器人收到活动:
directLine.activity$.subscribe(activity => {
  console.log('Activity received from bot:', activity);
});

已将应用程序部署到应用程序服务。

enter image description here

已测试:

enter image description here

在运行应用程序之前,使用 postman 或 curl 测试端点 url -

/api/messages

© www.soinside.com 2019 - 2024. All rights reserved.