我已经使用Bot Framework v4 c#在本地创建了一个Bot。它有一个欢迎卡,当我将本地URL与模拟器连接后,该卡会自动弹出,但是最近我将我的机器人部署在Azure上,并使用直接通道将其集成到我的网站中。现在,每当我单击时,它都会打开该机器人,但是欢迎卡并不会自动出现,当我从聊天机器人中写一些东西时,它就会出现。我只希望欢迎卡自动出现在模拟器中。你们可以帮我吗?以下是我正在网站中集成的直线代码。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<!-- Paste line 7 to 27 after the title tag in _Layout.cshtml -->
<link href="https://cdn.botframework.com/botframework-webchat/latest/botchat.css" rel="stylesheet"
/>
<script src="https://cdn.botframework.com/botframework-webchat/latest/botchat.js"></script>
<style>
#mychat {
margin: 10px;
position: fixed;
bottom: 30px;
left: 10px;
z-index: 1000000;
}
.botIcon {
float: left !important;
border-radius: 50%;
}
.userIcon {
float: right !important;
border-radius: 50%;
}
</style>
</head>
< body>
<!-- Paste line from 31 to 33 before the </body> tag at the end of code -->
<div id="container">
<img id="mychat" src=""/>
</div>
</body>
<!-- Paste line 38 to 88 after the </html> tag -->
<script>
(function () {
var div = document.createElement("div");
var user = {
id: "",
name: ''
};
var bot = {
id: '',
name: 'SaathiBot'
};
const botConnection = new BotChat.DirectLine({
secret: '',
webSocket: false
})
document.getElementsByTagName('body')[0].appendChild(div);
div.outerHTML = "<div id='botDiv' style='width: 400px; height: 0px; margin:10px; position:
fixed; bottom: 0; left:0; z-index: 1000;><div id='botTitleBar' style='height: 40px; width: 400px;
position:fixed;光标:指针;'>“;
BotChat.App({
botConnection: botConnection,
user: user,
bot: bot
}, document.getElementById("botDiv"));
document.getElementsByClassName("wc-header")[0].setAttribute("id", "chatbotheader");
document.querySelector('body').addEventListener('click', function (e) {
e.target.matches = e.target.matches || e.target.msMatchesSelector;
if (e.target.matches('#chatbotheader')) {
var botDiv = document.querySelector('#botDiv');
botDiv.style.height = "0px";
document.getElementById("mychat").style.display = "block";
};
});
document.getElementById("mychat").addEventListener("click", function (e) {
document.getElementById("botDiv").style.height = '500px';
e.target.style.display = "none";
})
}());
</script>
这也是我在C#中的欢迎卡代码
namespace Microsoft.BotBuilderSamples
{
public class WelcomeUser : SaathiDialogBot<MainDialog>
{
protected readonly string[] _cards =
{
Path.Combine(".", "Resources", "WelcomeCard.json"),
};
public WelcomeUser(ConversationState conversationState, UserState userState, MainDialog dialog, ILogger<SaathiDialogBot<MainDialog>> logger)
: base(conversationState, userState, dialog, logger)
{
}
protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
await SendWelcomeMessageAsync(turnContext, cancellationToken);
Random r = new Random();
var cardAttachment = CreateAdaptiveCardAttachment(_cards[r.Next(_cards.Length)]);
await turnContext.SendActivityAsync(MessageFactory.Attachment(cardAttachment), cancellationToken);
}
private static async Task SendWelcomeMessageAsync(ITurnContext turnContext, CancellationToken cancellationToken)
{
foreach (var member in turnContext.Activity.MembersAdded)
{
if (member.Id != turnContext.Activity.Recipient.Id)
{
if (DateTime.Now.Hour < 12)
{
await turnContext.SendActivityAsync(
$"Hi,Good Morning {member.Name}",
cancellationToken: cancellationToken);
}
else if (DateTime.Now.Hour < 17)
{
await turnContext.SendActivityAsync(
$"Hi,Good Afternoon {member.Name}",
cancellationToken: cancellationToken);
}
else
{
await turnContext.SendActivityAsync(
$"Hi,Good Evening {member.Name}",
cancellationToken: cancellationToken);
}
}
}
}
private static Attachment CreateAdaptiveCardAttachment(string filePath)
{
var adaptiveCardJson = File.ReadAllText(filePath);
var adaptiveCardAttachment = new Attachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JsonConvert.DeserializeObject(adaptiveCardJson),
};
return adaptiveCardAttachment;
}
}
}
这是在欢迎卡中继承的saathiDialog代码。这是我的bot文件夹中的两个文件
public class SaathiDialogBot<T> : ActivityHandler where T : Dialog
{
protected readonly BotState ConversationState;
protected readonly Dialog Dialog;
protected readonly ILogger Logger;
protected readonly BotState UserState;
private DialogSet Dialogs { get; set; }
public SaathiDialogBot(ConversationState conversationState, UserState userState, T dialog, ILogger<SaathiDialogBot<T>> logger)
{
ConversationState = conversationState;
UserState = userState;
Dialog = dialog;
Logger = logger;
}
public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
var activity = turnContext.Activity;
if (string.IsNullOrWhiteSpace(activity.Text) && activity.Value != null)
{
activity.Text = JsonConvert.SerializeObject(activity.Value);
}
if (turnContext.Activity.Text == "Yes")
{
await turnContext.SendActivityAsync($"Good bye. I will be here if you need me. ", cancellationToken: cancellationToken);
await turnContext.SendActivityAsync($"Say Hi to wake me up.", cancellationToken: cancellationToken);
}
else
{
await base.OnTurnAsync(turnContext, cancellationToken);
}
await ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);
await UserState.SaveChangesAsync(turnContext, false, cancellationToken);
}
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
Logger.LogInformation("Running dialog with Message Activity.");
await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
}
}
}
here is main Dialog code
namespace Microsoft.BotBuilderSamples { public class MainDialog : ComponentDialog { private const string UserInfo = "value-userInfo"; protected readonly ILogger _logger; protected readonly string[] _cards = { Path.Combine(".", "Resources", "ValidationCard.json"), }; public MainDialog(ILogger<MainDialog> logger) : base(nameof(MainDialog)) { _logger = logger; AddDialog(new ProductIssue($"{nameof(MainDialog)}.fromMain")); AddDialog(new ProductIssue($"{nameof(Confirm)}.fromConfirm")); AddDialog(new ProductIssue($"{ nameof(Resolution)}.resolution")); AddDialog(new Confirm()); AddDialog(new ChoicePrompt($"{nameof(MainDialog)}.issue")); AddDialog(new TextPrompt($"{nameof(MainDialog)}.callDialog")); AddDialog(new NumberPrompt<int>($"{nameof(MainDialog)}.num", valinatiotionAsync)); AddDialog(new WaterfallDialog($"{nameof(MainDialog)}.mainFlow", new WaterfallStep[]
{
MoblieNumberAsync,
ChoiceCardStepAsync,
ShowCardStepAsync,
CallingDialogsAsync
}));
AddDialog(new TextPrompt(nameof(TextPrompt)));
InitialDialogId = $"{nameof(MainDialog)}.mainFlow";
}
private async Task<DialogTurnResult> MoblieNumberAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
stepContext.Values[UserInfo] = new UserInput();
var options = new PromptOptions()
{
Prompt = MessageFactory.Text("Kindly enter your 10 digit mobile number without any spaces, dashes and country code. We will be sending an OTP later to this number "),
RetryPrompt = MessageFactory.Text("Incorrect mobile number entered. Please only enter the 10 digits of your mobile without any spaces, dashes and country code.")
};
return await stepContext.PromptAsync($"{nameof(MainDialog)}.num", options, cancellationToken);
}
private async Task<DialogTurnResult> ChoiceCardStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
BotAPIBLL botApiBLL = new BotAPIBLL();
var response = botApiBLL.GetCustomerDetail(stepContext.Context.Activity.Text);
await stepContext.Context.SendActivityAsync(MessageFactory.Text("Fetching your details from our systems. This may take a moment"), cancellationToken);
var options = new PromptOptions()
{
Prompt = MessageFactory.Text("Welcome user, How can we serve you ? "),
RetryPrompt = MessageFactory.Text("That was not a valid choice, please select a option between 1 to 4."),
Choices = GetChoices(),
};
return await stepContext.PromptAsync($"{nameof(MainDialog)}.issue", options, cancellationToken);
}
private async Task<DialogTurnResult> ShowCardStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var attachments = new List<Attachment>();
var reply = MessageFactory.Text("");
var user_choice = ((FoundChoice)stepContext.Result).Value;
switch (user_choice)
{
case "Product issue":
reply.Attachments.Add(Cards.CreateAdaptiveCardAttachment3());
break;
case "Register Product":
reply.Attachments.Add(Cards.GetHeroCard1().ToAttachment());
break;
case "Online Purchase":
reply.Attachments.Add(Cards.GetHeroCard2().ToAttachment());
break;
case "Customer Grivance":
reply.Attachments.Add(Cards.GetHeroCard3().ToAttachment());
break;
default:
reply.AttachmentLayout = AttachmentLayoutTypes.Carousel;
reply.Attachments.Add(Cards.CreateAdaptiveCardAttachment3());
reply.AttachmentLayout = AttachmentLayoutTypes.Carousel;
reply.Attachments.Add(Cards.GetHeroCard1().ToAttachment());
break;
}
if (user_choice == "Register Product" || user_choice == "Online Purchase" || user_choice == "Customer Grivance")
{
await stepContext.Context.SendActivityAsync(reply, cancellationToken);
Random r = new Random();
var validationcard = Cards.CreateAdaptiveCardAttachment2(_cards[r.Next(_cards.Length)]);
await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(validationcard), cancellationToken);
return await stepContext.EndDialogAsync(null, cancellationToken);
}
else
{
var options2 = new PromptOptions() { Prompt = reply, RetryPrompt = MessageFactory.Text("Retry") };
return await stepContext.PromptAsync($"{nameof(MainDialog)}.callDialog", options2, cancellationToken);
}
}
private async Task<DialogTurnResult> CallingDialogsAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
string choice = stepContext.Result.ToString();
if (choice.ToLower() == "no")
{
return await stepContext.BeginDialogAsync($"{nameof(MainDialog)}.fromMain", null, cancellationToken);
}
else
return await stepContext.BeginDialogAsync(nameof(Confirm), null, cancellationToken);
}
private IList<Choice> GetChoices()
{
var cardOptions = new List<Choice>()
{
new Choice() { Value = "Product issue", Synonyms = new List<string>() { "adaptive" } },
new Choice() { Value = "Register Product", Synonyms = new List<string>() { "hero" } },
new Choice() { Value = "Online Purchase", Synonyms = new List<string>() { "hero" } },
new Choice() { Value = "Customer Grivance", Synonyms = new List<string>() { "hero" } },
};
return cardOptions;
}
private Task<bool> valinatiotionAsync(PromptValidatorContext<int> promptContext, CancellationToken cancellationToken)
{
string value = (string)promptContext.Context.Activity.Text;
if (Regex.IsMatch(value, "^[0-9]{10}$"))
{
return Task.FromResult(true);
}
else
{
return Task.FromResult(false);
}
}
}
}
答案 0 :(得分:1)
您必须使用 ConversationUpdate 事件 ActivityTypes.ConversationUpdate
这是Switch语句中的一个示例,在该示例中,我检查所获得的不同ActivityType,然后使用sessionUpdate显示欢迎消息
case ActivityTypes.ConversationUpdate:
{
if (activity.MembersAdded?.Count > 0)
{
await innerDc.BeginDialogAsync(nameof(dialog));
}
break;
}
更新
请查看此工作示例以及有关如何从WebChat发送Welcome Message Event的说明。
答案 1 :(得分:1)
如果您使用的是WebChat或Directline,则在创建会话时会发送漫游器的ConversationUpdate,而在用户首次发送消息时会发送用户的ConversationUpdate。最初发送ConversationUpdate时,消息中没有足够的信息来构造对话框堆栈。之所以在模拟器中似乎起作用,是因为该模拟器模拟了一种伪DirectLine,但是两个对话更新都在模拟器中同时得到了解决,而实际服务的执行情况却并非如此。 >
一种解决方法是在建立DirectLine连接时向机器人发送反向通道欢迎事件,并从onEventAsync处理程序(而不是onMember Leicester)发送欢迎消息。
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
<style>
#webchat {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div style="display: flex">
<div style="position: relative; height: 500px; width: 500px"><div id="bot" ></div></div>
</div>
<script>
(async function() {
const res = await fetch('/directline/token', { method: 'POST' });
const { token } = await res.json();
var userinfo = {
id: 'user-id',
name: 'user name',
locale: 'es'
};
var botConnection = new window.BotChat.DirectLine({ token });
botConnection.connectionStatus$
.subscribe(connectionStatus => {
switch(connectionStatus) {
case window.BotChat.ConnectionStatus.Online:
botConnection.postActivity({
from: { id: 'myUserId', name: 'myUserName' },
type: 'event',
name: 'webchat/join',
value: { locale: 'en-US' }
}).subscribe(
id => console.log("Posted welcome event, assigned ID ", id),
error => console.log("Error posting activity", error)
);
break;
}
});
BotChat.App({
botConnection: botConnection,
user: userinfo,
bot: { id: 'botid' },
resize: 'detect'
}, document.getElementById("bot"));
})().catch(err => console.log(err));
</script>
</body>
</html>
protected override async Task OnEventActivityAsync(ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken)
{
if (turnContext.Activity.Name == "webchat/join") {
await turnContext.SendActivityAsync("Welcome Message!");
}
}
protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
if (turnContext.Activity.ChannelId != "webchat" && turnContext.Activity.ChannelId != "directline") {
foreach (var member in membersAdded)
{
if (member.Id != turnContext.Activity.Recipient.Id)
{
await turnContext.SendActivityAsync($"Hi there - {member.Name}. {WelcomeMessage}", cancellationToken: cancellationToken);
await turnContext.SendActivityAsync(InfoMessage, cancellationToken: cancellationToken);
await turnContext.SendActivityAsync(PatternMessage, cancellationToken: cancellationToken);
}
}
}
}
希望这会有所帮助。