You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure EchoBot无消息响应:无问候语且无法回复问题排查求助

Azure EchoBot无响应问题求助

搭建了基于ASP.NET Core 8 Web API与Angular应用的极简版Azure EchoBot,已部署至Azure Linux应用服务。Angular应用集成WebChat控件后,可发送消息并在聊天窗口显示,但Bot既不发送问候语,也不回复任何消息。

Chrome开发者控制台截图:
Chrome开发者控制台截图

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: 'support@limbo.dating',
      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: 'support@limbo.dating', 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 !== 'support@limbo.dating') {
        console.log('Incoming message:', activity);
      } else {
        console.log('Outgoing message:', activity);
      }
    });
  }
}

期望EchoBot能回复“Echo: ”加上聊天窗口输入的内容,求解决办法。


内容的提问来源于stack exchange,提问作者Eis Karlsson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 20:05:54